From 112930688bd306592a215180cf9b5801e5358eb8 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Thu, 12 Apr 2018 11:12:06 +0200 Subject: [PATCH 1/2] conf: ret-try devpts mount without gid=5 on error We should always default to mounting devpts with gid=5 but we should fallback to mounting without gid=5. This let's us cover use-cases such as container started with only a single mapping e.g.: lxc.idmap = u 1000 1000 1 lxc.idmap = g 1000 1000 1 Closes #2257. Signed-off-by: Christian Brauner --- src/lxc/conf.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 443087d6c..212c3c96f 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -1523,7 +1523,7 @@ static struct id_map *find_mapped_nsid_entry(struct lxc_conf *conf, unsigned id, static int lxc_setup_devpts(struct lxc_conf *conf) { int ret; - const char *default_devpts_mntopts; + const char *default_devpts_mntopts = "gid=5,newinstance,ptmxmode=0666,mode=0620"; char devpts_mntopts[256]; if (conf->pts <= 0) { @@ -1532,11 +1532,6 @@ static int lxc_setup_devpts(struct lxc_conf *conf) return 0; } - if (!find_mapped_nsid_entry(conf, 5, ID_TYPE_GID)) - default_devpts_mntopts = "newinstance,ptmxmode=0666,mode=0620"; - else - default_devpts_mntopts = "newinstance,ptmxmode=0666,mode=0620,gid=5"; - ret = snprintf(devpts_mntopts, sizeof(devpts_mntopts), "%s,max=%d", default_devpts_mntopts, conf->pts); if (ret < 0 || (size_t)ret >= sizeof(devpts_mntopts)) @@ -1560,11 +1555,16 @@ static int lxc_setup_devpts(struct lxc_conf *conf) return -1; } - /* Mount new devpts instance. */ + /* mount new devpts instance */ ret = mount("devpts", "/dev/pts", "devpts", MS_NOSUID | MS_NOEXEC, devpts_mntopts); if (ret < 0) { - SYSERROR("Failed to mount new devpts instance"); - return -1; + /* try mounting without gid=5 */ + ret = mount("devpts", "/dev/pts", "devpts", + MS_NOSUID | MS_NOEXEC, devpts_mntopts + sizeof("gid=5")); + if (ret < 0) { + SYSERROR("Failed to mount new devpts instance"); + return -1; + } } DEBUG("Mount new devpts instance with options \"%s\"", devpts_mntopts); From 794248d09d3a60633c901becc9d985db697f2feb Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Thu, 12 Apr 2018 12:49:20 +0200 Subject: [PATCH 2/2] execute: fix app containers without root mapping When starting application containers without a mapping for container root are started, a dummy bind-mount target for lxc-init needs to be created. This will not always work directly under "/" when e.g. permissions are missing due to the ownership and/or mode of "/". We can try to work around this by using the P_tmpdir as defined in POSIX which should usually land us in /tmp where basically everyone can create files. Signed-off-by: Christian Brauner --- src/lxc/conf.c | 26 +++++++++++++++----------- src/lxc/execute.c | 16 ++++------------ src/lxc/start.h | 6 ++++++ 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 212c3c96f..283a58218 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -99,6 +99,7 @@ #include "network.h" #include "parse.h" #include "ringbuf.h" +#include "start.h" #include "storage.h" #include "storage/overlay.h" #include "terminal.h" @@ -3206,10 +3207,12 @@ void remount_all_slave(void) free(line); } -static int lxc_execute_bind_init(struct lxc_conf *conf) +static int lxc_execute_bind_init(struct lxc_handler *handler) { int ret; - char path[PATH_MAX], destpath[PATH_MAX], *p; + char *p; + char path[PATH_MAX], destpath[PATH_MAX]; + struct lxc_conf *conf = handler->conf; /* If init exists in the container, don't bind mount a static one */ p = choose_init(conf->rootfs.mount); @@ -3227,20 +3230,16 @@ static int lxc_execute_bind_init(struct lxc_conf *conf) return -1; } - ret = snprintf(destpath, PATH_MAX, "%s%s", conf->rootfs.mount, "/init.lxc.static"); + ret = snprintf(destpath, PATH_MAX, "%s" P_tmpdir "%s", conf->rootfs.mount, "/.lxc-init"); if (ret < 0 || ret >= PATH_MAX) return -1; if (!file_exists(destpath)) { - FILE *pathfile; - - pathfile = fopen(destpath, "wb"); - if (!pathfile) { - SYSERROR("Failed to create mount target \"%s\"", destpath); + ret = mknod(destpath, S_IFREG | 0000, 0); + if (ret < 0 && errno != EEXIST) { + SYSERROR("Failed to create dummy \"%s\" file as bind mount target", destpath); return -1; } - - fclose(pathfile); } ret = safe_mount(path, destpath, "none", MS_BIND, NULL, conf->rootfs.mount); @@ -3249,6 +3248,11 @@ static int lxc_execute_bind_init(struct lxc_conf *conf) return -1; } + p = strdup(destpath + strlen(conf->rootfs.mount)); + if (!p) + return -ENOMEM; + ((struct execute_args *)handler->data)->init_path = p; + INFO("Bind mounted lxc.init.static into container at \"%s\"", path); return 0; } @@ -3383,7 +3387,7 @@ int lxc_setup(struct lxc_handler *handler) return -1; if (lxc_conf->is_execute) { - ret = lxc_execute_bind_init(lxc_conf); + ret = lxc_execute_bind_init(handler); if (ret < 0) { ERROR("Failed to bind-mount the lxc init system"); return -1; diff --git a/src/lxc/execute.c b/src/lxc/execute.c index 6adef9bf2..c7320ab2d 100644 --- a/src/lxc/execute.c +++ b/src/lxc/execute.c @@ -34,18 +34,12 @@ lxc_log_define(lxc_execute, lxc_start); -struct execute_args { - char *const *argv; - int quiet; -}; - static int execute_start(struct lxc_handler *handler, void* data) { int j, i = 0; struct execute_args *my_args = data; char **argv; int argc = 0, argc_add; - char *initpath; while (my_args->argv[argc++]); @@ -62,12 +56,10 @@ static int execute_start(struct lxc_handler *handler, void* data) if (!argv) goto out1; - initpath = choose_init(NULL); - if (!initpath) { - ERROR("Failed to find an init.lxc or init.lxc.static"); + if (!my_args->init_path) goto out2; - } - argv[i++] = initpath; + + argv[i++] = my_args->init_path; argv[i++] = "-n"; argv[i++] = (char *)handler->name; @@ -99,7 +91,7 @@ static int execute_start(struct lxc_handler *handler, void* data) execvp(argv[0], argv); SYSERROR("Failed to exec %s", argv[0]); - free(initpath); + out2: free(argv); out1: diff --git a/src/lxc/start.h b/src/lxc/start.h index e6aabe78c..5455ca5f3 100644 --- a/src/lxc/start.h +++ b/src/lxc/start.h @@ -134,6 +134,12 @@ struct lxc_handler { int exit_status; }; +struct execute_args { + char *init_path; + char *const *argv; + int quiet; +}; + struct lxc_operations { int (*start)(struct lxc_handler *, void *); int (*post_start)(struct lxc_handler *, void *);