diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2012-11-18 16:34:11 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-19 14:15:54 -0500 |
commit | c260b7722f8c21963d0f0347f7fc203da9ee1a6b (patch) | |
tree | 8d42f13a5cedbcd5d442d6f02e132f9a65372e7a | |
parent | 3594698a1fb8e5ae60a92c72ce9ca280256939a7 (diff) |
net: Allow userns root to control tun and tap devices
Allow an unpriviled user who has created a user namespace, and then
created a network namespace to effectively use the new network
namespace, by reducing capable(CAP_NET_ADMIN) calls to
ns_capable(net->user_ns,CAP_NET_ADMIN) calls.
Allow setting of the tun iff flags.
Allow creating of tun devices.
Allow adding a new queue to a tun device.
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/tun.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index b44d7b79cddc..b01e8c0c422b 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -373,10 +373,11 @@ static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb) | |||
373 | static inline bool tun_not_capable(struct tun_struct *tun) | 373 | static inline bool tun_not_capable(struct tun_struct *tun) |
374 | { | 374 | { |
375 | const struct cred *cred = current_cred(); | 375 | const struct cred *cred = current_cred(); |
376 | struct net *net = dev_net(tun->dev); | ||
376 | 377 | ||
377 | return ((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) || | 378 | return ((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) || |
378 | (gid_valid(tun->group) && !in_egroup_p(tun->group))) && | 379 | (gid_valid(tun->group) && !in_egroup_p(tun->group))) && |
379 | !capable(CAP_NET_ADMIN); | 380 | !ns_capable(net->user_ns, CAP_NET_ADMIN); |
380 | } | 381 | } |
381 | 382 | ||
382 | static void tun_set_real_num_queues(struct tun_struct *tun) | 383 | static void tun_set_real_num_queues(struct tun_struct *tun) |
@@ -1559,7 +1560,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1559 | char *name; | 1560 | char *name; |
1560 | unsigned long flags = 0; | 1561 | unsigned long flags = 0; |
1561 | 1562 | ||
1562 | if (!capable(CAP_NET_ADMIN)) | 1563 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) |
1563 | return -EPERM; | 1564 | return -EPERM; |
1564 | err = security_tun_dev_create(); | 1565 | err = security_tun_dev_create(); |
1565 | if (err < 0) | 1566 | if (err < 0) |