From: Kirill Tkhai <[email protected]> This patch adds possibility to get tun device's net namespace fd in the same way we allow to do that for sockets.
Socket ioctl numbers do not intersect with tun-specific, and there is already SIOCSIFHWADDR used in tun code. So, SIOCGSKNS number is choosen instead of custom-made for this functionality. Note, that open_related_ns() uses plain get_net_ns() and it's safe (net can't be already dead at this moment): tun socket is allocated via sk_alloc() with zero last arg (kern = 0). So, each alive socket increments net::count, and the socket is definitely alive during ioctl syscall. Also, common variable net is introduced, so small cleanup in TUNSETIFF is made. Signed-off-by: Kirill Tkhai <[email protected]> Signed-off-by: David S. Miller <[email protected]> While on it also fix inconsistency with MS behaviour: TUNSETIFF should return EEXIST if tun exists. (cherry picked from commit f2780d6d74756bc1d7ba32ff3dd0de4afd7c7e1e) https://jira.sw.ru/browse/PSBM-102357 Signed-off-by: Pavel Tikhomirov <[email protected]> --- drivers/net/tun.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 81b305abbf05..08332bdff1bc 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -71,6 +71,7 @@ #include <net/sock.h> #include <linux/skb_array.h> #include <linux/seq_file.h> +#include <linux/socket.h> #include <asm/uaccess.h> @@ -2329,6 +2330,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, void __user* argp = (void __user*)arg; unsigned int ifindex, carrier; struct ifreq ifr; + struct net *net; kuid_t owner; kgid_t group; int sndbuf; @@ -2338,7 +2340,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, bool do_notify = false; if (cmd == TUNSETIFF || cmd == TUNSETQUEUE || cmd == TUNSETACCTID || - _IOC_TYPE(cmd) == 0x89) { + (_IOC_TYPE(cmd) == 0x89 && cmd != SIOCGSKNS)) { if (copy_from_user(&ifr, argp, ifreq_len)) return -EFAULT; } else { @@ -2365,7 +2367,11 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, #endif /* CONFIG_VE_TUNTAP_ACCOUNTING */ tun = __tun_get(tfile); - if (cmd == TUNSETIFF && !tun) { + net = sock_net(&tfile->sk); + if (cmd == TUNSETIFF) { + ret = -EEXIST; + if (tun) + goto unlock; ifr.ifr_name[IFNAMSIZ-1] = '\0'; ret = tun_set_iff(tfile->net, file, &ifr); @@ -2390,6 +2396,14 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, tfile->ifindex = ifindex; goto unlock; } + if (cmd == SIOCGSKNS) { + ret = -EPERM; + if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) + goto unlock; + + ret = open_related_ns(&net->ns, get_net_ns); + goto unlock; + } ret = -EBADFD; if (!tun) -- 2.24.1 _______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
