The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxc/pull/1801

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Closes #1800.

Signed-off-by: Christian Brauner <[email protected]>
From 415a8851483d354f8e95d6d9788687fbdf48a69d Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Sat, 9 Sep 2017 11:20:57 +0200
Subject: [PATCH 1/7] conf: add userns_exec_full()

Closes #1800.

Signed-off-by: Christian Brauner <[email protected]>
---
 src/lxc/conf.c | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/lxc/conf.h |   2 +
 2 files changed, 181 insertions(+), 2 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 7a1188165..8544e32f5 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -3816,8 +3816,7 @@ int userns_exec_1(struct lxc_conf *conf, int (*fn)(void 
*), void *data,
        ret = lxc_map_ids(idmap, pid);
        if (ret < 0) {
                ERROR("error setting up {g,u}id mappings for child process "
-                     "\"%d\"",
-                     pid);
+                     "\"%d\"", pid);
                goto on_error;
        }
 
@@ -3849,6 +3848,184 @@ int userns_exec_1(struct lxc_conf *conf, int (*fn)(void 
*), void *data,
        return ret;
 }
 
+int userns_exec_full(struct lxc_conf *conf, int (*fn)(void *), void *data,
+                    const char *fn_name)
+{
+       pid_t pid;
+       uid_t euid, egid;
+       struct userns_fn_data d;
+       int p[2];
+       struct id_map *map;
+       struct lxc_list *cur;
+       char c = '1';
+       int ret = -1;
+       struct lxc_list *idmap = NULL, *tmplist = NULL;
+       struct id_map *container_root_uid = NULL, *container_root_gid = NULL,
+                     *host_uid_map = NULL, *host_gid_map = NULL;
+
+       ret = pipe(p);
+       if (ret < 0) {
+               SYSERROR("opening pipe");
+               return -1;
+       }
+       d.fn = fn;
+       d.fn_name = fn_name;
+       d.arg = data;
+       d.p[0] = p[0];
+       d.p[1] = p[1];
+
+       /* Clone child in new user namespace. */
+       pid = lxc_clone(run_userns_fn, &d, CLONE_NEWUSER);
+       if (pid < 0) {
+               ERROR("failed to clone child process in new user namespace");
+               goto on_error;
+       }
+
+       close(p[0]);
+       p[0] = -1;
+
+       euid = geteuid();
+       egid = getegid();
+
+       /* Allocate new {g,u}id map list. */
+       idmap = malloc(sizeof(*idmap));
+       if (!idmap)
+               goto on_error;
+       lxc_list_init(idmap);
+
+       /* Find container root. */
+       lxc_list_for_each(cur, &conf->id_map) {
+               struct id_map *tmpmap;
+
+               tmplist = malloc(sizeof(*tmplist));
+               if (!tmplist)
+                       goto on_error;
+
+               tmpmap = malloc(sizeof(*tmpmap));
+               if (!tmpmap) {
+                       free(tmplist);
+                       goto on_error;
+               }
+
+               memset(tmpmap, 0, sizeof(*tmpmap));
+               memcpy(tmpmap, cur->elem, sizeof(*tmpmap));
+               tmplist->elem = tmpmap;
+
+               lxc_list_add_tail(idmap, tmplist);
+
+               map = cur->elem;
+
+               if (map->idtype == ID_TYPE_UID)
+                       if (euid >= map->hostid && euid < map->hostid + 
map->range)
+                               host_uid_map = map;
+
+               if (map->idtype == ID_TYPE_GID)
+                       if (egid >= map->hostid && egid < map->hostid + 
map->range)
+                               host_gid_map = map;
+
+               if (map->nsid != 0)
+                       continue;
+
+               if (map->idtype == ID_TYPE_UID)
+                       if (container_root_uid == NULL)
+                               container_root_uid = map;
+
+               if (map->idtype == ID_TYPE_GID)
+                       if (container_root_gid == NULL)
+                               container_root_gid = map;
+       }
+
+       if (!container_root_uid || !container_root_gid) {
+               ERROR("No mapping for container root found");
+               goto on_error;
+       }
+
+       /* Check whether the {g,u}id of the user has a mapping. */
+       if (!host_uid_map)
+               host_uid_map = idmap_add(conf, euid, ID_TYPE_UID);
+       else
+               host_uid_map = container_root_uid;
+
+       if (!host_gid_map)
+               host_gid_map = idmap_add(conf, egid, ID_TYPE_GID);
+       else
+               host_gid_map = container_root_gid;
+
+       if (!host_uid_map) {
+               DEBUG("Failed to find mapping for uid %d", euid);
+               goto on_error;
+       }
+
+       if (!host_gid_map) {
+               DEBUG("Failed to find mapping for gid %d", egid);
+               goto on_error;
+       }
+
+       if (host_uid_map && (host_uid_map != container_root_uid)) {
+               /* Add container root to the map. */
+               tmplist = malloc(sizeof(*tmplist));
+               if (!tmplist)
+                       goto on_error;
+               lxc_list_add_elem(tmplist, host_uid_map);
+               lxc_list_add_tail(idmap, tmplist);
+       }
+       /* idmap will now keep track of that memory. */
+       host_uid_map = NULL;
+
+       if (host_gid_map && (host_gid_map != container_root_gid)) {
+               tmplist = malloc(sizeof(*tmplist));
+               if (!tmplist)
+                       goto on_error;
+               lxc_list_add_elem(tmplist, host_gid_map);
+               lxc_list_add_tail(idmap, tmplist);
+       }
+       /* idmap will now keep track of that memory. */
+       host_gid_map = NULL;
+
+       if (lxc_log_get_level() == LXC_LOG_LEVEL_TRACE ||
+           conf->loglevel == LXC_LOG_LEVEL_TRACE) {
+               lxc_list_for_each(cur, idmap) {
+                       map = cur->elem;
+                       TRACE("establishing %cid mapping for \"%d\" in new "
+                             "user namespace: nsuid %lu - hostid %lu - range "
+                             "%lu",
+                             (map->idtype == ID_TYPE_UID) ? 'u' : 'g', pid,
+                             map->nsid, map->hostid, map->range);
+               }
+       }
+
+       /* Set up {g,u}id mapping for user namespace of child process. */
+       ret = lxc_map_ids(idmap, pid);
+       if (ret < 0) {
+               ERROR("error setting up {g,u}id mappings for child process "
+                     "\"%d\"", pid);
+               goto on_error;
+       }
+
+       /* Tell child to proceed. */
+       if (write(p[1], &c, 1) != 1) {
+               SYSERROR("failed telling child process \"%d\" to proceed", pid);
+               goto on_error;
+       }
+
+       /* Wait for child to finish. */
+       ret = wait_for_pid(pid);
+
+on_error:
+       if (idmap)
+               lxc_free_idmap(idmap);
+       if (host_uid_map && (host_uid_map != container_root_uid))
+               free(host_uid_map);
+       if (host_gid_map && (host_gid_map != container_root_gid))
+               free(host_gid_map);
+
+       if (p[0] != -1)
+               close(p[0]);
+       close(p[1]);
+
+       return ret;
+}
+
 /* not thread-safe, do not use from api without first forking */
 static char* getuname(void)
 {
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 882c9cd83..946ae4a23 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -381,6 +381,8 @@ extern int chown_mapped_root(char *path, struct lxc_conf 
*conf);
 extern int lxc_ttys_shift_ids(struct lxc_conf *c);
 extern int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data,
                         const char *fn_name);
