From: Andrey Vagin <[email protected]> Each socket operates in a network namespace where it has been created, so if we want to dump and restore a socket, we have to know its network namespace.
We have a socket_diag to get information about sockets, it doesn't report sockets which are not bound or connected. This patch introduces a new socket ioctl, which is called SIOCGSKNS and used to get a file descriptor for a socket network namespace. A task must have CAP_NET_ADMIN in a target network namespace to use this ioctl. Cc: "David S. Miller" <[email protected]> Cc: Eric W. Biederman <[email protected]> Signed-off-by: Andrei Vagin <[email protected]> Signed-off-by: David S. Miller <[email protected]> (cherry picked from VZ8 commit c62cce2caee558e18aa05c01c2fd3b40f07174f2) https://jira.sw.ru/browse/PSBM-102357 Signed-off-by: Pavel Tikhomirov <[email protected]> --- fs/nsfs.c | 2 +- include/linux/proc_fs.h | 4 ++++ include/uapi/linux/sockios.h | 1 + net/socket.c | 13 +++++++++++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/fs/nsfs.c b/fs/nsfs.c index 20ae4f7d92e6..fb5215552a8d 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -126,7 +126,7 @@ void *ns_get_path(struct path *path, struct task_struct *task, return ret; } -static int open_related_ns(struct ns_common *ns, +int open_related_ns(struct ns_common *ns, struct ns_common *(*get_ns)(struct ns_common *ns)) { struct path path = {}; diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 1b516bccb5e2..91d2eab45808 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -120,4 +120,8 @@ static inline struct proc_dir_entry *proc_net_mkdir( return proc_mkdir_data(name, S_ISVTX|S_IRUGO|S_IXUGO, parent, net); } +struct ns_common; +int open_related_ns(struct ns_common *ns, + struct ns_common *(*get_ns)(struct ns_common *ns)); + #endif /* _LINUX_PROC_FS_H */ diff --git a/include/uapi/linux/sockios.h b/include/uapi/linux/sockios.h index e888b1aed69f..cf0a25ebc74c 100644 --- a/include/uapi/linux/sockios.h +++ b/include/uapi/linux/sockios.h @@ -84,6 +84,7 @@ #define SIOCWANDEV 0x894A /* get/set netdev parameters */ #define SIOCOUTQNSD 0x894B /* output queue size (not sent only) */ +#define SIOCGSKNS 0x894C /* get socket network namespace */ /* ARP cache control calls. */ /* 0x8950 - 0x8952 * obsolete calls, don't re-use */ diff --git a/net/socket.c b/net/socket.c index 5cb4ccef937c..728c7ec9fca4 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1091,6 +1091,11 @@ static long sock_do_ioctl(struct net *net, struct socket *sock, * what to do with it - that's up to the protocol still. */ +static struct ns_common *get_net_ns(struct ns_common *ns) +{ + return &get_net(container_of(ns, struct net, ns))->ns; +} + static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) { struct socket *sock; @@ -1158,6 +1163,13 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) err = dlci_ioctl_hook(cmd, argp); mutex_unlock(&dlci_ioctl_mutex); break; + case SIOCGSKNS: + err = -EPERM; + if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) + break; + + err = open_related_ns(&net->ns, get_net_ns); + break; default: err = sock_do_ioctl(net, sock, cmd, arg); break; @@ -3316,6 +3328,7 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock, case SIOCSIFVLAN: case SIOCADDDLCI: case SIOCDELDLCI: + case SIOCGSKNS: return sock_ioctl(file, cmd, arg); case SIOCGIFFLAGS: -- 2.24.1 _______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
