diff options
Diffstat (limited to 'kernel/ns_cgroup.c')
| -rw-r--r-- | kernel/ns_cgroup.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/kernel/ns_cgroup.c b/kernel/ns_cgroup.c index 5aa854f9e5ae..2a5dfec8efe0 100644 --- a/kernel/ns_cgroup.c +++ b/kernel/ns_cgroup.c | |||
| @@ -42,8 +42,8 @@ int ns_cgroup_clone(struct task_struct *task, struct pid *pid) | |||
| 42 | * (hence either you are in the same cgroup as task, or in an | 42 | * (hence either you are in the same cgroup as task, or in an |
| 43 | * ancestor cgroup thereof) | 43 | * ancestor cgroup thereof) |
| 44 | */ | 44 | */ |
| 45 | static int ns_can_attach(struct cgroup_subsys *ss, | 45 | static int ns_can_attach(struct cgroup_subsys *ss, struct cgroup *new_cgroup, |
| 46 | struct cgroup *new_cgroup, struct task_struct *task) | 46 | struct task_struct *task, bool threadgroup) |
| 47 | { | 47 | { |
| 48 | if (current != task) { | 48 | if (current != task) { |
| 49 | if (!capable(CAP_SYS_ADMIN)) | 49 | if (!capable(CAP_SYS_ADMIN)) |
| @@ -56,6 +56,18 @@ static int ns_can_attach(struct cgroup_subsys *ss, | |||
| 56 | if (!cgroup_is_descendant(new_cgroup, task)) | 56 | if (!cgroup_is_descendant(new_cgroup, task)) |
| 57 | return -EPERM; | 57 | return -EPERM; |
| 58 | 58 | ||
| 59 | if (threadgroup) { | ||
| 60 | struct task_struct *c; | ||
| 61 | rcu_read_lock(); | ||
| 62 | list_for_each_entry_rcu(c, &task->thread_group, thread_group) { | ||
| 63 | if (!cgroup_is_descendant(new_cgroup, c)) { | ||
| 64 | rcu_read_unlock(); | ||
| 65 | return -EPERM; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | rcu_read_unlock(); | ||
| 69 | } | ||
| 70 | |||
| 59 | return 0; | 71 | return 0; |
| 60 | } | 72 | } |
| 61 | 73 | ||
