
From: Hou Tao <houtao1@huawei.com> hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I7VO77 -------------------------------- Process fork and cgroup migration can happen simultaneously, and in the following case use-after-free of css_set is possible: CPU 0: process fork CPU 1: cgroup migration dup_fd __cgroup1_procs_write(threadgroup=false) files_cgroup_assign // task A task_lock task_cgroup(current, files_cgrp_id) css_set = task_css_set_check() cgroup_migrate_execute files_cgroup_can_attach css_set_move_task put_css_set_locked() files_cgroup_attach // task B which is in the same // thread group as task A task_lock cgroup_migrate_finish // the css_set will be freed put_css_set_locked() // use-after-free css_set->subsys[files_cgrp_id] Fix it by using task_get_css() instead to get a valid css. Fixes: 52cc1eccf6de ("cgroups: Resource controller for open files") Signed-off-by: Hou Tao <houtao1@huawei.com> Reviewed-by: luojiajun <luojiajun3@huawei.com> Signed-off-by: Yang Yingliang <yangyingliang@huawei.com> Signed-off-by: Lu Jialin <lujialin4@huawei.com> --- fs/filescontrol.c | 12 +++++------- include/linux/cgroup.h | 6 ------ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/fs/filescontrol.c b/fs/filescontrol.c index 44ad9ef44e20..1d2d29127fd4 100644 --- a/fs/filescontrol.c +++ b/fs/filescontrol.c @@ -293,18 +293,16 @@ struct cgroup_subsys files_cgrp_subsys = { .dfl_cftypes = files, }; +/* + * It could race against cgroup migration of current task, and + * using task_get_css() to get a valid css. + */ void files_cgroup_assign(struct files_struct *files) { - struct task_struct *tsk = current; struct cgroup_subsys_state *css; - struct cgroup *cgrp; - task_lock(tsk); - cgrp = task_cgroup(tsk, files_cgrp_id); - css = cgroup_subsys_state(cgrp, files_cgrp_id); - css_get(css); + css = task_get_css(current, files_cgrp_id); files->files_cgroup = container_of(css, struct files_cgroup, css); - task_unlock(tsk); } void files_cgroup_remove(struct files_struct *files) diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 40b67ca53719..885f5395fcd0 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -363,12 +363,6 @@ static inline void cgroup_put(struct cgroup *cgrp) css_put(&cgrp->self); } -static inline struct cgroup_subsys_state *cgroup_subsys_state( - struct cgroup *cgrp, int subsys_id) -{ - return cgrp->subsys[subsys_id]; -} - extern struct mutex cgroup_mutex; static inline void cgroup_lock(void) -- 2.34.1