From e06155c9abc930daf5983f890057ad709fe958fb Mon Sep 17 00:00:00 2001 From: Patrick Toomey Date: Thu, 9 Jul 2015 16:58:17 -0600 Subject: [PATCH 1/8] Do not switch to root for lxc-execute Signed-off-by: Patrick Toomey --- src/lxc/start.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lxc/start.c b/src/lxc/start.c index 6eded6155..ce65e8243 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -664,9 +664,10 @@ static int do_start(void *data) /* * if we are in a new user namespace, become root there to have - * privilege over our namespace + * privilege over our namespace. We don't become root for lxc-execute, as + * the intent is to execute a command as the original user. */ - if (!lxc_list_empty(&handler->conf->id_map)) { + if (!handler->conf->is_execute && !lxc_list_empty(&handler->conf->id_map)) { NOTICE("switching to gid/uid 0 in new user namespace"); if (setgid(0)) { SYSERROR("setgid"); From 56f8ff00e35b8729e66de46d3bdc5afa6a726f28 Mon Sep 17 00:00:00 2001 From: Patrick Toomey Date: Mon, 20 Jul 2015 12:37:20 -0600 Subject: [PATCH 2/8] Set UID/GID to parent value for lxc-execute Signed-off-by: Patrick Toomey --- src/lxc/conf.c | 3 +++ src/lxc/conf.h | 4 ++++ src/lxc/start.c | 10 ++++++---- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 9870455b3..429217401 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -2604,6 +2604,9 @@ struct lxc_conf *lxc_conf_init(void) for (i = 0; i < LXC_NS_MAX; i++) new->inherit_ns_fd[i] = -1; + new->parent_uid = getuid(); + new->parent_gid = getgid(); + return new; } diff --git a/src/lxc/conf.h b/src/lxc/conf.h index 2d67f0da6..47d4407e7 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -365,6 +365,10 @@ struct lxc_conf { /* init command */ char *init_cmd; + + /* The UID/GID of the process creating the container */ + uid_t parent_uid; + gid_t parent_gid; }; #ifdef HAVE_TLS diff --git a/src/lxc/start.c b/src/lxc/start.c index ce65e8243..eb6b94df8 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -667,13 +667,15 @@ static int do_start(void *data) * privilege over our namespace. We don't become root for lxc-execute, as * the intent is to execute a command as the original user. */ - if (!handler->conf->is_execute && !lxc_list_empty(&handler->conf->id_map)) { - NOTICE("switching to gid/uid 0 in new user namespace"); - if (setgid(0)) { + if (!lxc_list_empty(&handler->conf->id_map)) { + gid_t new_gid = handler->conf->is_execute ? handler->conf->parent_gid : 0; + gid_t new_uid = handler->conf->is_execute ? handler->conf->parent_uid : 0; + NOTICE("switching to gid/uid %d/%d in new user namespace", new_gid, new_uid); + if (setgid(new_gid)) { SYSERROR("setgid"); goto out_warn_father; } - if (setuid(0)) { + if (setuid(new_uid)) { SYSERROR("setuid"); goto out_warn_father; } From c5cd20ce8e2d36ff26da4deb22f0bc29484da74a Mon Sep 17 00:00:00 2001 From: Patrick Toomey Date: Tue, 18 Aug 2015 16:26:28 -0600 Subject: [PATCH 3/8] Pass UID/GID explicitly through flags Signed-off-by: Patrick Toomey --- src/lxc/arguments.h | 4 ++++ src/lxc/conf.c | 3 --- src/lxc/conf.h | 6 +++--- src/lxc/lxc_execute.c | 16 ++++++++++++++-- src/lxc/start.c | 10 ++++++++-- 5 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/lxc/arguments.h b/src/lxc/arguments.h index cc85f863f..0f2049b8c 100644 --- a/src/lxc/arguments.h +++ b/src/lxc/arguments.h @@ -88,6 +88,10 @@ struct lxc_arguments { char *lvname, *vgname, *thinpool; char *zfsroot, *lowerdir, *dir; + /* lxc-execute */ + uid_t uid; + gid_t gid; + /* auto-start */ int all; int ignore_auto; diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 429217401..9870455b3 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -2604,9 +2604,6 @@ struct lxc_conf *lxc_conf_init(void) for (i = 0; i < LXC_NS_MAX; i++) new->inherit_ns_fd[i] = -1; - new->parent_uid = getuid(); - new->parent_gid = getgid(); - return new; } diff --git a/src/lxc/conf.h b/src/lxc/conf.h index 47d4407e7..0087586e4 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -366,9 +366,9 @@ struct lxc_conf { /* init command */ char *init_cmd; - /* The UID/GID of the process creating the container */ - uid_t parent_uid; - gid_t parent_gid; + /* the UID/GID that COMMAND for lxc-execute should run under */ + uid_t init_uid; + gid_t init_gid; }; #ifdef HAVE_TLS diff --git a/src/lxc/lxc_execute.c b/src/lxc/lxc_execute.c index 4f1e1f674..4f42236e3 100644 --- a/src/lxc/lxc_execute.c +++ b/src/lxc/lxc_execute.c @@ -59,7 +59,9 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg) { switch (c) { case 'f': args->rcfile = arg; break; - case 's': return lxc_config_define_add(&defines, arg); + case 's': return lxc_config_define_add(&defines, arg); break; + case 'u': args->uid = atoi(arg); break; + case 'g': args->gid = atoi(arg); } return 0; } @@ -67,6 +69,8 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg) static const struct option my_longopts[] = { {"rcfile", required_argument, 0, 'f'}, {"define", required_argument, 0, 's'}, + {"uid", required_argument, 0, 'u'}, + {"gid", required_argument, 0, 'g'}, LXC_COMMON_OPTIONS }; @@ -81,7 +85,9 @@ and execs COMMAND into this container.\n\ Options :\n\ -n, --name=NAME NAME for name of the container\n\ -f, --rcfile=FILE Load configuration file FILE\n\ - -s, --define KEY=VAL Assign VAL to configuration variable KEY\n", + -s, --define KEY=VAL Assign VAL to configuration variable KEY\n\ + -u, --uid=UID Execute COMMAND with UID inside the container\n\ + -g, --gid=GID Execute COMMAND with GID inside the container\n", .options = my_longopts, .parser = my_parser, .checker = my_checker, @@ -139,6 +145,12 @@ int main(int argc, char *argv[]) if (lxc_config_define_load(&defines, conf)) return 1; + if (my_args.uid) + conf->init_uid = my_args.uid; + + if (my_args.gid) + conf->init_gid = my_args.gid; + ret = lxc_execute(my_args.name, my_args.argv, my_args.quiet, conf, my_args.lxcpath[0], false); lxc_conf_free(conf); diff --git a/src/lxc/start.c b/src/lxc/start.c index eb6b94df8..845621706 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -668,8 +668,14 @@ static int do_start(void *data) * the intent is to execute a command as the original user. */ if (!lxc_list_empty(&handler->conf->id_map)) { - gid_t new_gid = handler->conf->is_execute ? handler->conf->parent_gid : 0; - gid_t new_uid = handler->conf->is_execute ? handler->conf->parent_uid : 0; + gid_t new_gid = 0; + if (handler->conf->is_execute && handler->conf->init_gid) + new_gid = handler->conf->init_gid; + + uid_t new_uid = 0; + if (handler->conf->is_execute && handler->conf->init_uid) + new_uid = handler->conf->init_uid; + NOTICE("switching to gid/uid %d/%d in new user namespace", new_gid, new_uid); if (setgid(new_gid)) { SYSERROR("setgid"); From fd9f399baceee40c44b6038fc3046ef374ade33a Mon Sep 17 00:00:00 2001 From: Patrick Toomey Date: Wed, 19 Aug 2015 09:57:59 -0600 Subject: [PATCH 4/8] Clarify struct field comment Signed-off-by: Patrick Toomey --- src/lxc/conf.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lxc/conf.h b/src/lxc/conf.h index 0087586e4..b9f93f954 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -366,7 +366,8 @@ struct lxc_conf { /* init command */ char *init_cmd; - /* the UID/GID that COMMAND for lxc-execute should run under */ + /* if running in a new user namespace, the UID/GID that COMMAND for + * lxc-execute should run under */ uid_t init_uid; gid_t init_gid; }; From 72bb04e4b879de066cef0445bfb7d79ac922d43e Mon Sep 17 00:00:00 2001 From: Patrick Toomey Date: Wed, 19 Aug 2015 11:04:38 -0600 Subject: [PATCH 5/8] Add support for setting lxc-execute init UID/GID via configuration file Signed-off-by: Patrick Toomey --- src/lxc/conf.c | 5 +++++ src/lxc/conf.h | 4 ++-- src/lxc/confile.c | 20 +++++++++++++++++++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 9870455b3..07aecb758 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -2604,6 +2604,11 @@ struct lxc_conf *lxc_conf_init(void) for (i = 0; i < LXC_NS_MAX; i++) new->inherit_ns_fd[i] = -1; + /* if running in a new user namespace, init and COMMAND + * default to running as UID/GID 0 when using lxc-execute */ + new->init_uid = 0; + new->init_gid = 0; + return new; } diff --git a/src/lxc/conf.h b/src/lxc/conf.h index b9f93f954..dc5328a3f 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -366,8 +366,8 @@ struct lxc_conf { /* init command */ char *init_cmd; - /* if running in a new user namespace, the UID/GID that COMMAND for - * lxc-execute should run under */ + /* if running in a new user namespace, the UID/GID that init and COMMAND + * should run under when using lxc-execute */ uid_t init_uid; gid_t init_gid; }; diff --git a/src/lxc/confile.c b/src/lxc/confile.c index b045689d5..bb39ee05e 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -104,6 +104,8 @@ static int config_start(const char *, const char *, struct lxc_conf *); static int config_group(const char *, const char *, struct lxc_conf *); static int config_environment(const char *, const char *, struct lxc_conf *); static int config_init_cmd(const char *, const char *, struct lxc_conf *); +static int config_init_uid(const char *, const char *, struct lxc_conf *); +static int config_init_gid(const char *, const char *, struct lxc_conf *); static struct lxc_config_t config[] = { @@ -168,6 +170,8 @@ static struct lxc_config_t config[] = { { "lxc.group", config_group }, { "lxc.environment", config_environment }, { "lxc.init_cmd", config_init_cmd }, + { "lxc.init_uid", config_init_uid }, + { "lxc.init_gid", config_init_gid }, }; struct signame { @@ -1034,11 +1038,25 @@ static int config_init_cmd(const char *key, const char *value, return config_path_item(&lxc_conf->init_cmd, value); } +static int config_init_uid(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + lxc_conf->init_uid = atoi(value); + return 0; +} + +static int config_init_gid(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + lxc_conf->init_gid = atoi(value); + return 0; +} + static int config_hook(const char *key, const char *value, struct lxc_conf *lxc_conf) { char *copy; - + if (!value || strlen(value) == 0) return lxc_clear_hooks(lxc_conf, key); From dbca9237db78eb462efcd17776cd2e44f84b4dd2 Mon Sep 17 00:00:00 2001 From: Patrick Toomey Date: Wed, 19 Aug 2015 11:05:12 -0600 Subject: [PATCH 6/8] Update english docs for new lxc.init_uid and lxc.init_gid options Signed-off-by: Patrick Toomey --- doc/lxc.container.conf.sgml.in | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in index 03ce89ab8..d1ac83484 100644 --- a/doc/lxc.container.conf.sgml.in +++ b/doc/lxc.container.conf.sgml.in @@ -246,6 +246,39 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Init ID + + Sets the UID/GID to use for the init system, and subsequent command, executed by lxc-execute. + + These options are only used when lxc-execute is started in a private user namespace. + + Defaults to: UID(0), GID(0) + + + + + + + + + UID to use within a private user namesapce for init. + + + + + + + + + + GID to use within a private user namesapce for init. + + + + + + Network From 62d0053955d433f7823d6cd7ea5cd30a74f6fd20 Mon Sep 17 00:00:00 2001 From: Patrick Toomey Date: Wed, 19 Aug 2015 11:19:11 -0600 Subject: [PATCH 7/8] Update docs to reflect lxc.init_uid and lxc.init_gid options Signed-off-by: Patrick Toomey --- src/lxc/start.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lxc/start.c b/src/lxc/start.c index 845621706..99bf8f497 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -664,8 +664,9 @@ static int do_start(void *data) /* * if we are in a new user namespace, become root there to have - * privilege over our namespace. We don't become root for lxc-execute, as - * the intent is to execute a command as the original user. + * privilege over our namespace. When using lxc-execute we default to root, + * but this can be overriden using the lxc.init_uid and lxc.init_gid + * configuration options. */ if (!lxc_list_empty(&handler->conf->id_map)) { gid_t new_gid = 0; From 68d18db8d854ff395052684fa0245f4b3fdac9ae Mon Sep 17 00:00:00 2001 From: Patrick Toomey Date: Thu, 27 Aug 2015 16:21:35 -0600 Subject: [PATCH 8/8] Add support for get_config_item and set_config_item Signed-off-by: Patrick Toomey --- src/lxc/confile.c | 4 ++++ src/tests/get_item.c | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/lxc/confile.c b/src/lxc/confile.c index bb39ee05e..105224158 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -2510,6 +2510,10 @@ int lxc_get_config_item(struct lxc_conf *c, const char *key, char *retv, return lxc_get_item_environment(c, retv, inlen); else if (strcmp(key, "lxc.init_cmd") == 0) v = c->init_cmd; + else if (strcmp(key, "lxc.init_uid") == 0) + return lxc_get_conf_int(c, retv, inlen, c->init_uid); + else if (strcmp(key, "lxc.init_gid") == 0) + return lxc_get_conf_int(c, retv, inlen, c->init_gid); else return -1; if (!v) diff --git a/src/tests/get_item.c b/src/tests/get_item.c index 943583cdd..270ced908 100644 --- a/src/tests/get_item.c +++ b/src/tests/get_item.c @@ -88,6 +88,32 @@ int main(int argc, char *argv[]) } printf("lxc.arch returned %d %s\n", ret, v2); + if (!c->set_config_item(c, "lxc.init_uid", "100")) { + fprintf(stderr, "%d: failed to set init_uid\n", __LINE__); + ret = 1; + goto out; + } + ret = c->get_config_item(c, "lxc.init_uid", v2, 255); + if (ret < 0) { + fprintf(stderr, "%d: get_config_item(lxc.init_uid) returned %d\n", __LINE__, ret); + ret = 1; + goto out; + } + printf("lxc.init_uid returned %d %s\n", ret, v2); + + if (!c->set_config_item(c, "lxc.init_gid", "100")) { + fprintf(stderr, "%d: failed to set init_gid\n", __LINE__); + ret = 1; + goto out; + } + ret = c->get_config_item(c, "lxc.init_gid", v2, 255); + if (ret < 0) { + fprintf(stderr, "%d: get_config_item(lxc.init_gid) returned %d\n", __LINE__, ret); + ret = 1; + goto out; + } + printf("lxc.init_gid returned %d %s\n", ret, v2); + #define HNAME "hostname1" // demonstrate proper usage: char *alloced;