Skip to content

Commit eedd0f4

Browse files
ebiedermhtejun
authored andcommitted
cgroupns: Close race between cgroup_post_fork and copy_cgroup_ns
In most code paths involving cgroup migration cgroup_threadgroup_rwsem is taken. There are two exceptions: - remove_tasks_in_empty_cpuset calls cgroup_transfer_tasks - vhost_attach_cgroups_work calls cgroup_attach_task_all With cgroup_threadgroup_rwsem held it is guaranteed that cgroup_post_fork and copy_cgroup_ns will reference the same css_set from the process calling fork. Without such an interlock there process after fork could reference one css_set from it's new cgroup namespace and another css_set from task->cgroups, which semantically is nonsensical. Cc: stable@vger.kernel.org Fixes: a79a908 ("cgroup: introduce cgroup namespaces") Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Tejun Heo <tj@kernel.org>
1 parent 7bd8830 commit eedd0f4

File tree

1 file changed

+5
-0
lines changed

1 file changed

+5
-0
lines changed

kernel/cgroup.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2962,6 +2962,7 @@ int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk)
29622962
int retval = 0;
29632963

29642964
mutex_lock(&cgroup_mutex);
2965+
percpu_down_write(&cgroup_threadgroup_rwsem);
29652966
for_each_root(root) {
29662967
struct cgroup *from_cgrp;
29672968

@@ -2976,6 +2977,7 @@ int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk)
29762977
if (retval)
29772978
break;
29782979
}
2980+
percpu_up_write(&cgroup_threadgroup_rwsem);
29792981
mutex_unlock(&cgroup_mutex);
29802982

29812983
return retval;
@@ -4343,6 +4345,8 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from)
43434345

43444346
mutex_lock(&cgroup_mutex);
43454347

4348+
percpu_down_write(&cgroup_threadgroup_rwsem);
4349+
43464350
/* all tasks in @from are being moved, all csets are source */
43474351
spin_lock_irq(&css_set_lock);
43484352
list_for_each_entry(link, &from->cset_links, cset_link)
@@ -4371,6 +4375,7 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from)
43714375
} while (task && !ret);
43724376
out_err:
43734377
cgroup_migrate_finish(&preloaded_csets);
4378+
percpu_up_write(&cgroup_threadgroup_rwsem);
43744379
mutex_unlock(&cgroup_mutex);
43754380
return ret;
43764381
}

0 commit comments

Comments
 (0)