/*
 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
 *
 * Sensitive Data Protection
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License 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.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#define pr_fmt(fmt) "SDP_MM: %s: " fmt, __func__

#include <asm/current.h>
#include <linux/cdev.h>
#include <linux/debugfs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mm_types.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <sdp/sdp_mm.h>

#define SDP_MM_DEV	"sdp_mm"

#define SENSITIVE 1
#define PER_USER_RANGE 100000

extern int dek_is_sdp_uid(uid_t uid);

static struct class *driver_class;
static dev_t sdp_mm_device_no;

struct sdp_mm_control {
	struct list_head  sdp_proc_list_head;
	spinlock_t        sdp_proc_list_lock;
	struct cdev cdev;
	unsigned int sensitive_proc_list_len;
	unsigned int proc_id[MAX_SENSITIVE_PROC];
};

static struct sdp_mm_control sdp_mm;

static int32_t sdp_mm_query_proc_loaded(void __user *argp)
{
	int32_t ret  = 0;
	struct task_struct *p = NULL;
	unsigned long flags = 0;
	struct sdp_mm_sensitive_proc_list_resp sdp_resp = {0};
	/* foreach process check if 'sensitive' flag is set in task/mm_struct */
	/* Copy the relevant information needed for loading the image */
	spin_lock_irqsave(&sdp_mm.sdp_proc_list_lock, flags);
	for_each_process(p) {
		if (p->sensitive == SENSITIVE) {
			sdp_resp.sensitive_proc_list[sdp_resp.sensitive_proc_list_len] = p->pid;
			sdp_resp.sensitive_proc_list_len++;
		}		if (sdp_resp.sensitive_proc_list_len >= MAX_SENSITIVE_PROC) break;
	}
	spin_unlock_irqrestore(&sdp_mm.sdp_proc_list_lock, flags);
	if (copy_to_user(argp, &sdp_resp, sizeof(sdp_resp))) {
		pr_err("SDP_MM: copy_to_user_failed\n");
		ret = -EFAULT;
	}
	return ret;
}

int32_t sdp_mm_set_process_sensitive(unsigned int proc_id)
{
	int32_t ret = 0;
	struct task_struct *task = NULL;
	uid_t uid;

	/* current.task.sensitive = 1 */
	task = pid_task(find_vpid(proc_id), PIDTYPE_PID);
	if (task) {
		uid = from_kuid(&init_user_ns, task_uid(task));
		if (((uid/PER_USER_RANGE) <= 199)  && ((uid/PER_USER_RANGE) >= 100)) {
			if (dek_is_sdp_uid(uid)) {
				task->sensitive = SENSITIVE;
				printk("SDP_MM: set the process as sensitive\n");
			} else {
				printk("SDP_MM: not a SDP process, failed to mark sensitive\n");
				ret = -EINVAL;
				goto task_err;
			}
		}
	} else {
		printk("SDP_MM; task not present\n");
		ret = -EINVAL;
		goto task_err;
	}

task_err:
	return ret;
}
EXPORT_SYMBOL(sdp_mm_set_process_sensitive);

static int32_t sdp_mm_set_proc_sensitive(void __user *argp)
{
	unsigned int proc_id = 0;

	if (copy_from_user(&proc_id, (void __user *)argp,
				sizeof(unsigned int))) {
		pr_err("SDP_MM: copy_from_user failed\n");
		return -EFAULT;
	}

	printk("SDP_MM: sensitive process id is %d\n", proc_id);
	if (sdp_mm.sensitive_proc_list_len < MAX_SENSITIVE_PROC) {
		sdp_mm.proc_id[sdp_mm.sensitive_proc_list_len] = proc_id;
		sdp_mm.sensitive_proc_list_len++;
	}
	
	return sdp_mm_set_process_sensitive(proc_id);
}


static long sdp_mm_ioctl(struct file *file, unsigned cmd,
		unsigned long arg)
{
	int ret = 0;
	void __user *argp = (void __user *) arg;

	printk("SDP_MM: Entering ioctl\n");

	switch (cmd) {
	case SDP_MM_IOCTL_PROC_SENSITIVE_QUERY_REQ: {
		printk("SDP_MM: SENSITIVE_PROC_QUERY\n");
		ret = sdp_mm_query_proc_loaded(argp);
		break;
	}
	case SDP_MM_IOCTL_SET_SENSITIVE_PROC_REQ: {
		printk("SDP_MM: SET_PROC_SENSITIVE\n");
		ret = sdp_mm_set_proc_sensitive(argp);
		break;
	}
	default:
		pr_err("Invalid IOCTL: %d\n", cmd);
		return -EINVAL;
	}
	return ret;
}

static int sdp_mm_open(struct inode *inode, struct file *file)
{
	int ret = 0;

	printk("SDP_MM: entering open\n");
	return ret;
}

