]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
execute: fix app containers without root mapping 2272/head
authorChristian Brauner <christian.brauner@ubuntu.com>
Thu, 12 Apr 2018 10:49:20 +0000 (12:49 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Thu, 12 Apr 2018 15:37:53 +0000 (17:37 +0200)
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 <christian.brauner@ubuntu.com>
src/lxc/conf.c
src/lxc/execute.c
src/lxc/start.h

index 212c3c96fe6a0369c01bc9f50545e7b6edc54121..283a58218b7eda5cf16fb7437ee496bdd54bc617 100644 (file)
@@ -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;
index 6adef9bf2121e8ec22caa4e52e67b3afe8a46a9c..c7320ab2d090430bdbd28507db19c1196f453e25 100644 (file)
 
 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:
index e6aabe78c9125f269f646849ff9c8a339e49be9c..5455ca5f35f3f7207ef438b494da6e87d288d046 100644 (file)
@@ -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 *);