From: Zhang Zekun zhangzekun11@huawei.com
ascend inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I612UG CVE: NA
--------------------------------
To support container scenario, use tgid instead of pid to find a specific task. In normal cases, "tgid" represent a process in init_pid_ns, this patch should not introduce problems to existing code.
Rename the input parameter "int pid" to "int tgid" in following exported interfaces: 1.mg_sp_group_id_by_pid() 2.mg_sp_group_add_task() 3.mg_sp_group_del_task() 4.mg_sp_make_share_k2u() 5.mg_sp_make_share_u2k() 6.mg_sp_config_dvpp_range()
Besides, rename these static function together: 1.__sp_find_spg_locked() 2.__sp_find_spg()
The following function use "current->pid" to find spg, change "current->pid" to "current->tgid". 1.find_or_alloc_sp_group() 2.sp_alloc_prepare() 3.mg_sp_make_share_k2u()
Signed-off-by: Zhang Zekun zhangzekun11@huawei.com --- include/linux/share_pool.h | 24 +++++++------- mm/share_pool.c | 64 ++++++++++++++++++++------------------ 2 files changed, 45 insertions(+), 43 deletions(-)
diff --git a/include/linux/share_pool.h b/include/linux/share_pool.h index 1432aaa08087..5e15e7a1234f 100644 --- a/include/linux/share_pool.h +++ b/include/linux/share_pool.h @@ -249,9 +249,9 @@ static inline void sp_init_mm(struct mm_struct *mm) /* * Those interfaces are exported for modules */ -extern int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id); -extern int mg_sp_group_del_task(int pid, int spg_id); -extern int mg_sp_group_id_by_pid(int pid, int *spg_ids, int *num); +extern int mg_sp_group_add_task(int tgid, unsigned long prot, int spg_id); +extern int mg_sp_group_del_task(int tgid, int spg_id); +extern int mg_sp_group_id_by_pid(int tgid, int *spg_ids, int *num); extern int proc_sp_group_state(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, struct task_struct *task);
@@ -259,8 +259,8 @@ extern void *mg_sp_alloc(unsigned long size, unsigned long sp_flags, int spg_id) extern int mg_sp_free(unsigned long addr, int id);
extern void *mg_sp_make_share_k2u(unsigned long kva, unsigned long size, - unsigned long sp_flags, int pid, int spg_id); -extern void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int pid); + unsigned long sp_flags, int tgid, int spg_id); +extern void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int tgid); extern int mg_sp_unshare(unsigned long va, unsigned long size, int spg_id);
extern int mg_sp_walk_page_range(unsigned long uva, unsigned long size, @@ -271,7 +271,7 @@ extern void mg_sp_walk_page_free(struct sp_walk_data *sp_walk_data); extern int sp_register_notifier(struct notifier_block *nb); extern int sp_unregister_notifier(struct notifier_block *nb);
-extern bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int pid); +extern bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int tgid);
extern bool mg_is_sharepool_addr(unsigned long addr);
@@ -321,12 +321,12 @@ static inline bool is_vmalloc_sharepool(unsigned long vm_flags)
#else /* CONFIG_ASCEND_SHARE_POOL */
-static inline int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id) +static inline int mg_sp_group_add_task(int tgid, unsigned long prot, int spg_id) { return -EPERM; }
-static inline int mg_sp_group_del_task(int pid, int spg_id) +static inline int mg_sp_group_del_task(int tgid, int spg_id) { return -EPERM; } @@ -340,7 +340,7 @@ static inline void sp_group_post_exit(struct mm_struct *mm) { }
-static inline int mg_sp_group_id_by_pid(int pid, int *spg_ids, int *num) +static inline int mg_sp_group_id_by_pid(int tgid, int *spg_ids, int *num) { return -EPERM; } @@ -362,12 +362,12 @@ static inline int mg_sp_free(unsigned long addr, int id) }
static inline void *mg_sp_make_share_k2u(unsigned long kva, unsigned long size, - unsigned long sp_flags, int pid, int spg_id) + unsigned long sp_flags, int tgid, int spg_id) { return NULL; }
-static inline void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int pid) +static inline void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int tgid) { return NULL; } @@ -410,7 +410,7 @@ static inline int sp_unregister_notifier(struct notifier_block *nb) return -EPERM; }
-static inline bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int pid) +static inline bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int tgid) { return false; } diff --git a/mm/share_pool.c b/mm/share_pool.c index 68e8f5c93a1f..7a1b7f5caf54 100644 --- a/mm/share_pool.c +++ b/mm/share_pool.c @@ -975,12 +975,14 @@ static void sp_group_drop(struct sp_group *spg) }
/* use with put_task_struct(task) */ -static int get_task(int pid, struct task_struct **task) +static int get_task(int tgid, struct task_struct **task) { struct task_struct *tsk; + struct pid *p;
rcu_read_lock(); - tsk = find_task_by_vpid(pid); + p = find_pid_ns(tgid, &init_pid_ns); + tsk = pid_task(p, PIDTYPE_TGID); if (!tsk || (tsk->flags & PF_EXITING)) { rcu_read_unlock(); return -ESRCH; @@ -1010,14 +1012,14 @@ static bool is_process_in_group(struct sp_group *spg, }
/* user must call sp_group_drop() after use */ -static struct sp_group *__sp_find_spg_locked(int pid, int spg_id) +static struct sp_group *__sp_find_spg_locked(int tgid, int spg_id) { struct sp_group *spg = NULL; struct task_struct *tsk = NULL; int ret = 0;
if (spg_id == SPG_ID_DEFAULT) { - ret = get_task(pid, &tsk); + ret = get_task(tgid, &tsk); if (ret) return NULL;
@@ -1039,19 +1041,19 @@ static struct sp_group *__sp_find_spg_locked(int pid, int spg_id) return spg; }
-static struct sp_group *__sp_find_spg(int pid, int spg_id) +static struct sp_group *__sp_find_spg(int tgid, int spg_id) { struct sp_group *spg;
down_read(&sp_group_sem); - spg = __sp_find_spg_locked(pid, spg_id); + spg = __sp_find_spg_locked(tgid, spg_id); up_read(&sp_group_sem); return spg; }
/** * mp_sp_group_id_by_pid() - Get the sp_group ID array of a process. - * @pid: pid of target process. + * @tgid: tgid of target process. * @spg_ids: point to an array to save the group ids the process belongs to * @num: input the spg_ids array size; output the spg number of the process * @@ -1061,7 +1063,7 @@ static struct sp_group *__sp_find_spg(int pid, int spg_id) * -EINVAL - spg_ids or num is NULL. * -E2BIG - the num of groups process belongs to is larger than *num */ -int mg_sp_group_id_by_pid(int pid, int *spg_ids, int *num) +int mg_sp_group_id_by_pid(int tgid, int *spg_ids, int *num) { int ret = 0, real_count; struct sp_group_node *node; @@ -1076,7 +1078,7 @@ int mg_sp_group_id_by_pid(int pid, int *spg_ids, int *num) if (!spg_ids || !num || *num <= 0) return -EINVAL;
- ret = get_task(pid, &tsk); + ret = get_task(tgid, &tsk); if (ret) return ret;
@@ -1198,7 +1200,7 @@ static struct sp_group *find_or_alloc_sp_group(int spg_id, unsigned long flag) { struct sp_group *spg;
- spg = __sp_find_spg_locked(current->pid, spg_id); + spg = __sp_find_spg_locked(current->tgid, spg_id);
if (!spg) { spg = create_spg(spg_id, flag); @@ -1350,7 +1352,7 @@ static int local_group_add_task(struct mm_struct *mm, struct sp_group *spg)
/** * mg_sp_group_add_task() - Add a process to an share group (sp_group). - * @pid: the pid of the task to be added. + * @tgid: the tgid of the task to be added. * @prot: the prot of task for this spg. * @spg_id: the ID of the sp_group. * @flag: to give some special message. @@ -1364,7 +1366,7 @@ static int local_group_add_task(struct mm_struct *mm, struct sp_group *spg) * The automatically allocated ID is between [SPG_ID_AUTO_MIN, SPG_ID_AUTO_MAX]. * When negative, the return value is -errno. */ -int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id) +int mg_sp_group_add_task(int tgid, unsigned long prot, int spg_id) { unsigned long flag = 0; struct task_struct *tsk; @@ -1393,7 +1395,7 @@ int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id) }
if (spg_id >= SPG_ID_AUTO_MIN && spg_id <= SPG_ID_AUTO_MAX) { - spg = __sp_find_spg(pid, spg_id); + spg = __sp_find_spg(tgid, spg_id);
if (!spg) { pr_err_ratelimited("spg %d hasn't been created\n", spg_id); @@ -1424,7 +1426,7 @@ int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id)
down_write(&sp_group_sem);
- ret = get_task(pid, &tsk); + ret = get_task(tgid, &tsk); if (ret) { up_write(&sp_group_sem); free_new_spg_id(id_newly_generated, spg_id); @@ -1599,7 +1601,7 @@ EXPORT_SYMBOL_GPL(mg_sp_group_add_task);
/** * mg_sp_group_del_task() - delete a process from a sp group. - * @pid: the pid of the task to be deleted + * @tgid: the tgid of the task to be deleted * @spg_id: sharepool group id * * the group's spa list must be empty, or deletion will fail. @@ -1607,9 +1609,9 @@ EXPORT_SYMBOL_GPL(mg_sp_group_add_task); * Return: * * if success, return 0. * * -EINVAL, spg_id invalid or spa_lsit not emtpy or spg dead - * * -ESRCH, the task group of pid is not in group / process dead + * * -ESRCH, the task group of tgid is not in group / process dead */ -int mg_sp_group_del_task(int pid, int spg_id) +int mg_sp_group_del_task(int tgid, int spg_id) { int ret = 0; struct sp_group *spg; @@ -1626,7 +1628,7 @@ int mg_sp_group_del_task(int pid, int spg_id) return -EINVAL; }
- spg = __sp_find_spg(pid, spg_id); + spg = __sp_find_spg(tgid, spg_id); if (!spg) { pr_err_ratelimited("spg not found or get task failed."); return -EINVAL; @@ -1647,7 +1649,7 @@ int mg_sp_group_del_task(int pid, int spg_id) goto out; }
- ret = get_task(pid, &tsk); + ret = get_task(tgid, &tsk); if (ret) { up_write(&sp_group_sem); pr_err_ratelimited("task is not found"); @@ -1759,7 +1761,7 @@ static void insert_sp_area(struct sp_mapping *spm, struct sp_area *spa) * @flags: how to allocate the memory. * @spg: the share group that the memory is allocated to. * @type: the type of the region. - * @applier: the pid of the task which allocates the region. + * @applier: the tgid of the task which allocates the region. * * Return: a valid pointer for success, NULL on failure. */ @@ -2318,7 +2320,7 @@ static int sp_alloc_prepare(unsigned long size, unsigned long sp_flags, sp_flags |= SP_HUGEPAGE;
if (spg_id != SPG_ID_DEFAULT) { - spg = __sp_find_spg(current->pid, spg_id); + spg = __sp_find_spg(current->tgid, spg_id); if (!spg) { pr_err_ratelimited("allocation failed, can't find group\n"); return -ENODEV; @@ -2921,7 +2923,7 @@ static void *sp_k2u_finish(void *uva, struct sp_k2u_context *kc) * @kva: the VA of shared kernel memory. * @size: the size of shared kernel memory. * @sp_flags: how to allocate the memory. We only support SP_DVPP. - * @pid: the pid of the specified process (Not currently in use). + * @tgid: the tgid of the specified process (Not currently in use). * @spg_id: the share group that the memory is shared to. * * Return: the shared target user address to start at @@ -2934,7 +2936,7 @@ static void *sp_k2u_finish(void *uva, struct sp_k2u_context *kc) * * if fail, return the pointer of -errno. */ void *mg_sp_make_share_k2u(unsigned long kva, unsigned long size, - unsigned long sp_flags, int pid, int spg_id) + unsigned long sp_flags, int tgid, int spg_id) { void *uva; int ret; @@ -2954,7 +2956,7 @@ void *mg_sp_make_share_k2u(unsigned long kva, unsigned long size, } else { struct sp_group *spg;
- spg = __sp_find_spg(current->pid, kc.spg_id); + spg = __sp_find_spg(current->tgid, kc.spg_id); if (spg) { ret = sp_check_caller_permission(spg, current->mm); if (ret < 0) { @@ -3214,13 +3216,13 @@ static void __sp_walk_page_free(struct sp_walk_data *data) * mg_sp_make_share_u2k() - Share user memory of a specified process to kernel. * @uva: the VA of shared user memory * @size: the size of shared user memory - * @pid: the pid of the specified process(Not currently in use) + * @tgid: the tgid of the specified process(Not currently in use) * * Return: * * if success, return the starting kernel address of the shared memory. * * if failed, return the pointer of -errno. */ -void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int pid) +void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int tgid) { int ret = 0; struct mm_struct *mm = current->mm; @@ -3282,7 +3284,7 @@ void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int pid) EXPORT_SYMBOL_GPL(mg_sp_make_share_u2k);
/* - * Input parameters uva, pid and spg_id are now useless. spg_id will be useful + * Input parameters uva, tgid and spg_id are now useless. spg_id will be useful * when supporting a process in multiple sp groups. * * Procedure of unshare uva must be compatible with: @@ -3612,13 +3614,13 @@ static bool is_sp_dynamic_dvpp_addr(unsigned long addr); * @start: the value of share pool start * @size: the value of share pool * @device_id: the num of Da-vinci device - * @pid: the pid of device process + * @tgid: the tgid of device process * * Return true for success. * Return false if parameter invalid or has been set up. * This functuon has no concurrent problem. */ -bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int pid) +bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int tgid) { int ret; bool err = false; @@ -3632,12 +3634,12 @@ bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int pid) return false;
/* NOTE: check the start address */ - if (pid < 0 || size <= 0 || size > MMAP_SHARE_POOL_16G_SIZE || + if (tgid < 0 || size <= 0 || size > MMAP_SHARE_POOL_16G_SIZE || device_id < 0 || device_id >= MAX_DEVID || !is_online_node_id(device_id) || !is_sp_dynamic_dvpp_addr(start) || !is_sp_dynamic_dvpp_addr(start + size - 1)) return false;
- ret = get_task(pid, &tsk); + ret = get_task(tgid, &tsk); if (ret) return false;