]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
confile: handle appending init groups
authorChristian Brauner <christian.brauner@ubuntu.com>
Fri, 5 Feb 2021 10:06:24 +0000 (11:06 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Fri, 5 Feb 2021 11:14:07 +0000 (12:14 +0100)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/conf.c
src/lxc/confile.c

index a3cc3f697a864addb2ef984859e9649fd9063c53..8aa37aa05886b90d30051691e55a5313e2b9b910 100644 (file)
@@ -2671,6 +2671,7 @@ struct lxc_conf *lxc_conf_init(void)
         * default to running as UID/GID 0 when using lxc-execute */
        new->init_uid = 0;
        new->init_gid = 0;
+       memset(&new->init_groups, 0, sizeof(lxc_groups_t));
        memset(&new->cgroup_meta, 0, sizeof(struct lxc_cgroup));
        memset(&new->ns_share, 0, sizeof(char *) * LXC_NS_MAX);
        memset(&new->timens, 0, sizeof(struct timens_offsets));
index d7905b37fac4afc63823a088c205892e1bb7b1fd..f7ae28b03a40490173436ea05130f556b6147d35 100644 (file)
@@ -1184,9 +1184,9 @@ static int set_config_init_groups(const char *key, const char *value,
                                  struct lxc_conf *lxc_conf, void *data)
 {
        __do_free char *value_dup = NULL;
-       __do_free gid_t *init_groups = NULL;
-       int num_groups = 0;
-       int iter = 0;
+       gid_t *init_groups = NULL;
+       size_t num_groups = 0;
+       size_t idx;
        char *token;
 
        if (lxc_config_value_empty(value))
@@ -1199,13 +1199,24 @@ static int set_config_init_groups(const char *key, const char *value,
        lxc_iterate_parts(token, value_dup, ",")
                num_groups++;
 
+       if (num_groups == INT_MAX)
+               return log_error_errno(-ERANGE, ERANGE, "Excessive number of supplementary groups specified");
+
        if (num_groups == 0)
                return clr_config_init_groups(key, lxc_conf, NULL);
 
-       init_groups = zalloc(sizeof(gid_t) * num_groups);
+       idx = lxc_conf->init_groups.size;
+       init_groups = realloc(lxc_conf->init_groups.list, sizeof(gid_t) * (idx + num_groups));
        if (!init_groups)
                return ret_errno(ENOMEM);
 
+       /*
+        * Once the realloc() succeeded we need to hand control of the memory
+        * back to the config otherwise we risk a double-free when
+        * lxc_conf_free() is called.
+        */
+       lxc_conf->init_groups.list = init_groups;
+
        /* Restore duplicated value so we can call lxc_iterate_parts() again. */
        strcpy(value_dup, value);
 
@@ -1218,11 +1229,10 @@ static int set_config_init_groups(const char *key, const char *value,
                if (ret)
                        return ret;
 
-               init_groups[iter++] = group;
+               init_groups[idx++] = group;
        }
 
-       lxc_conf->init_groups.size = num_groups;
-       lxc_conf->init_groups.list = move_ptr(init_groups);
+       lxc_conf->init_groups.size += num_groups;
 
        return 0;
 }
@@ -5036,8 +5046,8 @@ static inline int clr_config_init_gid(const char *key, struct lxc_conf *c,
 static inline int clr_config_init_groups(const char *key, struct lxc_conf *c,
                                         void *data)
 {
-       free_disarm(c->init_groups.list);
        c->init_groups.size = 0;
+       free_disarm(c->init_groups.list);
        return 0;
 }