diff options
Diffstat (limited to 'net/core/net_namespace.c')
-rw-r--r-- | net/core/net_namespace.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 2c1c59091685..6456439cbbd9 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/proc_fs.h> | 13 | #include <linux/proc_fs.h> |
14 | #include <linux/file.h> | 14 | #include <linux/file.h> |
15 | #include <linux/export.h> | 15 | #include <linux/export.h> |
16 | #include <linux/user_namespace.h> | ||
16 | #include <net/net_namespace.h> | 17 | #include <net/net_namespace.h> |
17 | #include <net/netns/generic.h> | 18 | #include <net/netns/generic.h> |
18 | 19 | ||
@@ -145,7 +146,7 @@ static void ops_free_list(const struct pernet_operations *ops, | |||
145 | /* | 146 | /* |
146 | * setup_net runs the initializers for the network namespace object. | 147 | * setup_net runs the initializers for the network namespace object. |
147 | */ | 148 | */ |
148 | static __net_init int setup_net(struct net *net) | 149 | static __net_init int setup_net(struct net *net, struct user_namespace *user_ns) |
149 | { | 150 | { |
150 | /* Must be called with net_mutex held */ | 151 | /* Must be called with net_mutex held */ |
151 | const struct pernet_operations *ops, *saved_ops; | 152 | const struct pernet_operations *ops, *saved_ops; |
@@ -155,6 +156,7 @@ static __net_init int setup_net(struct net *net) | |||
155 | atomic_set(&net->count, 1); | 156 | atomic_set(&net->count, 1); |
156 | atomic_set(&net->passive, 1); | 157 | atomic_set(&net->passive, 1); |
157 | net->dev_base_seq = 1; | 158 | net->dev_base_seq = 1; |
159 | net->user_ns = user_ns; | ||
158 | 160 | ||
159 | #ifdef NETNS_REFCNT_DEBUG | 161 | #ifdef NETNS_REFCNT_DEBUG |
160 | atomic_set(&net->use_count, 0); | 162 | atomic_set(&net->use_count, 0); |
@@ -232,7 +234,8 @@ void net_drop_ns(void *p) | |||
232 | net_free(ns); | 234 | net_free(ns); |
233 | } | 235 | } |
234 | 236 | ||
235 | struct net *copy_net_ns(unsigned long flags, struct net *old_net) | 237 | struct net *copy_net_ns(unsigned long flags, |
238 | struct user_namespace *user_ns, struct net *old_net) | ||
236 | { | 239 | { |
237 | struct net *net; | 240 | struct net *net; |
238 | int rv; | 241 | int rv; |
@@ -243,8 +246,11 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net) | |||
243 | net = net_alloc(); | 246 | net = net_alloc(); |
244 | if (!net) | 247 | if (!net) |
245 | return ERR_PTR(-ENOMEM); | 248 | return ERR_PTR(-ENOMEM); |
249 | |||
250 | get_user_ns(user_ns); | ||
251 | |||
246 | mutex_lock(&net_mutex); | 252 | mutex_lock(&net_mutex); |
247 | rv = setup_net(net); | 253 | rv = setup_net(net, user_ns); |
248 | if (rv == 0) { | 254 | if (rv == 0) { |
249 | rtnl_lock(); | 255 | rtnl_lock(); |
250 | list_add_tail_rcu(&net->list, &net_namespace_list); | 256 | list_add_tail_rcu(&net->list, &net_namespace_list); |
@@ -252,6 +258,7 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net) | |||
252 | } | 258 | } |
253 | mutex_unlock(&net_mutex); | 259 | mutex_unlock(&net_mutex); |
254 | if (rv < 0) { | 260 | if (rv < 0) { |
261 | put_user_ns(user_ns); | ||
255 | net_drop_ns(net); | 262 | net_drop_ns(net); |
256 | return ERR_PTR(rv); | 263 | return ERR_PTR(rv); |
257 | } | 264 | } |
@@ -308,6 +315,7 @@ static void cleanup_net(struct work_struct *work) | |||
308 | /* Finally it is safe to free my network namespace structure */ | 315 | /* Finally it is safe to free my network namespace structure */ |
309 | list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { | 316 | list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { |
310 | list_del_init(&net->exit_list); | 317 | list_del_init(&net->exit_list); |
318 | put_user_ns(net->user_ns); | ||
311 | net_drop_ns(net); | 319 | net_drop_ns(net); |
312 | } | 320 | } |
313 | } | 321 | } |
@@ -395,7 +403,7 @@ static int __init net_ns_init(void) | |||
395 | rcu_assign_pointer(init_net.gen, ng); | 403 | rcu_assign_pointer(init_net.gen, ng); |
396 | 404 | ||
397 | mutex_lock(&net_mutex); | 405 | mutex_lock(&net_mutex); |
398 | if (setup_net(&init_net)) | 406 | if (setup_net(&init_net, &init_user_ns)) |
399 | panic("Could not setup the initial network namespace"); | 407 | panic("Could not setup the initial network namespace"); |
400 | 408 | ||
401 | rtnl_lock(); | 409 | rtnl_lock(); |