]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
conf: use run_command for lxc-usernsexec 1592/head
authorChristian Brauner <christian.brauner@ubuntu.com>
Mon, 29 May 2017 02:30:16 +0000 (04:30 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Tue, 30 May 2017 07:11:47 +0000 (09:11 +0200)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/conf.c

index f0f7253f940be021ab7be1b7f01570db31896706..afef2b9a6b5a3f1d534070bd612fde50691f2891 100644 (file)
@@ -1453,6 +1453,7 @@ static int lxc_setup_devpts(int num_pts)
                SYSERROR("failed to mount new devpts instance");
                return -1;
        }
+       DEBUG("mount new devpts instance with options \"%s\"", devpts_mntopts);
 
        /* Remove any pre-existing /dev/ptmx file. */
        ret = access("/dev/ptmx", F_OK);
@@ -3750,6 +3751,13 @@ void lxc_delete_tty(struct lxc_tty_info *tty_info)
        tty_info->nbtty = 0;
 }
 
+
+int chown_mapped_root_exec_wrapper(void *args)
+{
+       execvp("lxc-usernsexec", args);
+       return -1;
+}
+
 /*
  * chown_mapped_root: for an unprivileged user with uid/gid X to
  * chown a dir to subuid/subgid Y, he needs to run chown as root
@@ -3760,26 +3768,46 @@ void lxc_delete_tty(struct lxc_tty_info *tty_info)
  */
 int chown_mapped_root(char *path, struct lxc_conf *conf)
 {
-       uid_t rootuid;
-       gid_t rootgid;
-       pid_t pid;
+       uid_t rootuid, rootgid;
        unsigned long val;
        char *chownpath = path;
+       int hostuid, hostgid, ret;
+       struct stat sb;
+       char map1[100], map2[100], map3[100], map4[100], map5[100];
+       char ugid[100];
+       char *args1[] = {"lxc-usernsexec",
+                        "-m", map1,
+                        "-m", map2,
+                        "-m", map3,
+                        "-m", map5,
+                        "--", "chown", ugid, path,
+                        NULL};
+       char *args2[] = {"lxc-usernsexec",
+                        "-m", map1,
+                        "-m", map2,
+                        "-m", map3,
+                        "-m", map4,
+                        "-m", map5,
+                        "--", "chown", ugid, path,
+                        NULL};
+       char cmd_output[MAXPATHLEN];
+
+       hostuid = geteuid();
+       hostgid = getegid();
 
        if (!get_mapped_rootid(conf, ID_TYPE_UID, &val)) {
                ERROR("No uid mapping for container root");
                return -1;
        }
-       rootuid = (uid_t) val;
+       rootuid = (uid_t)val;
        if (!get_mapped_rootid(conf, ID_TYPE_GID, &val)) {
                ERROR("No gid mapping for container root");
                return -1;
        }
-       rootgid = (gid_t) val;
+       rootgid = (gid_t)val;
 
        /*
-        * In case of overlay, we want only the writeable layer
-        * to be chowned
+        * In case of overlay, we want only the writeable layer to be chowned
         */
        if (strncmp(path, "overlayfs:", 10) == 0 || strncmp(path, "aufs:", 5) == 0) {
                chownpath = strchr(path, ':');
@@ -3787,7 +3815,7 @@ int chown_mapped_root(char *path, struct lxc_conf *conf)
                        ERROR("Bad overlay path: %s", path);
                        return -1;
                }
-               chownpath = strchr(chownpath+1, ':');
+               chownpath = strchr(chownpath + 1, ':');
                if (!chownpath) {
                        ERROR("Bad overlay path: %s", path);
                        return -1;
@@ -3795,7 +3823,7 @@ int chown_mapped_root(char *path, struct lxc_conf *conf)
                chownpath++;
        }
        path = chownpath;
-       if (geteuid() == 0) {
+       if (hostuid == 0) {
                if (chown(path, rootuid, rootgid) < 0) {
                        ERROR("Error chowning %s", path);
                        return -1;
@@ -3803,97 +3831,85 @@ int chown_mapped_root(char *path, struct lxc_conf *conf)
                return 0;
        }
 
-       if (rootuid == geteuid()) {
+       if (rootuid == hostuid) {
                // nothing to do
                INFO("%s: container root is our uid;  no need to chown" ,__func__);
                return 0;
        }
 
-       pid = fork();
-       if (pid < 0) {
-               SYSERROR("Failed forking");
+       // save the current gid of "path"
+       if (stat(path, &sb) < 0) {
+               ERROR("Error stat %s", path);
                return -1;
        }
-       if (!pid) {
-               int hostuid = geteuid(), hostgid = getegid(), ret;
-               struct stat sb;
-               char map1[100], map2[100], map3[100], map4[100], map5[100];
-               char ugid[100];
-               char *args1[] = { "lxc-usernsexec", "-m", map1, "-m", map2,
-                               "-m", map3, "-m", map5,
-                               "--", "chown", ugid, path, NULL };
-               char *args2[] = { "lxc-usernsexec", "-m", map1, "-m", map2,
-                               "-m", map3, "-m", map4, "-m", map5,
-                               "--", "chown", ugid, path, NULL };
-
-               // save the current gid of "path"
-               if (stat(path, &sb) < 0) {
-                       ERROR("Error stat %s", path);
-                       return -1;
-               }
-
-               /*
-                * A file has to be group-owned by a gid mapped into the
-                * container, or the container won't be privileged over it.
-                */
-               if (sb.st_uid == geteuid() &&
-                               mapped_hostid(sb.st_gid, conf, ID_TYPE_GID) < 0 &&
-                               chown(path, -1, hostgid) < 0) {
-                       ERROR("Failed chgrping %s", path);
-                       return -1;
-               }
 
-               // "u:0:rootuid:1"
-               ret = snprintf(map1, 100, "u:0:%d:1", rootuid);
-               if (ret < 0 || ret >= 100) {
-                       ERROR("Error uid printing map string");
-                       return -1;
-               }
+       /*
+        * A file has to be group-owned by a gid mapped into the
+        * container, or the container won't be privileged over it.
+        */
+       DEBUG("trying to chown \"%s\" to %d", path, hostgid);
+       if (sb.st_uid == hostuid &&
+           mapped_hostid(sb.st_gid, conf, ID_TYPE_GID) < 0 &&
+           chown(path, -1, hostgid) < 0) {
+               ERROR("Failed chgrping %s", path);
+               return -1;
+       }
 
-               // "u:hostuid:hostuid:1"
-               ret = snprintf(map2, 100, "u:%d:%d:1", hostuid, hostuid);
-               if (ret < 0 || ret >= 100) {
-                       ERROR("Error uid printing map string");
-                       return -1;
-               }
+       // "u:0:rootuid:1"
+       ret = snprintf(map1, 100, "u:0:%d:1", rootuid);
+       if (ret < 0 || ret >= 100) {
+               ERROR("Error uid printing map string");
+               return -1;
+       }
 
-               // "g:0:rootgid:1"
-               ret = snprintf(map3, 100, "g:0:%d:1", rootgid);
-               if (ret < 0 || ret >= 100) {
-                       ERROR("Error gid printing map string");
-                       return -1;
-               }
+       // "u:hostuid:hostuid:1"
+       ret = snprintf(map2, 100, "u:%d:%d:1", hostuid, hostuid);
+       if (ret < 0 || ret >= 100) {
+               ERROR("Error uid printing map string");
+               return -1;
+       }
 
-               // "g:pathgid:rootgid+pathgid:1"
-               ret = snprintf(map4, 100, "g:%d:%d:1", (gid_t)sb.st_gid,
-                               rootgid + (gid_t)sb.st_gid);
-               if (ret < 0 || ret >= 100) {
-                       ERROR("Error gid printing map string");
-                       return -1;
-               }
+       // "g:0:rootgid:1"
+       ret = snprintf(map3, 100, "g:0:%d:1", rootgid);
+       if (ret < 0 || ret >= 100) {
+               ERROR("Error gid printing map string");
+               return -1;
+       }
 
-               // "g:hostgid:hostgid:1"
-               ret = snprintf(map5, 100, "g:%d:%d:1", hostgid, hostgid);
-               if (ret < 0 || ret >= 100) {
-                       ERROR("Error gid printing map string");
-                       return -1;
-               }
+       // "g:pathgid:rootgid+pathgid:1"
+       ret = snprintf(map4, 100, "g:%d:%d:1", (gid_t)sb.st_gid,
+                      rootgid + (gid_t)sb.st_gid);
+       if (ret < 0 || ret >= 100) {
+               ERROR("Error gid printing map string");
+               return -1;
+       }
 
-               // "0:pathgid" (chown)
-               ret = snprintf(ugid, 100, "0:%d", (gid_t)sb.st_gid);
-               if (ret < 0 || ret >= 100) {
-                       ERROR("Error owner printing format string for chown");
-                       return -1;
-               }
+       // "g:hostgid:hostgid:1"
+       ret = snprintf(map5, 100, "g:%d:%d:1", hostgid, hostgid);
+       if (ret < 0 || ret >= 100) {
+               ERROR("Error gid printing map string");
+               return -1;
+       }
 
-               if (hostgid == sb.st_gid)
-                       ret = execvp("lxc-usernsexec", args1);
-               else
-                       ret = execvp("lxc-usernsexec", args2);
-               SYSERROR("Failed executing usernsexec");
-               exit(1);
+       // "0:pathgid" (chown)
+       ret = snprintf(ugid, 100, "0:%d", (gid_t)sb.st_gid);
+       if (ret < 0 || ret >= 100) {
+               ERROR("Error owner printing format string for chown");
+               return -1;
        }
-       return wait_for_pid(pid);
+
+       if (hostgid == sb.st_gid)
+               ret = run_command(cmd_output, sizeof(cmd_output),
+                                 chown_mapped_root_exec_wrapper,
+                                 (void *)args1);
+       else
+               ret = run_command(cmd_output, sizeof(cmd_output),
+                                 chown_mapped_root_exec_wrapper,
+                                 (void *)args2);
+       if (ret < 0)
+               ERROR("lxc-usernsexec failed: %s", cmd_output);
+
+       return ret;
 }
 
 int ttys_shift_ids(struct lxc_conf *c)