[lxc-devel] [lxc/master] Implementation of additional group IDs for init and attach process
Drachenfels-GmbH on Github
lxc-bot at linuxcontainers.org
Thu Nov 5 10:22:13 UTC 2020
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 585 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20201105/23694d93/attachment.bin>
-------------- next part --------------
From a8213d477aa91fd770141c0acdd1e78e3fe82498 Mon Sep 17 00:00:00 2001
From: Ruben Jenster <r.jenster at drachenfels.de>
Date: Fri, 30 Oct 2020 10:00:07 +0100
Subject: [PATCH 1/2] Introduce lxc.init.groups to keep additional group ID's.
Signed-off-by: Ruben Jenster <r.jenster at drachenfels.de>
---
src/lxc/conf.c | 1 +
src/lxc/conf.h | 4 +++
src/lxc/confile.c | 79 ++++++++++++++++++++++++++++++++++++++++++++
src/lxc/start.c | 12 +++++--
src/lxc/utils.c | 7 +++-
src/tests/get_item.c | 28 ++++++++++++++++
6 files changed, 128 insertions(+), 3 deletions(-)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index c258d0b4c5..ceffb8f6c9 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -3820,6 +3820,7 @@ void lxc_conf_free(struct lxc_conf *conf)
free(conf->rcfile);
free(conf->execute_cmd);
free(conf->init_cmd);
+ free(conf->init_groups.list);
free(conf->init_cwd);
free(conf->unexpanded_config);
free(conf->syslog);
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 907cbdfa52..90d77e6eff 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -373,6 +373,10 @@ struct lxc_conf {
* should run under when using lxc-execute */
uid_t init_uid;
gid_t init_gid;
+ struct {
+ int size;
+ gid_t *list;
+ } init_groups;
/* indicator if the container will be destroyed on shutdown */
unsigned int ephemeral;
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 4f7621a900..103163280c 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -94,6 +94,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(keyring_session);
lxc_config_define(log_file);
lxc_config_define(log_level);
@@ -211,6 +212,7 @@ static struct lxc_config_t config_jump_table[] = {
{ "lxc.include", set_config_includefiles, get_config_includefiles, clr_config_includefiles, },
{ "lxc.init.cmd", set_config_init_cmd, get_config_init_cmd, clr_config_init_cmd, },
{ "lxc.init.gid", set_config_init_gid, get_config_init_gid, clr_config_init_gid, },
+ { "lxc.init.groups", set_config_init_groups, get_config_init_groups, clr_config_init_groups, },
{ "lxc.init.uid", set_config_init_uid, get_config_init_uid, clr_config_init_uid, },
{ "lxc.init.cwd", set_config_init_cwd, get_config_init_cwd, clr_config_init_cwd, },
{ "lxc.keyring.session", set_config_keyring_session, get_config_keyring_session, clr_config_keyring_session },
@@ -1217,6 +1219,53 @@ 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)
+{
+ char *value_dup, *token;
+ int num_groups = 0;
+ gid_t *init_groups;
+ int iter = 0;
+
+ if (lxc_config_value_empty(value))
+ return clr_config_init_groups(key, lxc_conf, NULL);
+
+ value_dup = strdup(value);
+ if (!value_dup)
+ return -1;
+
+ lxc_iterate_parts(token, value_dup, " \t") num_groups++;
+
+ if (num_groups == 0) {
+ free(value_dup);
+ return clr_config_init_groups(key, lxc_conf, NULL);
+ }
+
+ init_groups = malloc(sizeof(gid_t) * num_groups);
+ if (!init_groups) {
+ free(value_dup);
+ return -1;
+ }
+
+ strcpy(value_dup, value);
+ lxc_iterate_parts(token, value_dup, " \t")
+ {
+ gid_t group;
+ if (lxc_safe_uint(token, &group) < 0) {
+ free(value_dup);
+ free(init_groups);
+ return -1;
+ }
+ init_groups[iter++] = group;
+ }
+
+ lxc_conf->init_groups.size = num_groups;
+ lxc_conf->init_groups.list = init_groups;
+
+ free(value_dup);
+ return 0;
+}
+
static int set_config_hooks(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
@@ -4441,6 +4490,27 @@ 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)
{
@@ -5147,6 +5217,15 @@ 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)
+{
+ free(c->init_groups.list);
+ c->init_groups.list = NULL;
+ c->init_groups.size = 0;
+ return 0;
+}
+
static inline int clr_config_ephemeral(const char *key, struct lxc_conf *c,
void *data)
{
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 7bf7f8a2fb..c650367885 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -1414,8 +1414,16 @@ static int do_start(void *data)
#if HAVE_LIBCAP
if (lxc_proc_cap_is_set(CAP_SETGID, CAP_EFFECTIVE))
#endif
- if (!lxc_setgroups(0, NULL))
- goto out_warn_father;
+ {
+ if (handler->conf->init_groups.size > 0) {
+ if (!lxc_setgroups(handler->conf->init_groups.size,
+ handler->conf->init_groups.list))
+ goto out_warn_father;
+ } else {
+ if (!lxc_setgroups(0, NULL))
+ goto out_warn_father;
+ }
+ }
if (!lxc_switch_uid_gid(new_uid, new_gid))
goto out_warn_father;
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index baf80b7f5c..75ad3137d6 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -1412,7 +1412,12 @@ bool lxc_setgroups(int size, gid_t list[])
SYSERROR("Failed to setgroups()");
return false;
}
- NOTICE("Dropped additional groups");
+ if (size == 0)
+ NOTICE("Dropped additional groups");
+ else {
+ for(int i = 0; i < size; i++)
+ NOTICE("Kept additional group with GID %d", list[i]);
+ }
return true;
}
diff --git a/src/tests/get_item.c b/src/tests/get_item.c
index 11db5f6738..5ceea9ec49 100644
--- a/src/tests/get_item.c
+++ b/src/tests/get_item.c
@@ -136,6 +136,34 @@ int main(int argc, char *argv[])
}
printf("lxc.init_gid returned %d %s\n", ret, v2);
+ if (!c->set_config_item(c, "lxc.init.groups", "")) {
+ fprintf(stderr, "%d: failed to set init_groups\n", __LINE__);
+ goto out;
+ }
+
+ if (!c->set_config_item(c, "lxc.init.groups", "10 20 foo 40")) {
+ printf("%d: failed to set init_groups\n", __LINE__);
+ } else {
+ goto out;
+ }
+
+ if (!c->set_config_item(c, "lxc.init.groups", "10 20 30 40")) {
+ fprintf(stderr, "%d: failed to set init_groups\n", __LINE__);
+ goto out;
+ }
+
+ ret = c->get_config_item(c, "lxc.init.groups", v2, 255);
+ if (ret < 0) {
+ fprintf(stderr, "%d: get_config_item(lxc.init_gid) returned %d\n",
+ __LINE__, ret);
+ goto out;
+ }
+ ret = strcmp("10 20 30 40", v2);
+ printf("lxc.init_groups returned %d %s\n", ret, v2);
+ if (ret != 0) {
+ goto out;
+ }
+
#define HNAME "hostname1"
// demonstrate proper usage:
char *alloced;
From 29de94987e8908210caa450afdd49d671f708e75 Mon Sep 17 00:00:00 2001
From: Ruben Jenster <r.jenster at drachenfels.de>
Date: Thu, 5 Nov 2020 10:56:19 +0100
Subject: [PATCH 2/2] attach: Add groups option to keep additional group IDs.
Signed-off-by: Ruben Jenster <r.jenster at drachenfels.de>
---
src/lxc/attach.c | 13 +++++++------
src/lxc/attach_options.h | 12 ++++++++++++
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/src/lxc/attach.c b/src/lxc/attach.c
index acbffa238d..477308c047 100644
--- a/src/lxc/attach.c
+++ b/src/lxc/attach.c
@@ -552,10 +552,6 @@ static void lxc_attach_get_init_uidgid(uid_t *init_uid, gid_t *init_gid)
if (gid != LXC_INVALID_GID)
*init_gid = gid;
-
- /* TODO: we should also parse supplementary groups and use
- * setgroups() to set them.
- */
}
static bool fetch_seccomp(struct lxc_container *c, lxc_attach_options_t *options)
@@ -740,8 +736,13 @@ static int attach_child_main(struct attach_clone_payload *payload)
goto on_error;
}
- if (!lxc_setgroups(0, NULL) && errno != EPERM)
- goto on_error;
+ if (options->groups.size > 0) {
+ if (!lxc_setgroups(options->groups.size, options->groups.list))
+ goto on_error;
+ } else {
+ if (!lxc_setgroups(0, NULL) && errno != EPERM)
+ goto on_error;
+ }
if (options->namespaces & CLONE_NEWUSER) {
/* Check whether nsuid 0 has a mapping. */
diff --git a/src/lxc/attach_options.h b/src/lxc/attach_options.h
index 80fe439103..c07c13cd85 100644
--- a/src/lxc/attach_options.h
+++ b/src/lxc/attach_options.h
@@ -52,6 +52,11 @@ enum {
*/
typedef int (*lxc_attach_exec_t)(void* payload);
+typedef struct lxc_groups_t {
+ int size;
+ gid_t *list;
+} lxc_groups_t;
+
/*!
* LXC attach options for \ref lxc_container \c attach().
*/
@@ -88,6 +93,12 @@ typedef struct lxc_attach_options_t {
*/
gid_t gid;
+ /*! The additional group GIDs to run with.
+ *
+ * If unset all additional groups are dropped.
+ */
+ lxc_groups_t groups;
+
/*! Environment policy */
lxc_attach_env_policy_t env_policy;
@@ -128,6 +139,7 @@ typedef struct lxc_attach_options_t {
/* .initial_cwd = */ NULL, \
/* .uid = */ (uid_t)-1, \
/* .gid = */ (gid_t)-1, \
+ /* .groups = */ { 0, NULL}, \
/* .env_policy = */ LXC_ATTACH_KEEP_ENV, \
/* .extra_env_vars = */ NULL, \
/* .extra_keep_env = */ NULL, \
More information about the lxc-devel
mailing list