/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/net.h>
#include <linux/socket.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/gfp.h>
#include <linux/uaccess.h>
#include <linux/kernel.h>
#include <linux/msm_ipc.h>
#include <linux/rwsem.h>
#include <linux/uaccess.h>

#include <net/sock.h>
#include "ipc_router_private.h"
#include "ipc_router_security.h"

#define IRSC_COMPLETION_TIMEOUT_MS 30000
#define SEC_RULES_HASH_SZ 32

#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)-1)
#endif

struct security_rule {
	struct list_head list;
	uint32_t service_id;
	uint32_t instance_id;
	unsigned reserved;
	int num_group_info;
	kgid_t *group_id;
};

static DECLARE_RWSEM(security_rules_lock_lha4);
static struct list_head security_rules[SEC_RULES_HASH_SZ];
static DECLARE_COMPLETION(irsc_completion);

/**
 * wait_for_irsc_completion() - Wait for IPC Router Security Configuration
 *                              (IRSC) to complete
 */
void wait_for_irsc_completion(void)
{
	unsigned long rem_jiffies;
	do {
		rem_jiffies = wait_for_completion_timeout(&irsc_completion,
				msecs_to_jiffies(IRSC_COMPLETION_TIMEOUT_MS));
		if (rem_jiffies)
			return;
		pr_err("%s: waiting for IPC Security Conf.\n", __func__);
	} while (1);
}

/**
 * signal_irsc_completion() - Signal the completion of IRSC
 */
void signal_irsc_completion(void)
{
	complete_all(&irsc_completion);
}

/**
 * check_permisions() - Check whether the process has permissions to
 *                      create an interface handle with IPC Router
 *
 * @return: true if the process has permissions, else false.
 */
int check_permissions(void)
{
	int rc = 0;
	if (capable(CAP_NET_RAW) || capable(CAP_NET_BIND_SERVICE))
		rc = 1;
	return rc;
}
EXPORT_SYMBOL(check_permissions);

/**
 * msm_ipc_config_sec_rules() - Add a security rule to the database
 * @arg: Pointer to the buffer containing the rule.
 *
 * @return: 0 if successfully added, < 0 for error.
 *
 * A security rule is defined using <Service_ID: Group_ID> tuple. The rule
 * implies that a user-space process in order to send a QMI message to
 * service Service_ID should belong to the Linux group Group_ID.
 */
int msm_ipc_config_sec_rules(void *arg)
{
	struct config_sec_rules_args sec_rules_arg;
	struct security_rule *rule, *temp_rule;
	int key;
	size_t kgroup_info_sz;
	int ret;
	size_t group_info_sz;
	gid_t *group_id = NULL;
	int loop;

	if (!uid_eq(current_euid(), GLOBAL_ROOT_UID))
		return -EPERM;

	ret = copy_from_user(&sec_rules_arg, (void *)arg,
			     sizeof(sec_rules_arg));
	if (ret)
		return -EFAULT;

	if (sec_rules_arg.num_group_info <= 0)
		return -EINVAL;

	if (sec_rules_arg.num_group_info > (SIZE_MAX / sizeof(gid_t))) {
		pr_err("%s: Integer Overflow %zu * %d\n", __func__,
			sizeof(gid_t), sec_rules_arg.num_group_info);
		return -EINVAL;
	}
	group_info_sz = sec_rules_arg.num_group_info * sizeof(gid_t);

	if (sec_rules_arg.num_group_info > (SIZE_MAX / sizeof(kgid_t))) {
		pr_err("%s: Integer Overflow %zu * %d\n", __func__,
			sizeof(kgid_t), sec_rules_arg.num_group_info);
		return -EINVAL;
	}
	kgroup_info_sz = sec_rules_arg.num_group_info * sizeof(kgid_t);

	rule = kzalloc(sizeof(struct security_rule), GFP_KERNEL);
	if (!rule) {
		pr_err("%s: security_rule alloc failed\n", __func__);
		return -ENOMEM;
	}

	rule->group_id = kzalloc(kgroup_info_sz, GFP_KERNEL);
	if (!rule->group_id) {
		pr_err("%s: kgroup_id alloc failed\n", __func__);
		kfree(rule);
		return -ENOMEM;
	}

	group_id = kzalloc(group_info_sz, GFP_KERNEL);
	if (!group_id) {
		pr_err("%s: group_id alloc failed\n", __func__);
		kfree(rule->group_id);
		kfree(rule);
		return -ENOMEM;
	}

	rule->service_id = sec_rules_arg.service_id;
	rule->instance_id = sec_rules_arg.instance_id;
	rule->reserved = sec_rules_arg.reserved;
	rule->num_group_info = sec_rules_arg.num_group_info;
	ret = copy_from_user(group_id, ((void *)(arg + sizeof(sec_rules_arg))),
			     group_info_sz);
	if (ret) {
		kfree(group_id);
		kfree(rule->group_id);
		kfree(rule);
		return -EFAULT;
	}
	for (loop = 0; loop < rule->num_group_info; loop++)
		rule->group_id[loop] = make_kgid(current_user_ns(),
						 group_id[loop]);
	kfree(group_id);

	key = rule->service_id & (SEC_RULES_HASH_SZ - 1);
	down_write(&security_rules_lock_lha4);
	if (rule->service_id == ALL_SERVICE) {
		temp_rule = list_first_entry(&security_rules[key],
					     struct security_rule, list);
		list_del(&temp_rule->list);
		kfree(temp_rule->group_id);
		kfree(temp_rule);
	}
	list_add_tail(&rule->list, &security_rules[key]);
	up_write(&security_rules_lock_lha4);

	if (rule->service_id == ALL_SERVICE)
		msm_ipc_sync_default_sec_rule((void *)rule);
	else
		msm_ipc_sync_sec_rule(rule->service_id, rule->instance_id,
				      (void *)rule);

	return 0;
}
EXPORT_SYMBOL(msm_ipc_config_sec_rules);

