From 794248d09d3a60633c901becc9d985db697f2feb Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Thu, 12 Apr 2018 12:49:20 +0200 Subject: [PATCH] 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 *); -- 2.47.2