]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
cgfsng: use init {g,u}id
authorChristian Brauner <christian.brauner@ubuntu.com>
Tue, 2 Jan 2018 22:41:10 +0000 (23:41 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Fri, 19 Jan 2018 13:26:16 +0000 (14:26 +0100)
If no id mapping for the container's root id is defined try to us the id
mappings specified via lxc.init.{g,u}id.

Closes #2033.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/cgroups/cgfsng.c
src/lxc/conf.c
src/lxc/confile.c
src/lxc/start.c

index 26c25a214c13a22279e10112cda86e2a86bef6bd..c0367ee859e5e122db67399529daee5119d816dd 100644 (file)
@@ -1244,25 +1244,41 @@ next:
        return r;
 }
 
+struct generic_userns_exec_data {
+       struct cgfsng_handler_data *d;
+       struct lxc_conf *conf;
+       uid_t origuid; /* target uid in parent namespace */
+       char *path;
+};
+
 static int rmdir_wrapper(void *data)
 {
-       char *path = data;
+       struct generic_userns_exec_data *arg = data;
+       uid_t nsuid = (arg->conf->root_nsuid_map != NULL) ? 0 : arg->conf->init_uid;
+       gid_t nsgid = (arg->conf->root_nsgid_map != NULL) ? 0 : arg->conf->init_gid;
 
-       if (setresgid(0,0,0) < 0)
+       if (setresgid(nsgid, nsgid, nsgid) < 0)
                SYSERROR("Failed to setgid to 0");
-       if (setresuid(0,0,0) < 0)
+       if (setresuid(nsuid, nsuid, nsuid) < 0)
                SYSERROR("Failed to setuid to 0");
        if (setgroups(0, NULL) < 0)
                SYSERROR("Failed to clear groups");
 
-       return cgroup_rmdir(path);
+       return cgroup_rmdir(arg->path);
 }
 
 void recursive_destroy(char *path, struct lxc_conf *conf)
 {
        int r;
+       struct generic_userns_exec_data wrap;
+
+       wrap.origuid = 0;
+       wrap.d = NULL;
+       wrap.path = path;
+       wrap.conf = conf;
+
        if (conf && !lxc_list_empty(&conf->id_map))
-               r = userns_exec_1(conf, rmdir_wrapper, path, "rmdir_wrapper");
+               r = userns_exec_1(conf, rmdir_wrapper, &wrap, "rmdir_wrapper");
        else
                r = cgroup_rmdir(path);
 
@@ -1433,13 +1449,15 @@ struct chown_data {
  */
 static int chown_cgroup_wrapper(void *data)
 {
-       struct chown_data *arg = data;
-       uid_t destuid;
        int i;
+       uid_t destuid;
+       struct generic_userns_exec_data *arg = data;
+       uid_t nsuid = (arg->conf->root_nsuid_map != NULL) ? 0 : arg->conf->init_uid;
+       gid_t nsgid = (arg->conf->root_nsgid_map != NULL) ? 0 : arg->conf->init_gid;
 
-       if (setresgid(0,0,0) < 0)
+       if (setresgid(nsgid, nsgid, nsgid) < 0)
                SYSERROR("Failed to setgid to 0");
-       if (setresuid(0,0,0) < 0)
+       if (setresuid(nsuid, nsuid, nsuid) < 0)
                SYSERROR("Failed to setuid to 0");
        if (setgroups(0, NULL) < 0)
                SYSERROR("Failed to clear groups");
@@ -1449,7 +1467,7 @@ static int chown_cgroup_wrapper(void *data)
        for (i = 0; hierarchies[i]; i++) {
                char *fullpath, *path = hierarchies[i]->fullcgpath;
 
-               if (chown(path, destuid, 0) < 0) {
+               if (chown(path, destuid, nsgid) < 0) {
                        SYSERROR("Error chowning %s to %d", path, (int) destuid);
                        return -1;
                }
@@ -1467,7 +1485,7 @@ static int chown_cgroup_wrapper(void *data)
                 * insists on doing)
                 */
                fullpath = must_make_path(path, "tasks", NULL);
-               if (chown(fullpath, destuid, 0) < 0 && errno != ENOENT)
+               if (chown(fullpath, destuid, nsgid) < 0 && errno != ENOENT)
                        WARN("Failed chowning %s to %d: %s", fullpath, (int) destuid,
                             strerror(errno));
                if (chmod(fullpath, 0664) < 0)
@@ -1486,7 +1504,7 @@ static int chown_cgroup_wrapper(void *data)
                        continue;
 
                fullpath = must_make_path(path, "cgroup.subtree_control", NULL);
-               if (chown(fullpath, destuid, 0) < 0 && errno != ENOENT)
+               if (chown(fullpath, destuid, nsgid) < 0 && errno != ENOENT)
                        WARN("Failed chowning %s to %d: %s", fullpath, (int) destuid,
                             strerror(errno));
                if (chmod(fullpath, 0664) < 0)
@@ -1494,7 +1512,7 @@ static int chown_cgroup_wrapper(void *data)
                free(fullpath);
 
                fullpath = must_make_path(path, "cgroup.threads", NULL);
-               if (chown(fullpath, destuid, 0) < 0 && errno != ENOENT)
+               if (chown(fullpath, destuid, nsgid) < 0 && errno != ENOENT)
                        WARN("Failed chowning %s to %d: %s", fullpath, (int) destuid,
                             strerror(errno));
                if (chmod(fullpath, 0664) < 0)
@@ -1508,7 +1526,7 @@ static int chown_cgroup_wrapper(void *data)
 static bool cgfsng_chown(void *hdata, struct lxc_conf *conf)
 {
        struct cgfsng_handler_data *d = hdata;
-       struct chown_data wrap;
+       struct generic_userns_exec_data wrap;
 
        if (!d)
                return false;
@@ -1516,8 +1534,10 @@ static bool cgfsng_chown(void *hdata, struct lxc_conf *conf)
        if (lxc_list_empty(&conf->id_map))
                return true;
 
-       wrap.d = d;
        wrap.origuid = geteuid();
+       wrap.path = NULL;
+       wrap.d = d;
+       wrap.conf = conf;
 
        if (userns_exec_1(conf, chown_cgroup_wrapper, &wrap,
                          "chown_cgroup_wrapper") < 0) {
index e4411d9b98bc9de4c76904312d10476c9cea3ef4..834e789869854bb73a448318da9ca967c1d2dd54 100644 (file)
@@ -2576,20 +2576,27 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid)
  * Return true if id was found, false otherwise.
  */
 bool get_mapped_rootid(struct lxc_conf *conf, enum idtype idtype,
-                       unsigned long *val)
+                      unsigned long *val)
 {
        struct lxc_list *it;
        struct id_map *map;
+       unsigned nsid;
+
+       if (idtype == ID_TYPE_UID)
+               nsid = (conf->root_nsuid_map != NULL) ? 0 : conf->init_uid;
+       else
+               nsid = (conf->root_nsgid_map != NULL) ? 0 : conf->init_gid;
 
        lxc_list_for_each(it, &conf->id_map) {
                map = it->elem;
                if (map->idtype != idtype)
                        continue;
-               if (map->nsid != 0)
+               if (map->nsid != nsid)
                        continue;
                *val = map->hostid;
                return true;
        }
+
        return false;
 }
 
@@ -3591,6 +3598,8 @@ int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data,
        struct id_map *map;
        char c = '1';
        int ret = -1, status = -1;
+       uid_t nsuid = (conf->root_nsuid_map != NULL) ? 0 : conf->init_uid;
+       gid_t nsgid = (conf->root_nsgid_map != NULL) ? 0 : conf->init_gid;
        struct lxc_list *idmap = NULL, *tmplist = NULL;
        struct id_map *container_root_uid = NULL, *container_root_gid = NULL,
                      *host_uid_map = NULL, *host_gid_map = NULL;
@@ -3618,7 +3627,7 @@ int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data,
 
        /* Find container root mappings. */
        euid = geteuid();
-       container_root_uid = mapped_nsid_add(conf, 0, ID_TYPE_UID);
+       container_root_uid = mapped_nsid_add(conf, nsuid, ID_TYPE_UID);
        if (!container_root_uid) {
                DEBUG("Failed to find mapping for container root uid %d", 0);
                goto on_error;
@@ -3627,7 +3636,7 @@ int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data,
                host_uid_map = container_root_uid;
 
        egid = getegid();
-       container_root_gid = mapped_nsid_add(conf, 0, ID_TYPE_GID);
+       container_root_gid = mapped_nsid_add(conf, nsgid, ID_TYPE_GID);
        if (!container_root_gid) {
                DEBUG("Failed to find mapping for container root gid %d", 0);
                goto on_error;
index 77f06edc73e35ec39307faeb624e1de478c19f21..ccd45a2fa6f3ba0b17ae537f4236884800f34d68 100644 (file)
@@ -1877,7 +1877,7 @@ static int set_config_idmaps(const char *key, const char *value,
                        lxc_conf->root_nsuid_map = idmap;
 
 
-       if (!lxc_conf->root_nsuid_map && idmap->idtype == ID_TYPE_GID)
+       if (!lxc_conf->root_nsgid_map && idmap->idtype == ID_TYPE_GID)
                if (idmap->nsid == 0)
                        lxc_conf->root_nsgid_map = idmap;
 
index f362fa575189ab67846fa237292b859217deb8c2..2494c49c2e979322b58a0cb70e3ab443854db560 100644 (file)
@@ -1041,7 +1041,14 @@ static int do_start(void *data)
         * privilege over our namespace.
         */
        if (!lxc_list_empty(&handler->conf->id_map)) {
-               ret = lxc_switch_uid_gid(0, 0);
+               uid_t nsuid = (handler->conf->root_nsuid_map != NULL)
+                                 ? 0
+                                 : handler->conf->init_uid;
+               gid_t nsgid = (handler->conf->root_nsgid_map != NULL)
+                                 ? 0
+                                 : handler->conf->init_gid;
+
+               ret = lxc_switch_uid_gid(nsuid, nsgid);
                if (ret < 0)
                        goto out_warn_father;