From: Christian Brauner Date: Fri, 27 Mar 2020 20:25:59 +0000 (+0100) Subject: conf: simplify userns_exec_minimal() X-Git-Tag: lxc-5.0.0~487^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F3333%2Fhead;p=thirdparty%2Flxc.git conf: simplify userns_exec_minimal() Signed-off-by: Christian Brauner --- diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c index 8563ed7d2..d326a87e2 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c @@ -2123,29 +2123,10 @@ struct userns_exec_unified_attach_data { static int cgroup_unified_attach_wrapper(void *data) { struct userns_exec_unified_attach_data *args = data; - uid_t nsuid; - gid_t nsgid; - int ret; if (!args->conf || args->unified_fd < 0 || args->pid <= 0) return ret_errno(EINVAL); - if (!lxc_setgroups(0, NULL) && errno != EPERM) - return log_error_errno(-1, errno, "Failed to setgroups(0, NULL)"); - - nsuid = (args->conf->root_nsuid_map != NULL) ? 0 : args->conf->init_uid; - nsgid = (args->conf->root_nsgid_map != NULL) ? 0 : args->conf->init_gid; - - ret = setresgid(nsgid, nsgid, nsgid); - if (ret < 0) - return log_error_errno(-1, errno, "Failed to setresgid(%d, %d, %d)", - (int)nsgid, (int)nsgid, (int)nsgid); - - ret = setresuid(nsuid, nsuid, nsuid); - if (ret < 0) - return log_error_errno(-1, errno, "Failed to setresuid(%d, %d, %d)", - (int)nsuid, (int)nsuid, (int)nsuid); - return cgroup_attach_leaf(args->conf, args->unified_fd, args->pid); } diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 9e106b100..9fc5c68a7 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -3940,7 +3940,8 @@ static struct id_map *mapped_hostid_add(const struct lxc_conf *conf, uid_t id, return move_ptr(entry); } -static struct lxc_list *get_minimal_idmap(const struct lxc_conf *conf) +static struct lxc_list *get_minimal_idmap(const struct lxc_conf *conf, + uid_t *resuid, gid_t *resgid) { __do_free struct id_map *container_root_uid = NULL, *container_root_gid = NULL, @@ -4029,7 +4030,12 @@ static struct lxc_list *get_minimal_idmap(const struct lxc_conf *conf) /* idmap will now keep track of that memory. */ move_ptr(host_gid_map); - TRACE("Allocated minimal idmapping"); + TRACE("Allocated minimal idmapping for ns uid %d and ns gid %d", nsuid, nsgid); + + if (resuid) + *resuid = nsuid; + if (resgid) + *resgid = nsgid; return move_ptr(idmap); } @@ -4058,7 +4064,7 @@ int userns_exec_1(const struct lxc_conf *conf, int (*fn)(void *), void *data, if (!conf) return -EINVAL; - idmap = get_minimal_idmap(conf); + idmap = get_minimal_idmap(conf, NULL, NULL); if (!idmap) return ret_errno(ENOENT); @@ -4123,16 +4129,17 @@ on_error: int userns_exec_minimal(const struct lxc_conf *conf, int (*fn)(void *), void *data) { call_cleaner(lxc_free_idmap) struct lxc_list *idmap = NULL; - int ret = -1, status = -1; - ssize_t rret; + uid_t resuid = LXC_INVALID_UID; + gid_t resgid = LXC_INVALID_GID; char c = '1'; + ssize_t ret; pid_t pid; int sock_fds[2]; - if (!conf) - return -EINVAL; + if (!conf || !fn || !data) + return ret_errno(EINVAL); - idmap = get_minimal_idmap(conf); + idmap = get_minimal_idmap(conf, &resuid, &resgid); if (!idmap) return ret_errno(ENOENT); @@ -4142,7 +4149,7 @@ int userns_exec_minimal(const struct lxc_conf *conf, int (*fn)(void *), void *da pid = fork(); if (pid < 0) { - ERROR("Failed to clone process in new user namespace"); + SYSERROR("Failed to create new process"); goto on_error; } @@ -4150,11 +4157,13 @@ int userns_exec_minimal(const struct lxc_conf *conf, int (*fn)(void *), void *da close_prot_errno_disarm(sock_fds[1]); ret = unshare(CLONE_NEWUSER); - if (ret < 0) + if (ret < 0) { + SYSERROR("Failed to unshare new user namespace"); _exit(EXIT_FAILURE); + } - rret = lxc_write_nointr(sock_fds[0], &c, 1); - if (rret != 1) + ret = lxc_write_nointr(sock_fds[0], &c, 1); + if (ret != 1) _exit(EXIT_FAILURE); ret = lxc_read_nointr(sock_fds[0], &c, 1); @@ -4166,12 +4175,25 @@ int userns_exec_minimal(const struct lxc_conf *conf, int (*fn)(void *), void *da if (!lxc_setgroups(0, NULL) && errno != EPERM) _exit(EXIT_FAILURE); - if (!lxc_switch_uid_gid(0, 0)) + ret = setresgid(resgid, resgid, resgid); + if (ret < 0) { + SYSERROR("Failed to setresgid(%d, %d, %d)", + resgid, resgid, resgid); _exit(EXIT_FAILURE); + } + + ret = setresuid(resuid, resuid, resuid); + if (ret < 0) { + SYSERROR("Failed to setresuid(%d, %d, %d)", + resuid, resuid, resuid); + _exit(EXIT_FAILURE); + } ret = fn(data); - if (ret) + if (ret) { + SYSERROR("Running function in new user namespace failed"); _exit(EXIT_FAILURE); + } _exit(EXIT_SUCCESS); } @@ -4215,13 +4237,10 @@ on_error: close_prot_errno_disarm(sock_fds[1]); /* Wait for child to finish. */ - if (pid > 0) - status = wait_for_pid(pid); - - if (status < 0) - ret = -1; + if (pid < 0) + return -1; - return ret; + return wait_for_pid(pid); } int userns_exec_full(struct lxc_conf *conf, int (*fn)(void *), void *data,