[RHEL7,COMMIT] ms/tun: Add ioctl() SIOCGSKNS cmd to allow obtaining net ns of tun device

Submitted by Konstantin Khorenko on April 2, 2018, 2:14 p.m.

Details

Message ID 201804021414.w32EEYkV023591@finist_ce7.work
State New
Series "Port SIOCGSKNS support for sockets and tun"
Headers show

Commit Message

Konstantin Khorenko April 2, 2018, 2:14 p.m.
The commit is pushed to "branch-rh7-3.10.0-693.21.1.vz7.46.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-693.21.1.vz7.46.2
------>
commit 46fe3e2b3544cdc3e8eddfabbe06558a9928457d
Author: Kirill Tkhai <ktkhai@virtuozzo.com>
Date:   Mon Apr 2 17:14:34 2018 +0300

    ms/tun: Add ioctl() SIOCGSKNS cmd to allow obtaining net ns of tun device
    
    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 <ktkhai@virtuozzo.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    
    ms commit (linux-next): f2780d6d7475:
    https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=f2780d6d74756bc1d7ba32ff3dd0de4afd7c7e1e
    
    https://jira.sw.ru/browse/PSBM-79229
    
    Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
    Reviewed-by: Pavel Tikhoirov <ptikhomirov@virtuozzo.com>
    
    ===========================================================
    Patchset description:
    Port SIOCGSKNS support for sockets and tun
    
    This patchset ports get-socket-and-tun-net-namespace-fd functionality
    from mainline kernel to vz7.
    
    Note, that in case of sockets and tun we don't have proc vfsmnt
    like we have for NS_GET_USERNS and NS_GET_PARENT. The workaround
    is to use current's pid_ns->proc_mnt. It has to work even in case
    of nested pid ns, since the namespaces inodes numbers are uniqul
    in the system.
    
    Kirill Tkhai (2):
          ms/net: add an ioctl to get a socket network namespace
          tun: Add ioctl() SIOCGSKNS cmd to allow obtaining net ns of tun device
---
 drivers/net/tun.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 8cd39507c64b..9264c06fd7d2 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -70,6 +70,7 @@ 
 #include <net/rtnetlink.h>
 #include <net/sock.h>
 #include <linux/skb_array.h>
+#include <linux/proc_ns.h>
 
 #include <asm/uaccess.h>
 
@@ -2224,7 +2225,7 @@  static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 	int ret;
 
 	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 {
@@ -2276,6 +2277,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(tfile->net->user_ns, CAP_NET_ADMIN))
+			goto unlock;
+
+		ret = open_net_ns_fd(tfile->net);
+		goto unlock;
+	}
 
 	ret = -EBADFD;
 	if (!tun)