[lxc-devel] [lxc/master] Unshare netns after setting the userns mappings

hallyn on Github lxc-bot at linuxcontainers.org
Mon May 9 21:13:14 UTC 2016


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 456 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20160509/9a0c133b/attachment.bin>
-------------- next part --------------
From 5b1e83cbc498cd3edeaf13afa987d530299a35a7 Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge.hallyn at ubuntu.com>
Date: Mon, 9 May 2016 15:30:46 -0500
Subject: [PATCH] Unshare netns after setting the userns mappings

so that there is a root uid mapping for the /proc/net files.

Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
---
 src/lxc/start.c | 48 ++++++++++++++++++++++++++++++++++++------------
 src/lxc/sync.c  |  5 +++++
 src/lxc/sync.h  |  2 ++
 3 files changed, 43 insertions(+), 12 deletions(-)

diff --git a/src/lxc/start.c b/src/lxc/start.c
index d9d5814..5437206 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -736,6 +736,20 @@ static int do_start(void *data)
 		close(handler->pinfd);
 	}
 
+	if (lxc_sync_wait_parent(handler, LXC_SYNC_STARTUP))
+		return -1;
+
+	/* Unshare CLONE_NEWNET after CLONE_NEWUSER  - see
+	  https://github.com/lxc/lxd/issues/1978 */
+	if ((handler->clone_flags & (CLONE_NEWNET | CLONE_NEWUSER)) ==
+			(CLONE_NEWNET | CLONE_NEWUSER)) {
+		ret = unshare(CLONE_NEWNET);
+		if (ret < 0) {
+			SYSERROR("Error unsharing network namespace");
+			goto out_warn_father;
+		}
+	}
+
 	/* Tell the parent task it can begin to configure the
 	 * container and wait for it to finish
 	 */
@@ -1027,7 +1041,7 @@ static int lxc_spawn(struct lxc_handler *handler)
 	char *errmsg = NULL;
 	bool cgroups_connected = false;
 	int saved_ns_fd[LXC_NS_MAX];
-	int preserve_mask = 0, i;
+	int preserve_mask = 0, i, flags;
 	int netpipepair[2], nveths;
 
 	netpipe = -1;
@@ -1118,6 +1132,9 @@ static int lxc_spawn(struct lxc_handler *handler)
 	}
 
 	/* Create a process in a new set of namespaces */
+	flags = handler->clone_flags;
+	if (handler->clone_flags & CLONE_NEWUSER)
+		flags &= ~CLONE_NEWNET;
 	handler->pid = lxc_clone(do_start, handler, handler->clone_flags);
 	if (handler->pid < 0) {
 		SYSERROR("failed to fork into a new namespace");
@@ -1135,8 +1152,25 @@ static int lxc_spawn(struct lxc_handler *handler)
 
 	lxc_sync_fini_child(handler);
 
-	if (lxc_sync_wait_child(handler, LXC_SYNC_CONFIGURE))
+	/* map the container uids - the container became an invalid
+	 * userid the moment it was cloned with CLONE_NEWUSER - this
+	 * call doesn't change anything immediately, but allows the
+	 * container to setuid(0) (0 being mapped to something else on
+	 * the host) later to become a valid uid again */
+	if (lxc_map_ids(&handler->conf->id_map, handler->pid)) {
+		ERROR("failed to set up id mapping");
+		goto out_delete_net;
+	}
+
+	if (lxc_sync_wake_child(handler, LXC_SYNC_STARTUP)) {
 		failed_before_rename = 1;
+		goto out_delete_net;
+	}
+
+	if (lxc_sync_wait_child(handler, LXC_SYNC_CONFIGURE)) {
+		failed_before_rename = 1;
+		goto out_delete_net;
+	}
 
 	if (!cgroup_create_legacy(handler)) {
 		ERROR("failed to setup the legacy cgroups for %s", name);
@@ -1182,16 +1216,6 @@ static int lxc_spawn(struct lxc_handler *handler)
 		close(netpipepair[1]);
 	}
 
-	/* map the container uids - the container became an invalid
-	 * userid the moment it was cloned with CLONE_NEWUSER - this
-	 * call doesn't change anything immediately, but allows the
-	 * container to setuid(0) (0 being mapped to something else on
-	 * the host) later to become a valid uid again */
-	if (lxc_map_ids(&handler->conf->id_map, handler->pid)) {
-		ERROR("failed to set up id mapping");
-		goto out_delete_net;
-	}
-
 	/* Tell the child to continue its initialization.  we'll get
 	 * LXC_SYNC_CGROUP when it is ready for us to setup cgroups
 	 */
diff --git a/src/lxc/sync.c b/src/lxc/sync.c
index c9fbcd9..7f23622 100644
--- a/src/lxc/sync.c
+++ b/src/lxc/sync.c
@@ -99,6 +99,11 @@ int lxc_sync_wake_parent(struct lxc_handler *handler, int sequence)
 	return __sync_wake(handler->sv[0], sequence);
 }
 
+int lxc_sync_wait_parent(struct lxc_handler *handler, int sequence)
+{
+	return __sync_wait(handler->sv[0], sequence);
+}
+
 int lxc_sync_wait_child(struct lxc_handler *handler, int sequence)
 {
 	return __sync_wait(handler->sv[1], sequence);
diff --git a/src/lxc/sync.h b/src/lxc/sync.h
index d0aee6f..12a8b95 100644
--- a/src/lxc/sync.h
+++ b/src/lxc/sync.h
@@ -26,6 +26,7 @@
 struct lxc_handler;
 
 enum {
+	LXC_SYNC_STARTUP,
 	LXC_SYNC_CONFIGURE,
 	LXC_SYNC_POST_CONFIGURE,
 	LXC_SYNC_CGROUP,
@@ -42,6 +43,7 @@ void lxc_sync_fini_child(struct lxc_handler *);
 int lxc_sync_wake_child(struct lxc_handler *, int);
 int lxc_sync_wait_child(struct lxc_handler *, int);
 int lxc_sync_wake_parent(struct lxc_handler *, int);
+int lxc_sync_wait_parent(struct lxc_handler *, int);
 int lxc_sync_barrier_parent(struct lxc_handler *, int);
 int lxc_sync_barrier_child(struct lxc_handler *, int);
 


More information about the lxc-devel mailing list