[Devel] [PATCH RH7 24/32] net: add an ioctl to get a socket network namespace
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Mon Jun 8 20:05:54 MSK 2020
From: Andrey Vagin <avagin at openvz.org>
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" <davem at davemloft.net>
Cc: Eric W. Biederman <ebiederm at xmission.com>
Signed-off-by: Andrei Vagin <avagin at openvz.org>
Signed-off-by: David S. Miller <davem at davemloft.net>
(cherry picked from VZ8 commit c62cce2caee558e18aa05c01c2fd3b40f07174f2)
https://jira.sw.ru/browse/PSBM-102357
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
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
More information about the Devel
mailing list