diff options
Diffstat (limited to 'kernel/nsproxy.c')
-rw-r--r-- | kernel/nsproxy.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c index 49746c81ad8d..782102e59eed 100644 --- a/kernel/nsproxy.c +++ b/kernel/nsproxy.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/proc_ns.h> | 25 | #include <linux/proc_ns.h> |
26 | #include <linux/file.h> | 26 | #include <linux/file.h> |
27 | #include <linux/syscalls.h> | 27 | #include <linux/syscalls.h> |
28 | #include <linux/cgroup.h> | ||
28 | 29 | ||
29 | static struct kmem_cache *nsproxy_cachep; | 30 | static struct kmem_cache *nsproxy_cachep; |
30 | 31 | ||
@@ -39,6 +40,9 @@ struct nsproxy init_nsproxy = { | |||
39 | #ifdef CONFIG_NET | 40 | #ifdef CONFIG_NET |
40 | .net_ns = &init_net, | 41 | .net_ns = &init_net, |
41 | #endif | 42 | #endif |
43 | #ifdef CONFIG_CGROUPS | ||
44 | .cgroup_ns = &init_cgroup_ns, | ||
45 | #endif | ||
42 | }; | 46 | }; |
43 | 47 | ||
44 | static inline struct nsproxy *create_nsproxy(void) | 48 | static inline struct nsproxy *create_nsproxy(void) |
@@ -92,6 +96,13 @@ static struct nsproxy *create_new_namespaces(unsigned long flags, | |||
92 | goto out_pid; | 96 | goto out_pid; |
93 | } | 97 | } |
94 | 98 | ||
99 | new_nsp->cgroup_ns = copy_cgroup_ns(flags, user_ns, | ||
100 | tsk->nsproxy->cgroup_ns); | ||
101 | if (IS_ERR(new_nsp->cgroup_ns)) { | ||
102 | err = PTR_ERR(new_nsp->cgroup_ns); | ||
103 | goto out_cgroup; | ||
104 | } | ||
105 | |||
95 | new_nsp->net_ns = copy_net_ns(flags, user_ns, tsk->nsproxy->net_ns); | 106 | new_nsp->net_ns = copy_net_ns(flags, user_ns, tsk->nsproxy->net_ns); |
96 | if (IS_ERR(new_nsp->net_ns)) { | 107 | if (IS_ERR(new_nsp->net_ns)) { |
97 | err = PTR_ERR(new_nsp->net_ns); | 108 | err = PTR_ERR(new_nsp->net_ns); |
@@ -101,6 +112,8 @@ static struct nsproxy *create_new_namespaces(unsigned long flags, | |||
101 | return new_nsp; | 112 | return new_nsp; |
102 | 113 | ||
103 | out_net: | 114 | out_net: |
115 | put_cgroup_ns(new_nsp->cgroup_ns); | ||
116 | out_cgroup: | ||
104 | if (new_nsp->pid_ns_for_children) | 117 | if (new_nsp->pid_ns_for_children) |
105 | put_pid_ns(new_nsp->pid_ns_for_children); | 118 | put_pid_ns(new_nsp->pid_ns_for_children); |
106 | out_pid: | 119 | out_pid: |
@@ -128,7 +141,8 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk) | |||
128 | struct nsproxy *new_ns; | 141 | struct nsproxy *new_ns; |
129 | 142 | ||
130 | if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | | 143 | if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | |
131 | CLONE_NEWPID | CLONE_NEWNET)))) { | 144 | CLONE_NEWPID | CLONE_NEWNET | |
145 | CLONE_NEWCGROUP)))) { | ||
132 | get_nsproxy(old_ns); | 146 | get_nsproxy(old_ns); |
133 | return 0; | 147 | return 0; |
134 | } | 148 | } |
@@ -165,6 +179,7 @@ void free_nsproxy(struct nsproxy *ns) | |||
165 | put_ipc_ns(ns->ipc_ns); | 179 | put_ipc_ns(ns->ipc_ns); |
166 | if (ns->pid_ns_for_children) | 180 | if (ns->pid_ns_for_children) |
167 | put_pid_ns(ns->pid_ns_for_children); | 181 | put_pid_ns(ns->pid_ns_for_children); |
182 | put_cgroup_ns(ns->cgroup_ns); | ||
168 | put_net(ns->net_ns); | 183 | put_net(ns->net_ns); |
169 | kmem_cache_free(nsproxy_cachep, ns); | 184 | kmem_cache_free(nsproxy_cachep, ns); |
170 | } | 185 | } |
@@ -180,7 +195,7 @@ int unshare_nsproxy_namespaces(unsigned long unshare_flags, | |||
180 | int err = 0; | 195 | int err = 0; |
181 | 196 | ||
182 | if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | | 197 | if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | |
183 | CLONE_NEWNET | CLONE_NEWPID))) | 198 | CLONE_NEWNET | CLONE_NEWPID | CLONE_NEWCGROUP))) |
184 | return 0; | 199 | return 0; |
185 | 200 | ||
186 | user_ns = new_cred ? new_cred->user_ns : current_user_ns(); | 201 | user_ns = new_cred ? new_cred->user_ns : current_user_ns(); |