static const struct file_operations sdp_mm_fops = {
		.owner = THIS_MODULE,
		.unlocked_ioctl = sdp_mm_ioctl,
		.open = sdp_mm_open,
};

static int sdp_mm_probe(struct platform_device *pdev)
{
	int rc;
	struct device *class_dev;

	printk("SDP_MM: entering probe\n");
	rc = alloc_chrdev_region(&sdp_mm_device_no, 0, 1, SDP_MM_DEV);
	if (rc < 0) {
		pr_err("alloc_chrdev_region failed %d\n", rc);
		return rc;
	}

	driver_class = class_create(THIS_MODULE, SDP_MM_DEV);
	if (IS_ERR(driver_class)) {
		rc = -ENOMEM;
		pr_err("SDP_MM: class_create failed %d\n", rc);
		goto exit_unreg_chrdev_region;
	}

	class_dev = device_create(driver_class, NULL, sdp_mm_device_no, NULL,
			SDP_MM_DEV);
	if (!class_dev) {
		pr_err("SDP_MM: class_device_create failed %d\n", rc);
		rc = -ENOMEM;
		goto exit_destroy_class;
	}

	cdev_init(&sdp_mm.cdev, &sdp_mm_fops);
	sdp_mm.cdev.owner = THIS_MODULE;

	rc = cdev_add(&sdp_mm.cdev, MKDEV(MAJOR(sdp_mm_device_no), 0), 1);
	if (rc < 0) {
		pr_err("SDP_MM: cdev_add failed %d\n", rc);
		goto exit_destroy_device;
	}

	INIT_LIST_HEAD(&sdp_mm.sdp_proc_list_head);
	spin_lock_init(&sdp_mm.sdp_proc_list_lock);

	return 0;

exit_destroy_device:
	device_destroy(driver_class, sdp_mm_device_no);
exit_destroy_class:
	class_destroy(driver_class);
exit_unreg_chrdev_region:
	unregister_chrdev_region(sdp_mm_device_no, 1);
	return rc;
}

static int sdp_mm_remove(struct platform_device *pdev)
{
	int ret = 0;

	cdev_del(&sdp_mm.cdev);
	device_destroy(driver_class, sdp_mm_device_no);
	class_destroy(driver_class);
	unregister_chrdev_region(sdp_mm_device_no, 1);

	return ret;
}
static struct platform_driver sdp_mm_plat_driver = {
	.probe = sdp_mm_probe,
	.remove = sdp_mm_remove,
	.driver = {
		.name = "sdp_mm",
		.owner = THIS_MODULE,
	},
};

static int __init sdp_mm_init(void)
{
	int rc;
	struct device *class_dev;

	printk("SDP_MM: entering************************************************\n");
	rc = alloc_chrdev_region(&sdp_mm_device_no, 0, 1, SDP_MM_DEV);
	if (rc < 0) {
		pr_err("SDP_MM: Alloc_chrdev_region failed %d\n", rc);
		return rc;
	}

	driver_class = class_create(THIS_MODULE, SDP_MM_DEV);
	if (IS_ERR(driver_class)) {
		rc = -ENOMEM;
		pr_err("SDP_MM: class_create failed %d\n", rc);
		goto exit_unreg_chrdev_region;
	}

	class_dev = device_create(driver_class, NULL, sdp_mm_device_no, NULL,
			SDP_MM_DEV);
	if (!class_dev) {
		pr_err("SDP_MM: class_device_create failed %d\n", rc);
		rc = -ENOMEM;
		goto exit_destroy_class;
	}

	cdev_init(&sdp_mm.cdev, &sdp_mm_fops);
	sdp_mm.cdev.owner = THIS_MODULE;

	rc = cdev_add(&sdp_mm.cdev, MKDEV(MAJOR(sdp_mm_device_no), 0), 1);
	if (rc < 0) {
		pr_err("SDP_MM: cdev_add failed %d\n", rc);
		goto exit_destroy_device;
	}

	INIT_LIST_HEAD(&sdp_mm.sdp_proc_list_head);
	spin_lock_init(&sdp_mm.sdp_proc_list_lock);
	return 0;

exit_destroy_device:
	device_destroy(driver_class, sdp_mm_device_no);
exit_destroy_class:
	class_destroy(driver_class);
exit_unreg_chrdev_region:
	unregister_chrdev_region(sdp_mm_device_no, 1);
	return rc;
}

static void __exit sdp_mm_exit(void)
{
	platform_driver_unregister(&sdp_mm_plat_driver);
}

module_init(sdp_mm_init);
module_exit(sdp_mm_exit);

MODULE_AUTHOR("HP");
MODULE_LICENSE("GPL");