/**
 * msm_ipc_add_default_rule() - Add default security rule
 *
 * @return: 0 on success, < 0 on error/
 *
 * This function is used to ensure the basic security, if there is no
 * security rule defined for a service. It can be overwritten by the
 * default security rule from user-space script.
 */
static int msm_ipc_add_default_rule(void)
{
	struct security_rule *rule;
	int key;

	rule = kzalloc(sizeof(struct security_rule), GFP_KERNEL);
	if (!rule) {
		pr_err("%s: security_rule alloc failed\n", __func__);
		return -ENOMEM;
	}

	rule->group_id = kzalloc(sizeof(*(rule->group_id)), GFP_KERNEL);
	if (!rule->group_id) {
		pr_err("%s: group_id alloc failed\n", __func__);
		kfree(rule);
		return -ENOMEM;
	}

	rule->service_id = ALL_SERVICE;
	rule->instance_id = ALL_INSTANCE;
	rule->num_group_info = 1;
	*(rule->group_id) = make_kgid(current_user_ns(), AID_NET_RAW);
	down_write(&security_rules_lock_lha4);
	key = (ALL_SERVICE & (SEC_RULES_HASH_SZ - 1));
	list_add_tail(&rule->list, &security_rules[key]);
	up_write(&security_rules_lock_lha4);
	return 0;
}

/**
 * msm_ipc_get_security_rule() - Get the security rule corresponding to a
 *                               service
 * @service_id: Service ID for which the rule has to be got.
 * @instance_id: Instance ID for which the rule has to be got.
 *
 * @return: Returns the rule info on success, NULL on error.
 *
 * This function is used when the service comes up and gets registered with
 * the IPC Router.
 */
void *msm_ipc_get_security_rule(uint32_t service_id, uint32_t instance_id)
{
	int key;
	struct security_rule *rule;

	key = (service_id & (SEC_RULES_HASH_SZ - 1));
	down_read(&security_rules_lock_lha4);
	/* Return the rule for a specific <service:instance>, if found. */
	list_for_each_entry(rule, &security_rules[key], list) {
		if ((rule->service_id == service_id) &&
		    (rule->instance_id == instance_id)) {
			up_read(&security_rules_lock_lha4);
			return (void *)rule;
		}
	}

	/* Return the rule for a specific service, if found. */
	list_for_each_entry(rule, &security_rules[key], list) {
		if ((rule->service_id == service_id) &&
		    (rule->instance_id == ALL_INSTANCE)) {
			up_read(&security_rules_lock_lha4);
			return (void *)rule;
		}
	}

	/* Return the default rule, if no rule defined for a service. */
	key = (ALL_SERVICE & (SEC_RULES_HASH_SZ - 1));
	list_for_each_entry(rule, &security_rules[key], list) {
		if ((rule->service_id == ALL_SERVICE) &&
		    (rule->instance_id == ALL_INSTANCE)) {
			up_read(&security_rules_lock_lha4);
			return (void *)rule;
		}
	}
	up_read(&security_rules_lock_lha4);
	return NULL;
}
EXPORT_SYMBOL(msm_ipc_get_security_rule);

/**
 * msm_ipc_check_send_permissions() - Check if the sendng process has
 *                                    permissions specified as per the rule
 * @data: Security rule to be checked.
 *
 * @return: true if the process has permissions, else false.
 *
 * This function is used to check if the current executing process has
 * permissions to send message to the remote entity. The security rule
 * corresponding to the remote entity is specified by "data" parameter
 */
int msm_ipc_check_send_permissions(void *data)
{
	int i;
	struct security_rule *rule = (struct security_rule *)data;

	/* Source/Sender is Root user */
	if (uid_eq(current_euid(), GLOBAL_ROOT_UID))
		return 1;

	/* Destination has no rules defined, possibly a client. */
	if (!rule)
		return 1;

	for (i = 0; i < rule->num_group_info; i++) {
		if (!gid_valid(rule->group_id[i]))
			continue;
		if (in_egroup_p(rule->group_id[i]))
			return 1;
	}
	return 0;
}
EXPORT_SYMBOL(msm_ipc_check_send_permissions);

/**
 * msm_ipc_router_security_init() - Initialize the security rule database
 *
 * @return: 0 if successful, < 0 for error.
 */
int msm_ipc_router_security_init(void)
{
	int i;

	for (i = 0; i < SEC_RULES_HASH_SZ; i++)
		INIT_LIST_HEAD(&security_rules[i]);

	msm_ipc_add_default_rule();
	return 0;
}
EXPORT_SYMBOL(msm_ipc_router_security_init);
