提交 a8453b17 编写于 作者: H Hou Tao 提交者: Xie XiuQi

cgroup/files: use task_get_css() to get a valid css during dup_fd()

euler inclusion
category: bugfix
bugzilla: 14007
CVE: NA
-------------------------------------------------

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: NHou Tao <houtao1@huawei.com>
Reviewed-by: Nluojiajun <luojiajun3@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 d72c2468
...@@ -293,18 +293,16 @@ struct cgroup_subsys files_cgrp_subsys = { ...@@ -293,18 +293,16 @@ struct cgroup_subsys files_cgrp_subsys = {
.dfl_cftypes = files, .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) void files_cgroup_assign(struct files_struct *files)
{ {
struct task_struct *tsk = current;
struct cgroup_subsys_state *css; struct cgroup_subsys_state *css;
struct cgroup *cgrp;
task_lock(tsk); css = task_get_css(current, files_cgrp_id);
cgrp = task_cgroup(tsk, files_cgrp_id);
css = cgroup_subsys_state(cgrp, files_cgrp_id);
css_get(css);
files->files_cgroup = container_of(css, struct files_cgroup, css); files->files_cgroup = container_of(css, struct files_cgroup, css);
task_unlock(tsk);
} }
void files_cgroup_remove(struct files_struct *files) void files_cgroup_remove(struct files_struct *files)
......
...@@ -416,12 +416,6 @@ static inline void cgroup_put(struct cgroup *cgrp) ...@@ -416,12 +416,6 @@ static inline void cgroup_put(struct cgroup *cgrp)
css_put(&cgrp->self); css_put(&cgrp->self);
} }
static inline struct cgroup_subsys_state *cgroup_subsys_state(
struct cgroup *cgrp, int subsys_id)
{
return cgrp->subsys[subsys_id];
}
/** /**
* task_css_set_check - obtain a task's css_set with extra access conditions * task_css_set_check - obtain a task's css_set with extra access conditions
* @task: the task to obtain css_set for * @task: the task to obtain css_set for
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册