aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-11-15 22:02:57 -0500
committerDavid S. Miller <davem@davemloft.net>2012-11-18 20:30:55 -0500
commitd328b836823cd4a76611a45f52e208f8ce3d75d7 (patch)
tree73c874c9e1c5c328d198c15d79eff0ad4bbd52af /net/core
parent2407dc25f741cf73853e0521ce9257531c9fc61d (diff)
userns: make each net (net_ns) belong to a user_ns
The user namespace which creates a new network namespace owns that namespace and all resources created in it. This way we can target capability checks for privileged operations against network resources to the user_ns which created the network namespace in which the resource lives. Privilege to the user namespace which owns the network namespace, or any parent user namespace thereof, provides the same privilege to the network resource. This patch is reworked from a version originally by Serge E. Hallyn <serge.hallyn@canonical.com> Acked-by: Serge Hallyn <serge.hallyn@canonical.com> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/net_namespace.c16
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 */
148static __net_init int setup_net(struct net *net) 149static __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
235struct net *copy_net_ns(unsigned long flags, struct net *old_net) 237struct 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();