[20/28] net: Add file_desc_ops::get_user_ns for sockets

Submitted by Kirill Tkhai on June 5, 2017, 5:26 p.m.

Details

Message ID 149668358451.25229.8878577194241428062.stgit@localhost.localdomain
State Accepted
Series "Support sockets leaked to child user_ns task"
Commit fabf6f77cc241882cef5aae205376e04e169ce9f
Headers show

Commit Message

Kirill Tkhai June 5, 2017, 5:26 p.m.
Return user_ns of saved net ns_id.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 criu/include/sockets.h |    1 +
 criu/sk-inet.c         |    8 ++++++++
 criu/sk-netlink.c      |    8 ++++++++
 criu/sk-packet.c       |    8 ++++++++
 criu/sk-unix.c         |   14 ++++++++++++++
 criu/sockets.c         |    8 ++++++++
 6 files changed, 47 insertions(+)

Patch hide | download patch | download mbox

diff --git a/criu/include/sockets.h b/criu/include/sockets.h
index ad503a472..adea91115 100644
--- a/criu/include/sockets.h
+++ b/criu/include/sockets.h
@@ -42,6 +42,7 @@  extern struct collect_image_info netlink_sk_cinfo;
 
 extern struct socket_desc *lookup_socket(unsigned ino, int family, int proto);
 extern void fixup_sock_net_ns_id(uint32_t *ns_id, protobuf_c_boolean *has_ns_id);
+extern void sock_get_user_ns(uint32_t sock_net_ns_id, struct ns_id **sock_user_ns);
 
 extern const struct fdtype_ops unix_dump_ops;
 extern const struct fdtype_ops inet_dump_ops;
diff --git a/criu/sk-inet.c b/criu/sk-inet.c
index 6499d52c0..79fa80c27 100644
--- a/criu/sk-inet.c
+++ b/criu/sk-inet.c
@@ -497,9 +497,17 @@  int inet_collect_one(struct nlmsghdr *h, int family, int type, struct ns_id *ns)
 static int open_inet_sk(struct file_desc *d, int *new_fd);
 static int post_open_inet_sk(struct file_desc *d, int sk);
 
+static void inet_get_user_ns(struct file_desc *desc, uint32_t *file_uns_id, struct ns_id **setns_uns)
+{
+	uint32_t net_ns_id;
+	net_ns_id = container_of(desc, struct inet_sk_info, d)->ie->ns_id;
+	sock_get_user_ns(net_ns_id, setns_uns);
+}
+
 static struct file_desc_ops inet_desc_ops = {
 	.type = FD_TYPES__INETSK,
 	.open = open_inet_sk,
+	.get_user_ns = inet_get_user_ns,
 };
 
 static inline int tcp_connection(InetSkEntry *ie)
diff --git a/criu/sk-netlink.c b/criu/sk-netlink.c
index ae3a4d231..44982a1da 100644
--- a/criu/sk-netlink.c
+++ b/criu/sk-netlink.c
@@ -228,9 +228,17 @@  static int open_netlink_sk(struct file_desc *d, int *new_fd)
 	return -1;
 }
 
+static void netlink_get_user_ns(struct file_desc *desc, uint32_t *file_uns_id, struct ns_id **setns_uns)
+{
+	uint32_t net_ns_id;
+	net_ns_id = container_of(desc, struct netlink_sock_info, d)->nse->ns_id;
+	sock_get_user_ns(net_ns_id, setns_uns);
+}
+
 static struct file_desc_ops netlink_sock_desc_ops = {
 	.type = FD_TYPES__NETLINKSK,
 	.open = open_netlink_sk,
+	.get_user_ns = netlink_get_user_ns,
 };
 
 static int collect_one_netlink_sk(void *o, ProtobufCMessage *base, struct cr_img *i)
diff --git a/criu/sk-packet.c b/criu/sk-packet.c
index f2deddb82..372e9be7b 100644
--- a/criu/sk-packet.c
+++ b/criu/sk-packet.c
@@ -554,9 +554,17 @@  static int open_packet_sk(struct file_desc *d, int *new_fd)
 	return -1;
 }
 
+static void packet_get_user_ns(struct file_desc *desc, uint32_t *file_uns_id, struct ns_id **setns_uns)
+{
+	uint32_t net_ns_id;
+	net_ns_id = container_of(desc, struct packet_sock_info, d)->pse->ns_id;
+	sock_get_user_ns(net_ns_id, setns_uns);
+}
+
 static struct file_desc_ops packet_sock_desc_ops = {
 	.type = FD_TYPES__PACKETSK,
 	.open = open_packet_sk,
+	.get_user_ns = packet_get_user_ns,
 };
 
 static int collect_one_packet_sk(void *o, ProtobufCMessage *base, struct cr_img *i)
diff --git a/criu/sk-unix.c b/criu/sk-unix.c
index 6a5a0bc73..7c71448de 100644
--- a/criu/sk-unix.c
+++ b/criu/sk-unix.c
@@ -1346,9 +1346,23 @@  static char *socket_d_name(struct file_desc *d, char *buf, size_t s)
 	return buf;
 }
 
+static void unix_get_user_ns(struct file_desc *desc, uint32_t *file_uns_id, struct ns_id **setns_uns)
+{
+	struct unix_sk_info *ui;
+	uint32_t net_ns_id;
+
+	ui = container_of(desc, struct unix_sk_info, d);
+	net_ns_id = ui->ue->ns_id;
+	if (ui->ue->uflags & USK_EXTERN)
+		*setns_uns = NULL;
+	else
+		sock_get_user_ns(net_ns_id, setns_uns);
+}
+
 static struct file_desc_ops unix_desc_ops = {
 	.type = FD_TYPES__UNIXSK,
 	.open = open_unix_sk,
+	.get_user_ns = unix_get_user_ns,
 	.name = socket_d_name,
 };
 
diff --git a/criu/sockets.c b/criu/sockets.c
index d6e5fce61..9b0c4df99 100644
--- a/criu/sockets.c
+++ b/criu/sockets.c
@@ -786,3 +786,11 @@  void fixup_sock_net_ns_id(uint32_t *ns_id, protobuf_c_boolean *has_ns_id)
 	*has_ns_id = true;
 	*ns_id = top_net_ns->id;
 }
+
+void sock_get_user_ns(uint32_t sock_net_ns_id, struct ns_id **sock_user_ns)
+{
+	struct ns_id *net_ns_id;
+	net_ns_id = lookup_ns_by_id(sock_net_ns_id, &net_ns_desc);
+	BUG_ON(!net_ns_id);
+	*sock_user_ns = net_ns_id->user_ns;
+}