在 2022/1/13 21:20, gc1202 写道:
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
默认打开吗? default n?
+ 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.
This software...这一段应该是不需要了。
+ * + */ + +#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))
put_group_info(group_info);
+ return true; + } +
put_group_info(group_info);
+ 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)
if (g_func_array[func_cmd])
+ 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