]> git.proxmox.com Git - mirror_lxc.git/commitdiff
Merge pull request #2102 from brauner/2018-01-22/lsm_simplifications
authorSerge Hallyn <serge@hallyn.com>
Mon, 29 Jan 2018 23:08:38 +0000 (17:08 -0600)
committerGitHub <noreply@github.com>
Mon, 29 Jan 2018 23:08:38 +0000 (17:08 -0600)
lsm: simplifcations

22 files changed:
.gitignore
doc/ja/lxc-attach.sgml.in
doc/ja/lxc.container.conf.sgml.in
src/lxc/attach.c
src/lxc/cgroups/cgfsng.c
src/lxc/conf.c
src/lxc/console.c
src/lxc/lxc_init.c
src/lxc/lxccontainer.c
src/lxc/monitor.c
src/lxc/network.c
src/lxc/network.h
src/lxc/seccomp.c
src/lxc/start.c
src/lxc/storage/aufs.c
src/lxc/storage/btrfs.c
src/lxc/storage/overlay.c
src/lxc/storage/storage.c
src/lxc/tools/lxc_execute.c
src/lxc/utils.c
src/lxc/utils.h
templates/lxc-debian.in

index f4b74c762c15d3f127ac7ba05f5cc4c5addbba37..2961e07c68ab0a29deba7b9ba855f267b05b5827 100644 (file)
@@ -100,6 +100,11 @@ src/tests/lxc-usernic-test
 src/tests/lxc-test-config-jump-table
 src/tests/lxc-test-parse-config-file
 src/tests/lxc-test-shortlived
+src/tests/lxc-test-api-reboot
+src/tests/lxc-test-criu-check-feature
+src/tests/lxc-test-raw-clone
+src/tests/lxc-test-share-ns
+src/tests/lxc-test-state-server
 
 config/compile
 config/config.guess
index f04ee021b7cd3a3856eb4780ba2a16aa357204f8..19ccfb8aa406d9312c23b2030c23230bf1960c71 100644 (file)
@@ -63,7 +63,6 @@ by KATOH Yasufumi <karma at jazz.email.ne.jp>
       <arg choice="opt">-R, --remount-sys-proc</arg>
       <arg choice="opt">--keep-env</arg>
       <arg choice="opt">--clear-env</arg>
-      <arg choice="opt">-L, --pty-log <replaceable>file</replaceable></arg>
       <arg choice="opt">-v, --set-var <replaceable>variable</replaceable></arg>
       <arg choice="opt">--keep-var <replaceable>variable</replaceable></arg>
       <arg choice="opt">-- <replaceable>command</replaceable></arg>
@@ -338,28 +337,6 @@ by KATOH Yasufumi <karma at jazz.email.ne.jp>
        </listitem>
       </varlistentry>
 
-      <varlistentry>
-        <term>
-          <option>-L, --pty-log <replaceable>file</replaceable></option>
-        </term>
-        <listitem>
-          <para>
-            <!--
-            Specify a file where the output of <command>lxc-attach</command> will be
-            logged.
-              -->
-            <command>lxc-attach</command> の出力を記録するファイルを指定します。
-          </para>
-          <para>
-            <!--
-            <emphasis>Important:</emphasis>  When a standard file descriptor
-            does not refer to a pty output produced on it will not be logged.
-            -->
-            <emphasis>重要:</emphasis> 標準ファイルディスクリプタが pty を参照していない場合、それらに対する出力は記録されないでしょう。
-          </para>
-        </listitem>
-      </varlistentry>
-
       <varlistentry>
        <term>
          <option>-v, --set-var <replaceable>variable</replaceable></option>
index 8f71a73fb3ee1c21b5641174cea8c3df98f7095b..26e64baa7ab661642c81ca00caf3a27f10a01d16 100644 (file)
@@ -2877,7 +2877,7 @@ by KATOH Yasufumi <karma at jazz.email.ne.jp>
         </varlistentry>
         <varlistentry>
           <term>
-            <option>lxc.log</option>
+            <option>lxc.log.file</option>
           </term>
           <listitem>
             <para>
index 45979bcdca1c6be208b4c4894fc2d74ecb479ff0..6d3377f3eb404169f4fdd01ad8ae60f3ba095384 100644 (file)
@@ -742,8 +742,10 @@ static void lxc_put_attach_clone_payload(struct attach_clone_payload *p)
                p->pty_fd = -EBADF;
        }
 
-       if (p->init_ctx)
+       if (p->init_ctx) {
                lxc_proc_put_context_info(p->init_ctx);
+               p->init_ctx = NULL;
+       }
 }
 
 static int attach_child_main(struct attach_clone_payload *payload)
@@ -1045,6 +1047,7 @@ int lxc_attach(const char *name, const char *lxcpath,
        pid_t attached_pid, init_pid, pid;
        struct lxc_proc_context_info *init_ctx;
        struct lxc_console pty;
+       struct lxc_conf *conf;
        struct attach_clone_payload payload = {0};
 
        ret = access("/proc/self/ns", X_OK);
@@ -1089,6 +1092,7 @@ int lxc_attach(const char *name, const char *lxcpath,
                        return -ENOMEM;
                }
        }
+       conf = init_ctx->container->lxc_conf;
 
        if (!fetch_seccomp(init_ctx->container, options))
                WARN("Failed to get seccomp policy.");
