diff options
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 18 |
1 files changed, 8 insertions, 10 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 9624db80dc4e..d1c51b7f5221 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -2209,12 +2209,8 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type, | |||
2209 | goto out_unlock; | 2209 | goto out_unlock; |
2210 | } | 2210 | } |
2211 | 2211 | ||
2212 | /* | 2212 | /* Hierarchies may only be created in the initial cgroup namespace. */ |
2213 | * We know this subsystem has not yet been bound. Users in a non-init | 2213 | if (ns != &init_cgroup_ns) { |
2214 | * user namespace may only mount hierarchies with no bound subsystems, | ||
2215 | * i.e. 'none,name=user1' | ||
2216 | */ | ||
2217 | if (!opts.none && !capable(CAP_SYS_ADMIN)) { | ||
2218 | ret = -EPERM; | 2214 | ret = -EPERM; |
2219 | goto out_unlock; | 2215 | goto out_unlock; |
2220 | } | 2216 | } |
@@ -2956,6 +2952,7 @@ int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk) | |||
2956 | int retval = 0; | 2952 | int retval = 0; |
2957 | 2953 | ||
2958 | mutex_lock(&cgroup_mutex); | 2954 | mutex_lock(&cgroup_mutex); |
2955 | percpu_down_write(&cgroup_threadgroup_rwsem); | ||
2959 | for_each_root(root) { | 2956 | for_each_root(root) { |
2960 | struct cgroup *from_cgrp; | 2957 | struct cgroup *from_cgrp; |
2961 | 2958 | ||
@@ -2970,6 +2967,7 @@ int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk) | |||
2970 | if (retval) | 2967 | if (retval) |
2971 | break; | 2968 | break; |
2972 | } | 2969 | } |
2970 | percpu_up_write(&cgroup_threadgroup_rwsem); | ||
2973 | mutex_unlock(&cgroup_mutex); | 2971 | mutex_unlock(&cgroup_mutex); |
2974 | 2972 | ||
2975 | return retval; | 2973 | return retval; |
@@ -4337,6 +4335,8 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from) | |||
4337 | 4335 | ||
4338 | mutex_lock(&cgroup_mutex); | 4336 | mutex_lock(&cgroup_mutex); |
4339 | 4337 | ||
4338 | percpu_down_write(&cgroup_threadgroup_rwsem); | ||
4339 | |||
4340 | /* all tasks in @from are being moved, all csets are source */ | 4340 | /* all tasks in @from are being moved, all csets are source */ |
4341 | spin_lock_irq(&css_set_lock); | 4341 | spin_lock_irq(&css_set_lock); |
4342 | list_for_each_entry(link, &from->cset_links, cset_link) | 4342 | list_for_each_entry(link, &from->cset_links, cset_link) |
@@ -4365,6 +4365,7 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from) | |||
4365 | } while (task && !ret); | 4365 | } while (task && !ret); |
4366 | out_err: | 4366 | out_err: |
4367 | cgroup_migrate_finish(&preloaded_csets); | 4367 | cgroup_migrate_finish(&preloaded_csets); |
4368 | percpu_up_write(&cgroup_threadgroup_rwsem); | ||
4368 | mutex_unlock(&cgroup_mutex); | 4369 | mutex_unlock(&cgroup_mutex); |
4369 | return ret; | 4370 | return ret; |
4370 | } | 4371 | } |
@@ -6339,14 +6340,11 @@ struct cgroup_namespace *copy_cgroup_ns(unsigned long flags, | |||
6339 | if (!ns_capable(user_ns, CAP_SYS_ADMIN)) | 6340 | if (!ns_capable(user_ns, CAP_SYS_ADMIN)) |
6340 | return ERR_PTR(-EPERM); | 6341 | return ERR_PTR(-EPERM); |
6341 | 6342 | ||
6342 | mutex_lock(&cgroup_mutex); | 6343 | /* It is not safe to take cgroup_mutex here */ |
6343 | spin_lock_irq(&css_set_lock); | 6344 | spin_lock_irq(&css_set_lock); |
6344 | |||
6345 | cset = task_css_set(current); | 6345 | cset = task_css_set(current); |
6346 | get_css_set(cset); | 6346 | get_css_set(cset); |
6347 | |||
6348 | spin_unlock_irq(&css_set_lock); | 6347 | spin_unlock_irq(&css_set_lock); |
6349 | mutex_unlock(&cgroup_mutex); | ||
6350 | 6348 | ||
6351 | new_ns = alloc_cgroup_ns(); | 6349 | new_ns = alloc_cgroup_ns(); |
6352 | if (IS_ERR(new_ns)) { | 6350 | if (IS_ERR(new_ns)) { |