+extern int userns_exec_full(struct lxc_conf *conf, int (*fn)(void *),
+                           void *data, const char *fn_name);
 extern int parse_mntopts(const char *mntopts, unsigned long *mntflags,
                         char **mntdata);
 extern void tmp_proc_unmount(struct lxc_conf *lxc_conf);

From ee484f7f6851088b16532ea82bce506b1434c05a Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Sat, 9 Sep 2017 11:21:16 +0200
Subject: [PATCH 2/7] lxccontainer: use userns_exec_full()

Closes #1800.

Signed-off-by: Christian Brauner <[email protected]>
---
 src/lxc/lxccontainer.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 093a2992b..5e8ad00f9 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -2569,12 +2569,17 @@ static bool has_snapshots(struct lxc_container *c)
 }
 
 static bool do_destroy_container(struct lxc_conf *conf) {
+       int ret;
+
        if (am_unpriv()) {
-               if (userns_exec_1(conf, storage_destroy_wrapper, conf,
-                                 "storage_destroy_wrapper") < 0)
+               ret = userns_exec_full(conf, storage_destroy_wrapper, conf,
+                                      "storage_destroy_wrapper");
+               if (ret < 0)
                        return false;
+
                return true;
        }
+
        return storage_destroy(conf);
 }
 
@@ -2708,8 +2713,8 @@ static bool container_destroy(struct lxc_container *c,
        if (ret < 0 || (size_t)ret >= len)
                goto out;
        if (am_unpriv())
-               ret = userns_exec_1(conf, lxc_rmdir_onedev_wrapper, path,
-                                   "lxc_rmdir_onedev_wrapper");
+               ret = userns_exec_full(conf, lxc_rmdir_onedev_wrapper, path,
+                                      "lxc_rmdir_onedev_wrapper");
        else
                ret = lxc_rmdir_onedev(path, "snaps");
        if (ret < 0) {
@@ -3551,8 +3556,8 @@ static struct lxc_container *do_lxcapi_clone(struct 
lxc_container *c, const char
        data.flags = flags;
        data.hookargs = hookargs;
        if (am_unpriv())
-               ret = userns_exec_1(c->lxc_conf, clone_update_rootfs_wrapper,
-                                   &data, "clone_update_rootfs_wrapper");
+               ret = userns_exec_full(c->lxc_conf, clone_update_rootfs_wrapper,
+                                      &data, "clone_update_rootfs_wrapper");
        else
                ret = clone_update_rootfs(&data);
        if (ret < 0)

From 94b0a3ac393d0081520a0f32004ce15e2ade13af Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Sat, 9 Sep 2017 11:21:51 +0200
Subject: [PATCH 3/7] start: userns_exec_full()

Closes #1800.

Signed-off-by: Christian Brauner <[email protected]>
---
 src/lxc/start.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/lxc/start.c b/src/lxc/start.c
index 1370d681c..4fc289557 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -1596,8 +1596,8 @@ static void lxc_destroy_container_on_signal(struct 
lxc_handler *handler,
        }
 
        if (!handler->am_root)
-               ret = userns_exec_1(handler->conf, lxc_rmdir_onedev_wrapper,
-                                   destroy, "lxc_rmdir_onedev_wrapper");
+               ret = userns_exec_full(handler->conf, lxc_rmdir_onedev_wrapper,
+                                      destroy, "lxc_rmdir_onedev_wrapper");
        else
                ret = lxc_rmdir_onedev(destroy, NULL);
 
@@ -1615,9 +1615,12 @@ static int lxc_rmdir_onedev_wrapper(void *data)
 }
 
 static bool do_destroy_container(struct lxc_handler *handler) {
+       int ret;
+
        if (!handler->am_root) {
-               if (userns_exec_1(handler->conf, storage_destroy_wrapper,
-                                 handler->conf, "storage_destroy_wrapper") < 0)
+               ret = userns_exec_full(handler->conf, storage_destroy_wrapper,
+                                      handler->conf, 
"storage_destroy_wrapper");
+               if (ret < 0)
                        return false;
 
                return true;

From 5c05427a60171963fa56d45150374080fe2f223f Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Sat, 9 Sep 2017 11:22:44 +0200
Subject: [PATCH 4/7] storage: use userns_exec_full()

Closes #1800.

Signed-off-by: Christian Brauner <[email protected]>
---
 src/lxc/storage/aufs.c    | 4 ++--
 src/lxc/storage/btrfs.c   | 4 ++--
 src/lxc/storage/overlay.c | 4 ++--
 src/lxc/storage/storage.c | 5 +++--
 src/lxc/storage/storage.h | 1 -
 5 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/lxc/storage/aufs.c b/src/lxc/storage/aufs.c
index 312c32bcd..a39cd60aa 100644
--- a/src/lxc/storage/aufs.c
+++ b/src/lxc/storage/aufs.c
@@ -164,8 +164,8 @@ int aufs_clonepaths(struct lxc_storage *orig, struct 
lxc_storage *new,
                rdata.src = odelta;
                rdata.dest = ndelta;
                if (am_unpriv())
-                       ret = userns_exec_1(conf, lxc_rsync_delta_wrapper,
-                                           &rdata, "lxc_rsync_delta_wrapper");
+                       ret = userns_exec_full(conf, lxc_rsync_delta_wrapper,
+                                              &rdata, 
"lxc_rsync_delta_wrapper");
                else
                        ret = run_command(cmd_output, sizeof(cmd_output),
                                          lxc_rsync_delta_wrapper,
diff --git a/src/lxc/storage/btrfs.c b/src/lxc/storage/btrfs.c
index 1fe0d5acd..29b44dfdf 100644
--- a/src/lxc/storage/btrfs.c
+++ b/src/lxc/storage/btrfs.c
@@ -434,8 +434,8 @@ bool btrfs_create_clone(struct lxc_conf *conf, struct 
lxc_storage *orig,
        data.orig = orig;
        data.new = new;
        if (am_unpriv()) {
-               ret = userns_exec_1(conf, lxc_storage_rsync_exec_wrapper, &data,
-                                   "lxc_storage_rsync_exec_wrapper");
+               ret = userns_exec_full(conf, lxc_storage_rsync_exec_wrapper,
+                                      &data, "lxc_storage_rsync_exec_wrapper");
                if (ret < 0) {
                        ERROR("Failed to rsync from \"%s\" into \"%s\"",
                              orig->dest, new->dest);
diff --git a/src/lxc/storage/overlay.c b/src/lxc/storage/overlay.c
index e63a6ba56..7fe4536bb 100644
--- a/src/lxc/storage/overlay.c
+++ b/src/lxc/storage/overlay.c
@@ -971,8 +971,8 @@ static int ovl_do_rsync(const char *src, const char *dest,
        rdata.src = (char *)src;
        rdata.dest = (char *)dest;
        if (am_unpriv())
-               ret = userns_exec_1(conf, lxc_rsync_exec_wrapper, &rdata,
-                                   "lxc_rsync_exec_wrapper");
+               ret = userns_exec_full(conf, lxc_rsync_exec_wrapper, &rdata,
+                                      "lxc_rsync_exec_wrapper");
        else
                ret = run_command(cmd_output, sizeof(cmd_output),
                                  lxc_rsync_exec_wrapper, (void *)&rdata);
diff --git a/src/lxc/storage/storage.c b/src/lxc/storage/storage.c
index fee3d8df1..30aaaaa93 100644
--- a/src/lxc/storage/storage.c
+++ b/src/lxc/storage/storage.c
@@ -502,8 +502,9 @@ struct lxc_storage *storage_copy(struct lxc_container *c, 
const char *cname,
        data.orig = orig;
        data.new = new;
        if (am_unpriv())
-               ret = userns_exec_1(c->lxc_conf, lxc_storage_rsync_exec_wrapper,
-                                   &data, "lxc_storage_rsync_exec_wrapper");
+               ret = userns_exec_full(c->lxc_conf,
+                                      lxc_storage_rsync_exec_wrapper, &data,
+                                      "lxc_storage_rsync_exec_wrapper");
        else
                ret = run_command(cmd_output, sizeof(cmd_output),
                                  lxc_storage_rsync_exec_wrapper, (void 
*)&data);
diff --git a/src/lxc/storage/storage.h b/src/lxc/storage/storage.h
index aa819df65..c656d3952 100644
--- a/src/lxc/storage/storage.h
+++ b/src/lxc/storage/storage.h
@@ -136,7 +136,6 @@ extern struct lxc_storage *storage_create(const char *dest, 
const char *type,
 extern void storage_put(struct lxc_storage *bdev);
 extern bool storage_destroy(struct lxc_conf *conf);
 
-/* callback function to be used with userns_exec_1() */
 extern int storage_destroy_wrapper(void *data);
 extern bool rootfs_is_blockdev(struct lxc_conf *conf);
 extern char *lxc_storage_get_path(char *src, const char *prefix);

From a05a723f6a08fecfbef68a02dc0080c2ca9ac9ad Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Sat, 9 Sep 2017 11:23:14 +0200
Subject: [PATCH 5/7] console: remove dead assignments

non-functional changes

Signed-off-by: Christian Brauner <[email protected]>
---
 src/lxc/console.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/lxc/console.c b/src/lxc/console.c
index 97ae7a16e..c882b85c6 100644
--- a/src/lxc/console.c
+++ b/src/lxc/console.c
@@ -480,7 +480,6 @@ static int lxc_console_peer_default(struct lxc_console 
*console)
        console->tios = malloc(sizeof(*console->tios));
        if (!console->tios) {
                SYSERROR("failed to allocate memory");
-               ret = -ENOMEM;
                goto on_error1;
        }
 
@@ -492,7 +491,6 @@ static int lxc_console_peer_default(struct lxc_console 
*console)
 on_error2:
        free(console->tios);
        console->tios = NULL;
-       ret = -ENOTTY;
 
 on_error1:
        close(console->peer);

From 4dd08ac85fe302c288284d4dabb76462d67c2877 Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Sat, 9 Sep 2017 11:23:34 +0200
Subject: [PATCH 6/7] monitor: remove dead assignment

non-functional changes

Signed-off-by: Christian Brauner <[email protected]>
---
 src/lxc/monitor.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/lxc/monitor.c b/src/lxc/monitor.c
index 63a404d62..166329a7c 100644
--- a/src/lxc/monitor.c
+++ b/src/lxc/monitor.c
@@ -243,7 +243,6 @@ int lxc_monitor_open(const char *lxcpath)
                ERROR("Failed to connect to monitor socket: %s.", 
strerror(errno));
                goto on_error;
        }
-       ret = 0;
 
        return fd;
 

From 9e2bdae4a64ccbf59d9e402951be2ca01ecb5449 Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Sat, 9 Sep 2017 11:23:55 +0200
Subject: [PATCH 7/7] start: remove dead variable

non-functional changes

Signed-off-by: Christian Brauner <[email protected]>
---
 src/lxc/start.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/src/lxc/start.c b/src/lxc/start.c
index 4fc289557..3ccb73311 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -1142,7 +1142,7 @@ static int lxc_spawn(struct lxc_handler *handler)
        bool wants_to_map_ids;
        int saved_ns_fd[LXC_NS_MAX];
        struct lxc_list *id_map;
-       int failed_before_rename = 0, preserve_mask = 0;
+       int preserve_mask = 0;
        bool cgroups_connected = false;
 
        id_map = &handler->conf->id_map;
@@ -1256,15 +1256,11 @@ static int lxc_spawn(struct lxc_handler *handler)
                goto out_delete_net;
        }
 
-       if (lxc_sync_wake_child(handler, LXC_SYNC_STARTUP)) {
-               failed_before_rename = 1;
+       if (lxc_sync_wake_child(handler, LXC_SYNC_STARTUP))
                goto out_delete_net;
-       }
 
-       if (lxc_sync_wait_child(handler, LXC_SYNC_CONFIGURE)) {
-               failed_before_rename = 1;
+       if (lxc_sync_wait_child(handler, LXC_SYNC_CONFIGURE))
                goto out_delete_net;
-       }
 
        if (!cgroup_create_legacy(handler)) {
                ERROR("Failed to setup legacy cgroups for container \"%s\".", 
name);
@@ -1281,9 +1277,6 @@ static int lxc_spawn(struct lxc_handler *handler)
        if (!cgroup_chown(handler))
                goto out_delete_net;
 
-       if (failed_before_rename)
-               goto out_delete_net;
-
        handler->netnsfd = lxc_preserve_ns(handler->pid, "net");
        if (handler->netnsfd < 0) {
                ERROR("Failed to preserve network namespace");
_______________________________________________
lxc-devel mailing list
[email protected]
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to