@@ -1162,7 +1166,7 @@ int lxc_attach(const char *name, const char *lxcpath,
        }
 
        if (options->attach_flags & LXC_ATTACH_ALLOCATE_PTY) {
-               ret = lxc_attach_pty(init_ctx->container->lxc_conf, &pty);
+               ret = lxc_attach_pty(conf, &pty);
                if (ret < 0) {
                        ERROR("Failed to allocate pty");
                        free(cwd);
@@ -1171,6 +1175,8 @@ int lxc_attach(const char *name, const char *lxcpath,
                }
 
                pty.log_fd = options->log_fd;
+       } else {
+               lxc_pty_init(&pty);
        }
 
        /* Create a socket pair for IPC communication; set SOCK_CLOEXEC in order
@@ -1252,9 +1258,16 @@ int lxc_attach(const char *name, const char *lxcpath,
                              "cgroups", pid);
                }
 
+               /* Setup /proc limits */
+               if (!lxc_list_empty(&conf->procs)) {
+                       ret = setup_proc_filesystem(&conf->procs, pid);
+                       if (ret < 0)
+                               goto on_error;
+               }
+
                /* Setup resource limits */
-               if (!lxc_list_empty(&init_ctx->container->lxc_conf->limits)) {
-                       ret = setup_resource_limits(&init_ctx->container->lxc_conf->limits, pid);
+               if (!lxc_list_empty(&conf->limits)) {
+                       ret = setup_resource_limits(&conf->limits, pid);
                        if (ret < 0)
                                goto on_error;
                }
index 2d1ad4ebb82fd757a694be38724c9002102a0eae..86b39574d45a59445583f69635eb9b7f1c7083d9 100644 (file)
@@ -1221,9 +1221,6 @@ static int recursive_destroy(char *dirname)
                char *pathname;
                struct stat mystat;
 
-               if (!direntp)
-                       break;
-
                if (!strcmp(direntp->d_name, ".") ||
                    !strcmp(direntp->d_name, ".."))
                        continue;
@@ -2143,6 +2140,7 @@ static int lxc_cgroup_set_data(const char *filename, const char *value, struct c
                      "The controller seems to be unused by \"cgfsng\" cgroup "
                      "driver or not enabled on the cgroup hierarchy",
                      controller);
+               errno = ENOENT;
                return -1;
        }
 
index f5bcb9d2411900388f1f693a1eb9fd275ff0ae52..a080bbd7e08d98003c7a79a75e3b1389e3b14622 100644 (file)
@@ -1565,11 +1565,12 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs,
 {
        char path[MAXPATHLEN];
        int ret, fd;
+       char *rootfs_path = rootfs->path ? rootfs->mount : "";
 
        if (console->path && !strcmp(console->path, "none"))
                return 0;
 
-       ret = snprintf(path, sizeof(path), "%s/dev/console", rootfs->mount);
+       ret = snprintf(path, sizeof(path), "%s/dev/console", rootfs_path);
        if (ret < 0 || (size_t)ret >= sizeof(path))
                return -1;
 
@@ -1579,16 +1580,10 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs,
        if (file_exists(path)) {
                ret = lxc_unstack_mountpoint(path, false);
                if (ret < 0) {
-                       ERROR("failed to unmount \"%s\": %s", path, strerror(errno));
+                       ERROR("Failed to unmount \"%s\": %s", path, strerror(errno));
                        return -ret;
                } else {
-                       DEBUG("cleared all (%d) mounts from \"%s\"", ret, path);
-               }
-
-               ret = unlink(path);
-               if (ret < 0) {
-                       SYSERROR("error unlinking %s", path);
-                       return -errno;
+                       DEBUG("Cleared all (%d) mounts from \"%s\"", ret, path);
                }
        }
 
@@ -1598,24 +1593,26 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs,
        fd = open(path, O_CREAT | O_EXCL, S_IXUSR | S_IXGRP | S_IXOTH);
        if (fd < 0) {
                if (errno != EEXIST) {
-                       SYSERROR("failed to create console");
+                       SYSERROR("Failed to create console");
                        return -errno;
                }
        } else {
                close(fd);
        }
 
-       if (chmod(console->name, S_IXUSR | S_IXGRP | S_IXOTH)) {
-               SYSERROR("failed to set mode '0%o' to '%s'", S_IXUSR | S_IXGRP | S_IXOTH, console->name);
+       ret = chmod(console->name, S_IXUSR | S_IXGRP | S_IXOTH);
+       if (ret < 0) {
+               SYSERROR("Failed to set mode '0%o' to '%s'", S_IXUSR | S_IXGRP | S_IXOTH, console->name);
                return -errno;
        }
 
-       if (safe_mount(console->name, path, "none", MS_BIND, 0, rootfs->mount) < 0) {
-               ERROR("failed to mount '%s' on '%s'", console->name, path);
+       ret = safe_mount(console->name, path, "none", MS_BIND, 0, rootfs_path);
+       if (ret < 0) {
+               ERROR("Failed to mount '%s' on '%s'", console->name, path);
                return -1;
        }
 
-       DEBUG("mounted pts device \"%s\" onto \"%s\"", console->name, path);
+       DEBUG("Mounted pts device \"%s\" onto \"%s\"", console->name, path);
        return 0;
 }
 
@@ -1623,137 +1620,91 @@ static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs,
                                    const struct lxc_console *console,
                                    char *ttydir)
 {
-       int ret;
+       int ret, fd;
        char path[MAXPATHLEN], lxcpath[MAXPATHLEN];
+       char *rootfs_path = rootfs->path ? rootfs->mount : "";
+
+       if (console->path && !strcmp(console->path, "none"))
+               return 0;
 
        /* create rootfs/dev/<ttydir> directory */
-       ret = snprintf(path, sizeof(path), "%s/dev/%s", rootfs->mount, ttydir);
+       ret = snprintf(path, sizeof(path), "%s/dev/%s", rootfs_path, ttydir);
        if (ret < 0 || (size_t)ret >= sizeof(path))
                return -1;
 
        ret = mkdir(path, 0755);
        if (ret && errno != EEXIST) {
-               SYSERROR("failed with errno %d to create %s", errno, path);
+               SYSERROR("Failed with errno %d to create %s", errno, path);
                return -errno;
        }
        DEBUG("Created directory for console and tty devices at \"%s\"", path);
 
-       ret = snprintf(lxcpath, sizeof(lxcpath), "%s/dev/%s/console", rootfs->mount, ttydir);
+       ret = snprintf(lxcpath, sizeof(lxcpath), "%s/dev/%s/console", rootfs_path, ttydir);
        if (ret < 0 || (size_t)ret >= sizeof(lxcpath))
                return -1;
 
        ret = creat(lxcpath, 0660);
        if (ret == -1 && errno != EEXIST) {
-               SYSERROR("error %d creating %s", errno, lxcpath);
+               SYSERROR("Error %d creating %s", errno, lxcpath);
                return -errno;
        }
        if (ret >= 0)
                close(ret);
 
-       ret = snprintf(path, sizeof(path), "%s/dev/console", rootfs->mount);
-       if (ret < 0 || (size_t)ret >= sizeof(lxcpath))
+       ret = snprintf(path, sizeof(path), "%s/dev/console", rootfs_path);
+       if (ret < 0 || (size_t)ret >= sizeof(path))
                return -1;
 
-       /* When we are asked to setup a console we remove any previous
-        * /dev/console bind-mounts.
-        */
-       if (console->path && !strcmp(console->path, "none")) {
-               struct stat st;
-               ret = stat(path, &st);
-               if (ret < 0) {
-                       if (errno == ENOENT)
-                               return 0;
-                       SYSERROR("failed stat() \"%s\"", path);
-                       return -errno;
-               }
-
-               /* /dev/console must be character device with major number 5 and
-                * minor number 1. If not, give benefit of the doubt and assume
-                * the user has mounted something else right there on purpose.
-                */
-               if (((st.st_mode & S_IFMT) != S_IFCHR) || major(st.st_rdev) != 5 || minor(st.st_rdev) != 1)
-                       return 0;
-
-               /* In case the user requested a bind-mount for /dev/console and
-                * requests a ttydir we move the mount to the
-                * /dev/<ttydir/console.
-                * Note, we only move the uppermost mount and clear all other
-                * mounts underneath for safety.
-                * If it is a character device created via mknod() we simply
-                * rename it.
-                */
-               ret = safe_mount(path, lxcpath, "none", MS_MOVE, NULL, rootfs->mount);
-               if (ret < 0) {
-                       if (errno != EINVAL) {
-                               ERROR("failed to MS_MOVE \"%s\" to \"%s\": %s", path, lxcpath, strerror(errno));
-                               return -errno;
-                       }
-                       /* path was not a mountpoint */
-                       ret = rename(path, lxcpath);
-                       if (ret < 0) {
-                               ERROR("failed to rename \"%s\" to \"%s\": %s", path, lxcpath, strerror(errno));
-                               return -errno;
-                       }
-                       DEBUG("renamed \"%s\" to \"%s\"", path, lxcpath);
-               } else {
-                       DEBUG("moved mount \"%s\" to \"%s\"", path, lxcpath);
-               }
-
-               /* Clear all remaining bind-mounts. */
+       if (file_exists(path)) {
                ret = lxc_unstack_mountpoint(path, false);
                if (ret < 0) {
-                       ERROR("failed to unmount \"%s\": %s", path, strerror(errno));
+                       ERROR("Failed to unmount \"%s\": %s", path, strerror(errno));
                        return -ret;
                } else {
-                       DEBUG("cleared all (%d) mounts from \"%s\"", ret, path);
-               }
-       } else {
-               if (file_exists(path)) {
-                       ret = lxc_unstack_mountpoint(path, false);
-                       if (ret < 0) {
-                               ERROR("failed to unmount \"%s\": %s", path, strerror(errno));
-                               return -ret;
-                       } else {
-                               DEBUG("cleared all (%d) mounts from \"%s\"", ret, path);
-                       }
+                       DEBUG("Cleared all (%d) mounts from \"%s\"", ret, path);
                }
+       }
 
-               if (safe_mount(console->name, lxcpath, "none", MS_BIND, 0, rootfs->mount) < 0) {
-                       ERROR("failed to mount '%s' on '%s'", console->name, lxcpath);
-                       return -1;
+       fd = open(path, O_CREAT | O_EXCL, S_IXUSR | S_IXGRP | S_IXOTH);
+       if (fd < 0) {
+               if (errno != EEXIST) {
+                       SYSERROR("Failed to create console");
+                       return -errno;
                }
-               DEBUG("mounted \"%s\" onto \"%s\"", console->name, lxcpath);
+       } else {
+               close(fd);
        }
 
-       /* create symlink from rootfs /dev/console to '<ttydir>/console' */
-       ret = snprintf(lxcpath, sizeof(lxcpath), "%s/console", ttydir);
-       if (ret < 0 || (size_t)ret >= sizeof(lxcpath))
-               return -1;
-
-       ret = unlink(path);
-       if (ret && errno != ENOENT) {
-               SYSERROR("error unlinking %s", path);
+       ret = chmod(console->name, S_IXUSR | S_IXGRP | S_IXOTH);
+       if (ret < 0) {
+               SYSERROR("Failed to set mode '0%o' to '%s'", S_IXUSR | S_IXGRP | S_IXOTH, console->name);
                return -errno;
        }
 
-       ret = symlink(lxcpath, path);
+       /* bind mount console->name to '/dev/<ttydir>/console' */
+       ret = safe_mount(console->name, lxcpath, "none", MS_BIND, 0, rootfs_path);
+       if (ret < 0) {
+               ERROR("Failed to mount '%s' on '%s'", console->name, lxcpath);
+               return -1;
+       }
+       DEBUG("Mounted \"%s\" onto \"%s\"", console->name, lxcpath);
+
+       /* bind mount '/dev/<ttydir>/console'  to '/dev/console'  */
+       ret = safe_mount(lxcpath, path, "none", MS_BIND, 0, rootfs_path);
        if (ret < 0) {
-               SYSERROR("failed to create symlink for console from \"%s\" to \"%s\"", lxcpath, path);
+               ERROR("Failed to mount '%s' on '%s'", console->name, lxcpath);
                return -1;
        }
+       DEBUG("Mounted \"%s\" onto \"%s\"", console->name, lxcpath);
+
+       DEBUG("Console has been setup under \"%s\" and mounted to \"%s\"", lxcpath, path);
 
-       DEBUG("console has been setup under \"%s\" and symlinked to \"%s\"", lxcpath, path);
        return 0;
 }
 
 static int lxc_setup_console(const struct lxc_rootfs *rootfs,
                             const struct lxc_console *console, char *ttydir)
 {
-       /* We don't have a rootfs, /dev/console will be shared. */
-       if (!rootfs->path) {
-               DEBUG("/dev/console will be shared with the host");
-               return 0;
-       }
 
        if (!ttydir)
                return lxc_setup_dev_console(rootfs, console);
@@ -2657,15 +2608,17 @@ int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf,
                        return -1;
                }
 
-               buflen = sizeof("deny\n") - 1;
-               errno = 0;
-               ret = lxc_write_nointr(fd, "deny\n", buflen);
-               if (ret != buflen) {
-                       SYSERROR("Failed to write \"deny\" to \"/proc/%d/setgroups\"", pid);
+               if (fd >= 0) {
+                       buflen = sizeof("deny\n") - 1;
+                       errno = 0;
+                       ret = lxc_write_nointr(fd, "deny\n", buflen);
+                       if (ret != buflen) {
+                               SYSERROR("Failed to write \"deny\" to \"/proc/%d/setgroups\"", pid);
+                               close(fd);
+                               return -1;
+                       }
                        close(fd);
-                       return -1;
                }
-               close(fd);
        }
 
        ret = snprintf(path, MAXPATHLEN, "/proc/%d/%cid_map", pid,
index f875f8461b86e8bca80806be65607481376f7748..d613d79874defa6712ad3dcf906cd56144ebd95a 100644 (file)
@@ -747,12 +747,6 @@ int lxc_console_create(struct lxc_conf *conf)
        int ret;
        struct lxc_console *console = &conf->console;
 
-       if (!conf->rootfs.path) {
-               INFO("Container does not have a rootfs. The console will be "
-                    "shared with the host");
-               return 0;
-       }
-
        if (console->path && !strcmp(console->path, "none")) {
                INFO("No console was requested");
                return 0;
index 29394c80d0788c9ef0da3988ae31b28bdd1df42f..594b000941db21a2a789c2b822c1261b7a37afcc 100644 (file)
@@ -155,8 +155,6 @@ static void prevent_forking(void)
        }
 
 on_error:
-       if (fd >= 0)
-               close(fd);
        free(line);
        fclose(f);
 }
@@ -197,23 +195,25 @@ static void kill_children(pid_t pid)
 
 static void remove_self(void)
 {
-       char path[PATH_MAX];
+       int ret;
        ssize_t n;
+       char path[MAXPATHLEN] = {0};
 
        n = readlink("/proc/self/exe", path, sizeof(path));
-       if (n < 0) {
+       if (n < 0 || n >= MAXPATHLEN) {
                SYSERROR("Failed to readlink \"/proc/self/exe\"");
                return;
        }
+       path[n] = '\0';
 
-       path[n] = 0;
-
-       if (umount2(path, MNT_DETACH) < 0) {
+       ret = umount2(path, MNT_DETACH);
+       if (ret < 0) {
                SYSERROR("Failed to unmount \"%s\"", path);
                return;
        }
 
-       if (unlink(path) < 0) {
+       ret = unlink(path);
+       if (ret < 0) {
                SYSERROR("Failed to unlink \"%s\"", path);
                return;
        }
index f6f07bac13cded3ee068aa908facf083759b0cde..cca9f89b986b6f19d14c1757918662cc55d1e95c 100644 (file)
@@ -2678,7 +2678,7 @@ static bool has_snapshots(struct lxc_container *c)
 static bool do_destroy_container(struct lxc_conf *conf) {
        int ret;
 
-       if (am_unpriv()) {
+       if (am_host_unpriv()) {
                ret = userns_exec_full(conf, storage_destroy_wrapper, conf,
                                       "storage_destroy_wrapper");
                if (ret < 0)
@@ -2800,7 +2800,7 @@ static bool container_destroy(struct lxc_container *c,
                if (ret < 0 || (size_t)ret >= len)
                        goto out;
 
-               if (am_unpriv())
+               if (am_host_unpriv())
                        ret = userns_exec_1(conf, lxc_unlink_exec_wrapper, path,
                                            "lxc_unlink_exec_wrapper");
                else
@@ -2819,7 +2819,7 @@ static bool container_destroy(struct lxc_container *c,
        ret = snprintf(path, len, "%s/%s", p1, c->name);
        if (ret < 0 || (size_t)ret >= len)
                goto out;
-       if (am_unpriv())
+       if (am_host_unpriv())
                ret = userns_exec_full(conf, lxc_rmdir_onedev_wrapper, path,
                                       "lxc_rmdir_onedev_wrapper");
        else
@@ -3602,7 +3602,7 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
                }
        }
 
-       if (am_unpriv()) {
+       if (am_host_unpriv()) {
                if (chown_mapped_root(newpath, c->lxc_conf) < 0) {
                        ERROR("Error chowning %s to container root", newpath);
                        goto out;
@@ -3680,7 +3680,7 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
        data.c1 = c2;
        data.flags = flags;
        data.hookargs = hookargs;
-       if (am_unpriv())
+       if (am_host_unpriv())
                ret = userns_exec_full(c->lxc_conf, clone_update_rootfs_wrapper,
                                       &data, "clone_update_rootfs_wrapper");
        else
@@ -4355,7 +4355,7 @@ static bool add_remove_device_node(struct lxc_container *c, const char *src_path
 
 static bool do_lxcapi_add_device_node(struct lxc_container *c, const char *src_path, const char *dest_path)
 {
-       if (am_unpriv()) {
+       if (am_host_unpriv()) {
                ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
                return false;
        }
@@ -4366,7 +4366,7 @@ WRAP_API_2(bool, lxcapi_add_device_node, const char *, const char *)
 
 static bool do_lxcapi_remove_device_node(struct lxc_container *c, const char *src_path, const char *dest_path)
 {
-       if (am_unpriv()) {
+       if (am_host_unpriv()) {
                ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
                return false;
        }
@@ -4382,7 +4382,7 @@ static bool do_lxcapi_attach_interface(struct lxc_container *c,
        pid_t init_pid;
        int ret = 0;
 
-       if (am_unpriv()) {
+       if (am_host_unpriv()) {
                ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
                return false;
        }
@@ -4421,7 +4421,7 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
        int ret;
        pid_t pid, pid_outside;
 
-       if (am_unpriv()) {
+       if (am_host_unpriv()) {
                ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
                return false;
        }
index 6dcdd340d86cd6861c87992d357952d4cb918b18..644d2a52f67d2b9aa2bc05a4a223c8ad0e46738d 100644 (file)
@@ -209,7 +209,6 @@ int lxc_monitor_open(const char *lxcpath)
        int fd;
        size_t retry;
        size_t len;
-       int ret = -1;
        int backoff_ms[] = {10, 50, 100};
 
        if (lxc_monitor_sock_name(lxcpath, &addr) < 0)
@@ -218,16 +217,16 @@ int lxc_monitor_open(const char *lxcpath)
        fd = socket(PF_UNIX, SOCK_STREAM, 0);
        if (fd < 0) {
                ERROR("Failed to create socket: %s.", strerror(errno));
-               return -errno;
+               return -1;
        }
 
        len = strlen(&addr.sun_path[1]);
        DEBUG("opening monitor socket %s with len %zu", &addr.sun_path[1], len);
        if (len >= sizeof(addr.sun_path) - 1) {
                errno = ENAMETOOLONG;
-               ret = -errno;
                ERROR("name of monitor socket too long (%zu bytes): %s", len, strerror(errno));
-               goto on_error;
+               close(fd);
+               return -1;
        }
 
        for (retry = 0; retry < sizeof(backoff_ms) / sizeof(backoff_ms[0]); retry++) {
@@ -239,16 +238,12 @@ int lxc_monitor_open(const char *lxcpath)
        }
 
        if (fd < 0) {
-               ret = -errno;
                ERROR("Failed to connect to monitor socket: %s.", strerror(errno));
-               goto on_error;
+               close(fd);
+               return -1;
        }
 
        return fd;
-
-on_error:
-       close(fd);
-       return ret;
 }
 
 int lxc_monitor_read_fdset(struct pollfd *fds, nfds_t nfds, struct lxc_msg *msg,
index 3954a4f57eebe4822d46747ed6bbc44763c58e9f..0a23dc3eb2ef907f2c3b83d226b7f35c3f78d390 100644 (file)
@@ -1368,32 +1368,6 @@ static int proc_sys_net_write(const char *path, const char *value)
        return err;
 }
 
-static int ip_forward_set(const char *ifname, int family, int flag)
-{
-       int rc;
-       char path[MAXPATHLEN];
-
-       if (family != AF_INET && family != AF_INET6)
-               return -EINVAL;
-
-       rc = snprintf(path, MAXPATHLEN, "/proc/sys/net/%s/conf/%s/forwarding",
-                     family == AF_INET ? "ipv4" : "ipv6", ifname);
-       if (rc < 0 || (size_t)rc >= MAXPATHLEN)
-               return -E2BIG;
-
-       return proc_sys_net_write(path, flag ? "1" : "0");
-}
-
-int lxc_ip_forward_on(const char *ifname, int family)
-{
-       return ip_forward_set(ifname, family, 1);
-}
-
-int lxc_ip_forward_off(const char *ifname, int family)
-{
-       return ip_forward_set(ifname, family, 0);
-}
-
 static int neigh_proxy_set(const char *ifname, int family, int flag)
 {
        int ret;
@@ -2475,7 +2449,7 @@ int lxc_network_move_created_netdev_priv(const char *lxcpath, const char *lxcnam
        char ifname[IFNAMSIZ];
        struct lxc_list *iterator;
 
-       if (am_unpriv())
+       if (am_host_unpriv())
                return 0;
 
        lxc_list_for_each(iterator, network) {
@@ -2513,7 +2487,7 @@ int lxc_create_network_unpriv(const char *lxcpath, const char *lxcname,
 {
        struct lxc_list *iterator;
 
-       if (!am_unpriv())
+       if (!am_host_unpriv())
                return 0;
 
        lxc_list_for_each(iterator, network) {
index 971ef367dd1579e0aa731c35fcb3866e18f616d8..9b9858a52881297b9259233f99b36176cce4f56c 100644 (file)
@@ -207,12 +207,6 @@ extern int lxc_macvlan_create(const char *master, const char *name, int mode);
 extern int lxc_vlan_create(const char *master, const char *name,
                           unsigned short vid);
 
-/* Activate forwarding.*/
-extern int lxc_ip_forward_on(const char *name, int family);
-
-/* Disable forwarding. */
-extern int lxc_ip_forward_off(const char *name, int family);
-
 /* Set ip address. */
 extern int lxc_ipv6_addr_add(int ifindex, struct in6_addr *addr,
                             struct in6_addr *mcast,
index a4b088ed8f0334df4d6f023fb4bd3db0d37f3d03..310a742fc8ee39b9968ee90e247ee77d60f1c1b3 100644 (file)
@@ -144,26 +144,22 @@ struct seccomp_v2_rule {
 
 static enum scmp_compare parse_v2_rule_op(char *s)
 {
-       enum scmp_compare ret;
-
        if (strcmp(s, "SCMP_CMP_NE") == 0 || strcmp(s, "!=") == 0)
-               ret = SCMP_CMP_NE;
+               return SCMP_CMP_NE;
        else if (strcmp(s, "SCMP_CMP_LT") == 0 || strcmp(s, "<") == 0)
-               ret = SCMP_CMP_LT;
+               return SCMP_CMP_LT;
        else if (strcmp(s, "SCMP_CMP_LE") == 0 || strcmp(s, "<=") == 0)
-               ret = SCMP_CMP_LE;
+               return SCMP_CMP_LE;
        else if (strcmp(s, "SCMP_CMP_EQ") == 0 || strcmp(s, "==") == 0)
-               ret = SCMP_CMP_EQ;
+               return SCMP_CMP_EQ;
        else if (strcmp(s, "SCMP_CMP_GE") == 0 || strcmp(s, ">=") == 0)
-               ret = SCMP_CMP_GE;
+               return SCMP_CMP_GE;
        else if (strcmp(s, "SCMP_CMP_GT") == 0 || strcmp(s, ">") == 0)
-               ret = SCMP_CMP_GT;
+               return SCMP_CMP_GT;
        else if (strcmp(s, "SCMP_CMP_MASKED_EQ") == 0 || strcmp(s, "&=") == 0)
-               ret = SCMP_CMP_MASKED_EQ;
-       else
-               ret = _SCMP_CMP_MAX;
+               return SCMP_CMP_MASKED_EQ;
 
-       return ret;
+       return _SCMP_CMP_MAX;
 }
 
 /* This function is used to parse the args string into the structure.
index 41442a162d14f4dec4c6412167b54fd156c79bff..d79fbe2395f473c1c2f5cd88f4479cfacea05f7e 100644 (file)
@@ -494,9 +494,12 @@ int lxc_set_state(const char *name, struct lxc_handler *handler,
 int lxc_poll(const char *name, struct lxc_handler *handler)
 {
        int ret;
-       bool has_console = (handler->conf->rootfs.path != NULL);
+       bool has_console = true;
        struct lxc_epoll_descr descr, descr_console;
 
+       if (handler->conf->console.path && !strcmp(handler->conf->console.path, "none"))
+               has_console = false;
+
        ret = lxc_mainloop_open(&descr);
        if (ret < 0) {
                ERROR("Failed to create mainloop");
@@ -545,22 +548,21 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
        close(descr.epfd);
        descr.epfd = -EBADF;
        if (ret < 0 || !handler->init_died)
-               goto out_mainloop;
+               goto out_mainloop_console;
 
        if (has_console)
                ret = lxc_mainloop(&descr_console, 0);
 
-
-out_mainloop:
-       lxc_mainloop_close(&descr);
-       TRACE("Closed mainloop");
-
 out_mainloop_console:
        if (has_console) {
                lxc_mainloop_close(&descr_console);
                TRACE("Closed console mainloop");
        }
 
+out_mainloop:
+       lxc_mainloop_close(&descr);
+       TRACE("Closed mainloop");
+
 out_sigfd:
        close(handler->sigfd);
        TRACE("Closed signal file descriptor %d", handler->sigfd);
@@ -646,11 +648,11 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
 
        memset(handler, 0, sizeof(*handler));
 
-       /* Note that am_unpriv() checks the effective uid. We probably don't
+       /* Note that am_host_unpriv() checks the effective uid. We probably don't
         * care if we are real root only if we are running as root so this
         * should be fine.
         */
-       handler->am_root = !am_unpriv();
+       handler->am_root = !am_host_unpriv();
        handler->data_sock[0] = handler->data_sock[1] = -1;
        handler->conf = conf;
        handler->lxcpath = lxcpath;
index a39cd60aa6e1a05e7bed56280b6c199b8d5c4b31..0d53c3d8d1a3abcbcbb1abcaff4bb0aea7ab14ec 100644 (file)
@@ -89,7 +89,7 @@ int aufs_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
        if (mkdir_p(new->dest, 0755) < 0)
                return -1;
 
-       if (am_unpriv() && chown_mapped_root(new->dest, conf) < 0)
+       if (am_host_unpriv() && chown_mapped_root(new->dest, conf) < 0)
                WARN("Failed to update ownership of %s", new->dest);
 
        if (strcmp(orig->type, "dir") == 0) {
@@ -116,7 +116,7 @@ int aufs_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
                        free(delta);
                        return -1;
                }
-               if (am_unpriv() && chown_mapped_root(delta, conf) < 0)
+               if (am_host_unpriv() && chown_mapped_root(delta, conf) < 0)
                        WARN("Failed to update ownership of %s", delta);
 
                // the src will be 'aufs:lowerdir:upperdir'
@@ -157,13 +157,13 @@ int aufs_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
                        free(ndelta);
                        return -1;
                }
-               if (am_unpriv() && chown_mapped_root(ndelta, conf) < 0)
+               if (am_host_unpriv() && chown_mapped_root(ndelta, conf) < 0)
                        WARN("Failed to update ownership of %s", ndelta);
 
                struct rsync_data_char rdata;
                rdata.src = odelta;
                rdata.dest = ndelta;
-               if (am_unpriv())
+               if (am_host_unpriv())
                        ret = userns_exec_full(conf, lxc_rsync_delta_wrapper,
                                               &rdata, "lxc_rsync_delta_wrapper");
                else
index ec7ba62ee6a10133683ad7f6455130b5c3ad7ed7..4e21020fdfc370ec7ca1126ad3c68c6b645e0a33 100644 (file)
@@ -434,7 +434,7 @@ bool btrfs_create_clone(struct lxc_conf *conf, struct lxc_storage *orig,
        /* rsync the contents from source to target */
        data.orig = orig;
        data.new = new;
-       if (am_unpriv()) {
+       if (am_host_unpriv()) {
                ret = userns_exec_full(conf, lxc_storage_rsync_exec_wrapper,
                                       &data, "lxc_storage_rsync_exec_wrapper");
                if (ret < 0) {
@@ -466,7 +466,7 @@ bool btrfs_create_snapshot(struct lxc_conf *conf, struct lxc_storage *orig,
        if (ret < 0 && errno != ENOENT)
                return false;
 
-       if (am_unpriv()) {
+       if (am_host_unpriv()) {
                struct rsync_data_char args;
 
                args.src = orig->src;
index d2f3ed00c1aa33bf90f114280cd30c1cd5e8640e..e3aae8a29e797d5ef1c135ab86d19fdf811be3a8 100644 (file)
@@ -73,7 +73,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
                return -1;
        }
 
-       if (am_unpriv()) {
+       if (am_host_unpriv()) {
                ret = chown_mapped_root(new->dest, conf);
                if (ret < 0)
                        WARN("Failed to update ownership of %s", new->dest);
@@ -120,7 +120,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
                        return -1;
                }
 
-               if (am_unpriv()) {
+               if (am_host_unpriv()) {
                        ret = chown_mapped_root(delta, conf);
                        if (ret < 0)
                                WARN("Failed to update ownership of %s", delta);
@@ -153,7 +153,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
                        return -1;
                }
 
-               if (am_unpriv()) {
+               if (am_host_unpriv()) {
                        ret = chown_mapped_root(work, conf);
                        if (ret < 0)
                                WARN("Failed to update ownership of %s", work);
@@ -224,7 +224,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
                        return -1;
                }
 
-               if (am_unpriv()) {
+               if (am_host_unpriv()) {
                        ret = chown_mapped_root(ndelta, conf);
                        if (ret < 0)
                                WARN("Failed to update ownership of %s",
@@ -265,7 +265,7 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
                        return -1;
                }
 
-               if (am_unpriv()) {
+               if (am_host_unpriv()) {
                        ret = chown_mapped_root(work, conf);
                        if (ret < 0)
                                WARN("Failed to update ownership of %s", work);
@@ -960,7 +960,7 @@ static int ovl_do_rsync(const char *src, const char *dest,
 
        rdata.src = (char *)src;
        rdata.dest = (char *)dest;
-       if (am_unpriv())
+       if (am_host_unpriv())
                ret = userns_exec_full(conf, lxc_rsync_exec_wrapper, &rdata,
                                       "lxc_rsync_exec_wrapper");
        else
index e080ad87ad4a52e417bafa9ce0e2948a001ceb2e..6cb98f6b7ea4544c23dbdf0cd119d46e92130f3b 100644 (file)
@@ -406,7 +406,7 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
        if (!bdevtype && !keepbdevtype && snap && !strcmp(orig->type, "dir"))
                bdevtype = "overlay";
 
-       if (am_unpriv() && !unpriv_snap_allowed(orig, bdevtype, snap, maybe_snap)) {
+       if (am_host_unpriv() && !unpriv_snap_allowed(orig, bdevtype, snap, maybe_snap)) {
                ERROR("Unsupported snapshot type \"%s\" for unprivileged users",
                      bdevtype ? bdevtype : "(null)");
                goto on_error_put_orig;
@@ -505,7 +505,7 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
                else
                        src_no_prefix = lxc_storage_get_path(new->src, new->type);
 
-               if (am_unpriv()) {
+               if (am_host_unpriv()) {
                        ret = chown_mapped_root(src_no_prefix, c->lxc_conf);
                        if (ret < 0)
                                WARN("Failed to chown \"%s\"", new->src);
@@ -518,7 +518,7 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
        /* rsync the contents from source to target */
        data.orig = orig;
        data.new = new;
-       if (am_unpriv())
+       if (am_host_unpriv())
                ret = userns_exec_full(c->lxc_conf,
                                       lxc_storage_rsync_exec_wrapper, &data,
                                       "lxc_storage_rsync_exec_wrapper");
index 98f846fc2f7fa66a418c8e3c41657774197b4781..3348d7c1c291d625aebeddec6ef0526b6041ab24 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
 #include <errno.h>
 #include <libgen.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <lxc/lxccontainer.h>
-#include <sys/types.h>
-#include <sys/stat.h>
 #include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 
+#include <lxc/lxccontainer.h>
+
+#include "arguments.h"
 #include "caps.h"
-#include "lxc.h"
-#include "log.h"
 #include "conf.h"
-#include "confile.h"
-#include "arguments.h"
 #include "config.h"
+#include "confile.h"
+#include "log.h"
+#include "lxc.h"
 #include "start.h"
 #include "utils.h"
 
index a20e4b715ebbf71a5c7cfce67bf6ff1489dda039..c7812fdac97a7e09bcc2bd2f0e38c51b6bc2a61b 100644 (file)
@@ -245,8 +245,13 @@ char *get_rundir()
 {
        char *rundir;
        const char *homedir;
+       struct stat sb;
+
+       if (stat(RUNTIME_PATH, &sb) < 0) {
+               return NULL;
+       }
 
-       if (geteuid() == 0) {
+       if (geteuid() == sb.st_uid || getegid() == sb.st_gid) {
                rundir = strdup(RUNTIME_PATH);
                return rundir;
        }
@@ -2415,12 +2420,8 @@ int parse_byte_size_string(const char *s, int64_t *converted)
        if (suffix_len > 0 && (end - 2) == dup && !isdigit(*(end - 2)))
                return -EINVAL;
 
-       if (suffix_len > 0 && isalpha(*(end - 2))) {
-               if (suffix_len == 1)
-                       suffix_len++;
-               else
-                       return -EINVAL;
-       }
+       if (suffix_len > 0 && isalpha(*(end - 2)))
+               suffix_len++;
 
        if (suffix_len > 0) {
                memcpy(suffix, end - suffix_len, suffix_len);
index 188b646a3ad6107b3118b39954712776b3065d2a..223580edcc9cb41316044b8dc395a9817d95ee15 100644 (file)
@@ -427,8 +427,32 @@ extern int lxc_strmunmap(void *addr, size_t length);
 /* initialize rand with urandom */
 extern int randseed(bool);
 
-inline static bool am_unpriv(void) {
-       return geteuid() != 0;
+inline static bool am_host_unpriv(void)
+{
+       FILE *f;
+       uid_t user, host, count;
+       int ret;
+
+       if (geteuid() != 0)
+               return true;
+
+       /* Now: are we in a user namespace? Because then we're also
+        * unprivileged.
+        */
+       f = fopen("/proc/self/uid_map", "r");
+       if (!f) {
+               return false;
+       }
+
+       ret = fscanf(f, "%u %u %u", &user, &host, &count);
+       fclose(f);
+       if (ret != 3) {
+               return false;
+       }
+
+       if (user != 0 || host != 0 || count != UINT32_MAX)
+               return true;
+       return false;
 }
 
 /*
index fa87cb95dcb9fd71bd8f3f446ee07625577615f0..2656eeaaf9d7098cd28f81bbc59038800398c67a 100644 (file)
@@ -329,7 +329,7 @@ dialog,\
 isc-dhcp-client,\
 netbase,\
 net-tools,\
-iproute,\
+iproute2,\
 openssh-server
 
     cache=$1