]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
Unshare netns after setting the userns mappings 1014/head
authorSerge Hallyn <serge.hallyn@ubuntu.com>
Mon, 9 May 2016 20:30:46 +0000 (15:30 -0500)
committerSerge Hallyn <serge.hallyn@ubuntu.com>
Mon, 9 May 2016 20:53:26 +0000 (15:53 -0500)
so that there is a root uid mapping for the /proc/net files.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
src/lxc/start.c
src/lxc/sync.c
src/lxc/sync.h

index d9d5814b5b5e314b0e790415c0641c3983b2f9e8..54372066b9cb40f18db4dec180d9f29a5fd623cd 100644 (file)
@@ -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
         */
index c9fbcd934a0115c4f0f09baaf34c44aa3a9c9639..7f23622eb8a231316e1133c30db7b4e5b97e74ea 100644 (file)
@@ -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);
index d0aee6fe97ee37be718aad5290ab05481200fe81..12a8b95926e8cb0ea85983c7ed586d4037b3fc12 100644 (file)
@@ -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);