From: gaochao
ohos inclusion
category: feature
issue: #I4OWTZ
CVE: NA
-----------
tokendid is used for special app security control
Signed-off-by: gaochao
---
drivers/Kconfig | 2 +
drivers/Makefile | 1 +
drivers/accesstokenid/Kconfig | 5 +
drivers/accesstokenid/Makefile | 2 +
drivers/accesstokenid/access_tokenid.c | 187 +++++++++++++++++++++++++
drivers/accesstokenid/access_tokenid.h | 43 ++++++
fs/proc/base.c | 15 ++
include/linux/sched.h | 4 +
kernel/fork.c | 4 +
9 files changed, 263 insertions(+)
create mode 100644 drivers/accesstokenid/Kconfig
create mode 100644 drivers/accesstokenid/Makefile
create mode 100644 drivers/accesstokenid/access_tokenid.c
create mode 100644 drivers/accesstokenid/access_tokenid.h
diff --git a/drivers/Kconfig b/drivers/Kconfig
index dcecc9f6e33f..c9a22b041303 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -235,4 +235,6 @@ source "drivers/interconnect/Kconfig"
source "drivers/counter/Kconfig"
source "drivers/most/Kconfig"
+
+source "drivers/accesstokenid/Kconfig"
endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 576228037718..71da48160b09 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -189,3 +189,4 @@ obj-$(CONFIG_GNSS) += gnss/
obj-$(CONFIG_INTERCONNECT) += interconnect/
obj-$(CONFIG_COUNTER) += counter/
obj-$(CONFIG_MOST) += most/
+obj-$(CONFIG_ACCESS_TOKENID) += accesstokenid/
diff --git a/drivers/accesstokenid/Kconfig b/drivers/accesstokenid/Kconfig
new file mode 100644
index 000000000000..814c095678e9
--- /dev/null
+++ b/drivers/accesstokenid/Kconfig
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+config ACCESS_TOKENID
+ bool "Access task's token"
+ default y
+
diff --git a/drivers/accesstokenid/Makefile b/drivers/accesstokenid/Makefile
new file mode 100644
index 000000000000..738a550f86cf
--- /dev/null
+++ b/drivers/accesstokenid/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_ACCESS_TOKENID) += access_tokenid.o
diff --git a/drivers/accesstokenid/access_tokenid.c b/drivers/accesstokenid/access_tokenid.c
new file mode 100644
index 000000000000..94e5310521ec
--- /dev/null
+++ b/drivers/accesstokenid/access_tokenid.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * access_tokenid.c
+ *
+ * Copyright (C) 2022 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#define pr_fmt(fmt) "access_token_id: " fmt
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "access_tokenid.h"
+
+int access_tokenid_get_tokenid(struct file *file, void __user *uarg)
+{
+ return copy_to_user(uarg, ¤t->token,
+ sizeof(current->token)) ? -EFAULT : 0;
+}
+
+static bool check_permission_for_set_tokenid(struct file *file)
+{
+ const struct cred *cred = get_task_cred(current);
+ struct inode *inode = file->f_inode;
+
+ if (inode == NULL) {
+ pr_err("%s: file inode is null\n", __func__);
+ return false;
+ }
+
+ if (uid_eq(cred->uid, GLOBAL_ROOT_UID) ||
+ uid_eq(cred->uid, inode->i_uid)) {
+ return true;
+ }
+
+ return false;
+}
+
+int access_tokenid_set_tokenid(struct file *file, void __user *uarg)
+{
+ unsigned long long tmp = 0;
+
+ if (!check_permission_for_set_tokenid(file))
+ return -EPERM;
+
+ if (copy_from_user(&tmp, uarg, sizeof(tmp)))
+ return -EFAULT;
+
+ current->token = tmp;
+ return 0;
+}
+
+static bool check_permission_for_ftokenid(struct file *file)
+{
+ int i;
+ struct group_info *group_info;
+ const struct cred *cred = get_task_cred(current);
+ struct inode *inode = file->f_inode;
+
+ if (inode == NULL) {
+ pr_err("%s: file inode is null\n", __func__);
+ return false;
+ }
+
+ if (uid_eq(cred->uid, GLOBAL_ROOT_UID))
+ return true;
+
+ group_info = get_current_groups();
+ for (i = 0; i < group_info->ngroups; i++) {
+ kgid_t gid = group_info->gid[i];
+
+ if (gid_eq(gid, inode->i_gid))
+ return true;
+ }
+
+ return false;
+}
+
+int access_tokenid_get_ftokenid(struct file *file, void __user *uarg)
+{
+ if (!check_permission_for_ftokenid(file))
+ return -EPERM;
+
+ return copy_to_user(uarg, ¤t->ftoken,
+ sizeof(current->ftoken)) ? -EFAULT : 0;
+}
+
+int access_tokenid_set_ftokenid(struct file *file, void __user *uarg)
+{
+ unsigned long long tmp = 0;
+
+ if (!check_permission_for_ftokenid(file))
+ return -EPERM;
+
+ if (copy_from_user(&tmp, uarg, sizeof(tmp)))
+ return -EFAULT;
+
+ current->ftoken = tmp;
+ return 0;
+}
+
+typedef int (*access_token_id_func)(struct file *file, void __user *arg);
+
+static access_token_id_func g_func_array[ACCESS_TOKENID_MAX_NR] = {
+ NULL, /* reserved */
+ access_tokenid_get_tokenid,
+ access_tokenid_set_tokenid,
+ access_tokenid_get_ftokenid,
+ access_tokenid_set_ftokenid,
+};
+
+static long access_tokenid_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ void __user *uarg = (void __user *)arg;
+ unsigned int func_cmd = _IOC_NR(cmd);
+
+ if (uarg == NULL) {
+ pr_err("%s: invalid user uarg\n", __func__);
+ return -EINVAL;
+ }
+
+ if (_IOC_TYPE(cmd) != ACCESS_TOKEN_ID_IOCTL_BASE) {
+ pr_err("%s: access tokenid magic fail, TYPE=%d\n",
+ __func__, _IOC_TYPE(cmd));
+ return -EINVAL;
+ }
+
+ if (func_cmd >= ACCESS_TOKENID_MAX_NR) {
+ pr_err("%s: access tokenid cmd error, cmd:%d\n",
+ __func__, func_cmd);
+ return -EINVAL;
+ }
+
+ if (g_func_array[func_cmd] != NULL)
+ return (*g_func_array[func_cmd])(file, uarg);
+
+ return -EINVAL;
+}
+
+static const struct file_operations access_tokenid_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = access_tokenid_ioctl,
+ .compat_ioctl = access_tokenid_ioctl,
+};
+
+static struct miscdevice access_tokenid_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "access_token_id",
+ .fops = &access_tokenid_fops,
+};
+
+static int access_tokenid_init_module(void)
+{
+ int err;
+
+ err = misc_register(&access_tokenid_device);
+ if (err < 0) {
+ pr_err("access_tokenid register failed\n");
+ return err;
+ }
+
+ pr_info("access_tokenid init success\n");
+ return 0;
+}
+
+static void access_tokenid_exit_module(void)
+{
+ misc_deregister(&access_tokenid_device);
+}
+
+/* module entry points */
+module_init(access_tokenid_init_module);
+module_exit(access_tokenid_exit_module);
diff --git a/drivers/accesstokenid/access_tokenid.h b/drivers/accesstokenid/access_tokenid.h
new file mode 100644
index 000000000000..1b3906f993b7
--- /dev/null
+++ b/drivers/accesstokenid/access_tokenid.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * access_tokenid.h
+ *
+ * Copyright (C) 2022 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _ACCESS_TOKEN_ID_H
+#define _ACCESS_TOKEN_ID_H
+
+#include
+#include
+
+#define ACCESS_TOKEN_ID_IOCTL_BASE 'A'
+
+enum {
+ GET_TOKEN_ID = 1,
+ SET_TOKEN_ID,
+ GET_FTOKEN_ID,
+ SET_FTOKEN_ID,
+ ACCESS_TOKENID_MAX_NR
+};
+
+#define ACCESS_TOKENID_GET_TOKENID \
+ _IOR(ACCESS_TOKEN_ID_IOCTL_BASE, GET_TOKEN_ID, unsigned long long)
+#define ACCESS_TOKENID_SET_TOKENID \
+ _IOW(ACCESS_TOKEN_ID_IOCTL_BASE, SET_TOKEN_ID, unsigned long long)
+#define ACCESS_TOKENID_GET_FTOKENID \
+ _IOR(ACCESS_TOKEN_ID_IOCTL_BASE, GET_FTOKEN_ID, unsigned long long)
+#define ACCESS_TOKENID_SET_FTOKENID \
+ _IOW(ACCESS_TOKEN_ID_IOCTL_BASE, SET_FTOKEN_ID, unsigned long long)
+
+#endif /* _ACCESS_TOKEN_ID_H */
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 9b3038f1b9b5..9478b78f53ce 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -3179,6 +3179,15 @@ static int proc_stack_depth(struct seq_file *m, struct pid_namespace *ns,
}
#endif /* CONFIG_STACKLEAK_METRICS */
+#ifdef CONFIG_ACCESS_TOKENID
+static int proc_token_operations(struct seq_file *m, struct pid_namespace *ns,
+ struct pid *pid, struct task_struct *task)
+{
+ seq_printf(m, "%#llx %#llx\n", task->token, task->ftoken);
+ return 0;
+}
+#endif /* CONFIG_ACCESS_TOKENID */
+
/*
* Thread groups
*/
@@ -3292,6 +3301,9 @@ static const struct pid_entry tgid_base_stuff[] = {
#ifdef CONFIG_PROC_PID_ARCH_STATUS
ONE("arch_status", S_IRUGO, proc_pid_arch_status),
#endif
+#ifdef CONFIG_ACCESS_TOKENID
+ ONE("tokenid", S_IRUSR, proc_token_operations),
+#endif
};
static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx)
@@ -3621,6 +3633,9 @@ static const struct pid_entry tid_base_stuff[] = {
#ifdef CONFIG_PROC_PID_ARCH_STATUS
ONE("arch_status", S_IRUGO, proc_pid_arch_status),
#endif
+#ifdef CONFIG_ACCESS_TOKENID
+ ONE("tokenid", S_IRUSR, proc_token_operations),
+#endif
};
static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 53198ac3d154..d42f4addcaec 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1362,6 +1362,10 @@ struct task_struct {
int mce_count;
#endif
+#ifdef CONFIG_ACCESS_TOKENID
+ u64 token;
+ u64 ftoken;
+#endif
/*
* New fields for task_struct should be added above here, so that
* they are included in the randomized portion of task_struct.
diff --git a/kernel/fork.c b/kernel/fork.c
index 39b1783a7613..5d7a6821d59c 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -874,6 +874,10 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
err = arch_dup_task_struct(tsk, orig);
+#ifdef CONFIG_ACCESS_TOKENID
+ tsk->token = orig->token;
+ tsk->ftoken = 0;
+#endif
/*
* arch_dup_task_struct() clobbers the stack-related fields. Make
* sure they're properly initialized before using any stack-related
--
2.25.1