mirror of https://github.com/OpenIPC/firmware.git
180 lines
4.2 KiB
Diff
180 lines
4.2 KiB
Diff
diff -drupN a/security/fivm/fivm_dev.c b/security/fivm/fivm_dev.c
|
|
--- a/security/fivm/fivm_dev.c 1970-01-01 03:00:00.000000000 +0300
|
|
+++ b/security/fivm/fivm_dev.c 2022-06-12 05:28:14.000000000 +0300
|
|
@@ -0,0 +1,175 @@
|
|
+/*
|
|
+ * linux/security/fivm/fivm_dev.c
|
|
+ *
|
|
+ * Copyright (C) 2014 Allwinner Ltd.
|
|
+ *
|
|
+ * Author: ryan.chen <ryanchen@allwinnertech.com>
|
|
+ *
|
|
+ * allwinner fivm controller device
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ */
|
|
+#include <linux/module.h>
|
|
+#include <linux/version.h>
|
|
+#include <linux/init.h>
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/types.h>
|
|
+#include <linux/kdev_t.h>
|
|
+#include <linux/fs.h>
|
|
+#include <linux/device.h>
|
|
+#include <linux/cdev.h>
|
|
+#include <linux/compat.h>
|
|
+#include <linux/uaccess.h>
|
|
+
|
|
+#include "fivm.h"
|
|
+
|
|
+#define CMD_FIVM_INIT _IO('M', 0)
|
|
+#define CMD_FIVM_ENABLE _IO('M', 1)
|
|
+#define CMD_FIVM_SET _IOR('M', 2, struct fivm_param)
|
|
+
|
|
+#ifdef CONFIG_COMPAT
|
|
+#define CMD_FIVM_SET32 _IOR('M', 2, struct fivm_param_t32)
|
|
+#endif
|
|
+
|
|
+static dev_t dev;
|
|
+static struct cdev c_dev;
|
|
+static struct class *cl;
|
|
+
|
|
+static int fivm_open(struct inode *i, struct file *f)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+static int fivm_close(struct inode *i, struct file *f)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+extern int fivm_init(void);
|
|
+static long fivm_ioctl (
|
|
+ struct file *file,
|
|
+ unsigned int cmd,
|
|
+ unsigned long arg)
|
|
+{
|
|
+ int rc = 0;
|
|
+ switch (cmd) {
|
|
+ case CMD_FIVM_ENABLE:
|
|
+ rc = fivm_enable();
|
|
+ break;
|
|
+ case CMD_FIVM_SET:
|
|
+ rc = fivm_set((void *)arg);
|
|
+ break;
|
|
+ default:
|
|
+ rc = -EINVAL;
|
|
+ break;
|
|
+ }
|
|
+ return rc;
|
|
+}
|
|
+#ifdef CONFIG_COMPAT
|
|
+static long fivm_compat_ioctl(struct file *file,
|
|
+ unsigned int cmd,
|
|
+ unsigned long arg
|
|
+ )
|
|
+{
|
|
+ int rc = 0;
|
|
+ struct fivm_param_t32 param_t32;
|
|
+ struct fivm_param __user *param;
|
|
+
|
|
+ switch (cmd) {
|
|
+ case CMD_FIVM_ENABLE:
|
|
+ rc = fivm_enable();
|
|
+ break;
|
|
+ case CMD_FIVM_SET32:
|
|
+ if (copy_from_user(¶m_t32,
|
|
+ (const void __user *)arg,
|
|
+ sizeof(param_t32))) {
|
|
+ pr_err("wrong copy from user param\n");
|
|
+ return -EFAULT;
|
|
+ }
|
|
+
|
|
+ param = compat_alloc_user_space(sizeof(*param));
|
|
+ if (!access_ok(VERIFY_READ, param, sizeof(*param))) {
|
|
+ pr_err("access read fail for param\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ put_user(compat_ptr(param_t32.sig_head),
|
|
+ ¶m->sig_head);
|
|
+ put_user(param_t32.sig_head_size,
|
|
+ ¶m->sig_head_size);
|
|
+ put_user(compat_ptr(param_t32.sig_table),
|
|
+ ¶m->sig_table);
|
|
+ put_user(param_t32.sig_table_size,
|
|
+ ¶m->sig_table_size);
|
|
+
|
|
+ rc = fivm_set((void *)param);
|
|
+ break;
|
|
+ default:
|
|
+ rc = -EINVAL;
|
|
+ break;
|
|
+ }
|
|
+ return rc;
|
|
+}
|
|
+#endif
|
|
+static const struct file_operations fivm_fops = {
|
|
+ .owner = THIS_MODULE,
|
|
+ .open = fivm_open,
|
|
+ .release = fivm_close,
|
|
+ .unlocked_ioctl = fivm_ioctl,
|
|
+#ifdef CONFIG_COMPAT
|
|
+ .compat_ioctl = fivm_compat_ioctl,
|
|
+#endif
|
|
+};
|
|
+
|
|
+static int __init fivm_dev_init(void) /* Constructor */
|
|
+{
|
|
+ if (alloc_chrdev_region(&dev, 0, 1, "fivm_dev") < 0) {
|
|
+ pr_err("fivm chrdev create fail\n");
|
|
+ return -1;
|
|
+ }
|
|
+ cl = class_create(THIS_MODULE, "fivm_drv");
|
|
+ if (!cl) {
|
|
+ pr_err("fivm class create fail\n");
|
|
+ unregister_chrdev_region(dev, 1);
|
|
+ return -1;
|
|
+ }
|
|
+ if (device_create(cl, NULL, dev, NULL, "fivm") == NULL) {
|
|
+ pr_err("fivm device create fail\n");
|
|
+ class_destroy(cl);
|
|
+ unregister_chrdev_region(dev, 1);
|
|
+ return -1;
|
|
+ }
|
|
+ cdev_init(&c_dev, &fivm_fops);
|
|
+ if (cdev_add(&c_dev, dev, 1) == -1) {
|
|
+ pr_err("fivm cdev add fail\n");
|
|
+ device_destroy(cl, dev);
|
|
+ class_destroy(cl);
|
|
+ unregister_chrdev_region(dev, 1);
|
|
+ return -1;
|
|
+ }
|
|
+ if (fivm_init() < 0) {
|
|
+ pr_err("fivm init fail\n");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ pr_info("FIVM device register ok \n");
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void __exit fivm_dev_exit(void) /* Destructor */
|
|
+{
|
|
+ cdev_del(&c_dev);
|
|
+ device_destroy(cl, dev);
|
|
+ class_destroy(cl);
|
|
+ unregister_chrdev_region(dev, 1);
|
|
+ fivm_cleanup();
|
|
+}
|
|
+
|
|
+module_init(fivm_dev_init);
|
|
+module_exit(fivm_dev_exit);
|
|
+
|
|
+MODULE_LICENSE("GPL");
|
|
+MODULE_AUTHOR("ryan chen<ryanchen@allsoftwinnertech.com>");
|
|
+MODULE_DESCRIPTION("Sunxi file integrity verify module for system");
|
|
+
|