From: Christian Brauner Date: Mon, 14 Jun 2021 10:10:46 +0000 (+0200) Subject: confile: backport lxc.init.groups config key X-Git-Tag: lxc-4.0.10~41 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F3866%2Fhead;p=thirdparty%2Flxc.git confile: backport lxc.init.groups config key This is needed for lxcri. Fixes: #3862 Signed-off-by: Christian Brauner --- diff --git a/src/lxc/confile.c b/src/lxc/confile.c index 76d940262..8072d658a 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -86,6 +86,7 @@ lxc_config_define(init_cmd); lxc_config_define(init_cwd); lxc_config_define(init_gid); lxc_config_define(init_uid); +lxc_config_define(init_groups); lxc_config_define(jump_table_net); lxc_config_define(keyring_session); lxc_config_define(log_file); @@ -213,6 +214,7 @@ static struct lxc_config_t config_jump_table[] = { { "lxc.include", true, set_config_includefiles, get_config_includefiles, clr_config_includefiles, }, { "lxc.init.cmd", true, set_config_init_cmd, get_config_init_cmd, clr_config_init_cmd, }, { "lxc.init.gid", true, set_config_init_gid, get_config_init_gid, clr_config_init_gid, }, + { "lxc.init.groups", true, set_config_init_groups, get_config_init_groups, clr_config_init_groups, }, { "lxc.init.uid", true, set_config_init_uid, get_config_init_uid, clr_config_init_uid, }, { "lxc.init.cwd", true, set_config_init_cwd, get_config_init_cwd, clr_config_init_cwd, }, { "lxc.keyring.session", true, set_config_keyring_session, get_config_keyring_session, clr_config_keyring_session }, @@ -1177,6 +1179,64 @@ static int set_config_init_gid(const char *key, const char *value, return 0; } +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; + gid_t *init_groups = NULL; + size_t num_groups = 0; + size_t idx; + char *token; + + if (lxc_config_value_empty(value)) + return clr_config_init_groups(key, lxc_conf, NULL); + + value_dup = strdup(value); + if (!value_dup) + return -ENOMEM; + + 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"); + + /* This means the string wasn't empty and all we found was garbage. */ + if (num_groups == 0) + return log_error_errno(-EINVAL, EINVAL, "No valid groups specified %s", value); + + 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); + + lxc_iterate_parts(token, value_dup, ",") { + int ret; + + gid_t group; + + ret = lxc_safe_uint(token, &group); + if (ret) + return log_error_errno(ret, -ret, "Failed to parse group %s", token); + + init_groups[idx++] = group; + } + + lxc_conf->init_groups.size += num_groups; + + return 0; +} + static int set_config_hooks(const char *key, const char *value, struct lxc_conf *lxc_conf, void *data) { @@ -4174,6 +4234,26 @@ static int get_config_init_gid(const char *key, char *retv, int inlen, return lxc_get_conf_int(c, retv, inlen, c->init_gid); } +static int get_config_init_groups(const char *key, char *retv, int inlen, + struct lxc_conf *c, void *data) +{ + int fulllen = 0, len; + + if (!retv) + inlen = 0; + else + memset(retv, 0, inlen); + + if (c->init_groups.size == 0) + return 0; + + for (int i = 0; i < c->init_groups.size; i++) + strprint(retv, inlen, "%s%d", (i > 0) ? "," : "", + c->init_groups.list[i]); + + return fulllen; +} + static int get_config_ephemeral(const char *key, char *retv, int inlen, struct lxc_conf *c, void *data) { @@ -4821,6 +4901,14 @@ static inline int clr_config_init_gid(const char *key, struct lxc_conf *c, return 0; } +static inline int clr_config_init_groups(const char *key, struct lxc_conf *c, + void *data) +{ + c->init_groups.size = 0; + free_disarm(c->init_groups.list); + return 0; +} + static inline int clr_config_ephemeral(const char *key, struct lxc_conf *c, void *data) {