]> git.proxmox.com Git - mirror_lxc.git/commitdiff
confile: add lxc.init.groups to keep additional groups
authorRuben Jenster <r.jenster@drachenfels.de>
Fri, 30 Oct 2020 09:00:07 +0000 (10:00 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Fri, 5 Feb 2021 11:13:06 +0000 (12:13 +0100)
Signed-off-by: Ruben Jenster <r.jenster@drachenfels.de>
src/lxc/conf.c
src/lxc/conf.h
src/lxc/confile.c
src/lxc/start.c
src/tests/get_item.c

index 4d258ada71b7850281300e21086f848cbfb9b030..a3cc3f697a864addb2ef984859e9649fd9063c53 100644 (file)
@@ -3919,6 +3919,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);
index 2c6dfd9f2ecb2a8ba6cd30ce4d71fbcc2578891f..4d13e90dcb84756414a0488a32f86dfdae9fd9d9 100644 (file)
@@ -417,6 +417,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;
index 4c93542f98b58715030a160da9908fd6865f8fff..d7905b37fac4afc63823a088c205892e1bb7b1fd 100644 (file)
@@ -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             },
@@ -1178,6 +1180,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)
+{
+       __do_free char *value_dup = NULL;
+       __do_free gid_t *init_groups = NULL;
+       int num_groups = 0;
+       int iter = 0;
+       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 == 0)
+               return clr_config_init_groups(key, lxc_conf, NULL);
+
+       init_groups = zalloc(sizeof(gid_t) * num_groups);
+       if (!init_groups)
+               return ret_errno(ENOMEM);
+
+       /* 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 ret;
+
+               init_groups[iter++] = group;
+       }
+
+       lxc_conf->init_groups.size = num_groups;
+       lxc_conf->init_groups.list = move_ptr(init_groups);
+
+       return 0;
+}
+
 static int set_config_hooks(const char *key, const char *value,
                            struct lxc_conf *lxc_conf, void *data)
 {
@@ -4278,6 +4327,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)
 {
@@ -4964,6 +5033,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)
+{
+       free_disarm(c->init_groups.list);
+       c->init_groups.size = 0;
+       return 0;
+}
+
 static inline int clr_config_ephemeral(const char *key, struct lxc_conf *c,
                                       void *data)
 {
index 0a9edc303afe3fc0914afc76f62cab24a97898ba..019014c0c0559963e64a1fec22e687214f825a09 100644 (file)
@@ -1406,12 +1406,21 @@ static int do_start(void *data)
         * we switched to root in the new user namespace further above. Only
         * drop groups if we can, so ensure that we have necessary privilege.
         */
-       if (lxc_list_empty(&handler->conf->id_map))
+       if (lxc_list_empty(&handler->conf->id_map)) {
                #if HAVE_LIBCAP
                if (lxc_proc_cap_is_set(CAP_SETGID, CAP_EFFECTIVE))
                #endif
-                       if (!lxc_drop_groups())
-                               goto out_warn_father;
+               {
+                       if (handler->conf->init_groups.size > 0) {
+                               if (!lxc_setgroups(handler->conf->init_groups.list,
+                                                  handler->conf->init_groups.size))
+                                       goto out_warn_father;
+                       } else {
+                               if (!lxc_drop_groups())
+                                       goto out_warn_father;
+                       }
+               }
+       }
 
        if (!lxc_switch_uid_gid(new_uid, new_gid))
                goto out_warn_father;
index 11db5f6738fb294bbf14fb7005467aa26eb4015f..c503ddb994e7e250fb6ab9f449611ade0a5890af 100644 (file)
@@ -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("failed to set init_groups to '10,20,foo,40' as expected\n");
+       } 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;