confile: handle appending init groups

parent 4822319f
...@@ -2671,6 +2671,7 @@ struct lxc_conf *lxc_conf_init(void) ...@@ -2671,6 +2671,7 @@ struct lxc_conf *lxc_conf_init(void)
* default to running as UID/GID 0 when using lxc-execute */ * default to running as UID/GID 0 when using lxc-execute */
new->init_uid = 0; new->init_uid = 0;
new->init_gid = 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->cgroup_meta, 0, sizeof(struct lxc_cgroup));
memset(&new->ns_share, 0, sizeof(char *) * LXC_NS_MAX); memset(&new->ns_share, 0, sizeof(char *) * LXC_NS_MAX);
memset(&new->timens, 0, sizeof(struct timens_offsets)); memset(&new->timens, 0, sizeof(struct timens_offsets));
......
...@@ -1184,9 +1184,9 @@ static int set_config_init_groups(const char *key, const char *value, ...@@ -1184,9 +1184,9 @@ static int set_config_init_groups(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data) struct lxc_conf *lxc_conf, void *data)
{ {
__do_free char *value_dup = NULL; __do_free char *value_dup = NULL;
__do_free gid_t *init_groups = NULL; gid_t *init_groups = NULL;
int num_groups = 0; size_t num_groups = 0;
int iter = 0; size_t idx;
char *token; char *token;
if (lxc_config_value_empty(value)) if (lxc_config_value_empty(value))
...@@ -1199,13 +1199,24 @@ static int set_config_init_groups(const char *key, const char *value, ...@@ -1199,13 +1199,24 @@ static int set_config_init_groups(const char *key, const char *value,
lxc_iterate_parts(token, value_dup, ",") lxc_iterate_parts(token, value_dup, ",")
num_groups++; num_groups++;
if (num_groups == INT_MAX)
return log_error_errno(-ERANGE, ERANGE, "Excessive number of supplementary groups specified");
if (num_groups == 0) if (num_groups == 0)
return clr_config_init_groups(key, lxc_conf, NULL); 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) if (!init_groups)
return ret_errno(ENOMEM); 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. */ /* Restore duplicated value so we can call lxc_iterate_parts() again. */
strcpy(value_dup, value); strcpy(value_dup, value);
...@@ -1218,11 +1229,10 @@ static int set_config_init_groups(const char *key, const char *value, ...@@ -1218,11 +1229,10 @@ static int set_config_init_groups(const char *key, const char *value,
if (ret) if (ret)
return ret; return ret;
init_groups[iter++] = group; init_groups[idx++] = group;
} }
lxc_conf->init_groups.size = num_groups; lxc_conf->init_groups.size += num_groups;
lxc_conf->init_groups.list = move_ptr(init_groups);
return 0; return 0;
} }
...@@ -5036,8 +5046,8 @@ static inline int clr_config_init_gid(const char *key, struct lxc_conf *c, ...@@ -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, static inline int clr_config_init_groups(const char *key, struct lxc_conf *c,
void *data) void *data)
{ {
free_disarm(c->init_groups.list);
c->init_groups.size = 0; c->init_groups.size = 0;
free_disarm(c->init_groups.list);
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment