From 9d1431e1309e1acee06c016acc08cb7650b1d0af Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Thu, 11 Nov 2021 11:53:58 +0000 Subject: [PATCH] jail: allow passing environment variable to procd jailed process Introduce new option '-e' to ujail which can be stated multiple times to import environment variables to the jailed process environment. Use that option to import selected environment variables defined for a jailed service instance to its environment. Signed-off-by: Daniel Golle --- jail/jail.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- service/instance.c | 9 +++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/jail/jail.c b/jail/jail.c index 3f42bcb..6e9306d 100644 --- a/jail/jail.c +++ b/jail/jail.c @@ -69,7 +69,7 @@ #endif #define STACK_SIZE (1024 * 1024) -#define OPT_ARGS "cC:d:EfFG:h:ij:J:ln:NoO:pP:r:R:sS:uU:w:T:y" +#define OPT_ARGS "cC:d:e:EfFG:h:ij:J:ln:NoO:pP:r:R:sS:uU:w:T:y" #define OCI_VERSION_STRING "1.0.2" @@ -980,6 +980,7 @@ static void usage(void) fprintf(stderr, " -C \tcapabilities drop config\n"); fprintf(stderr, " -c\t\tset PR_SET_NO_NEW_PRIVS\n"); fprintf(stderr, " -n \tthe name of the jail\n"); + fprintf(stderr, " -e \timport environment variable\n"); fprintf(stderr, "namespace jail options:\n"); fprintf(stderr, " -h \tchange the hostname of the jail\n"); fprintf(stderr, " -N\t\tjail has network namespace\n"); @@ -2541,6 +2542,12 @@ static int pidns_fd; static int timens_fd; #endif static void post_create_runtime(void); + +struct env_e { + struct list_head list; + char *envarg; +}; + int main(int argc, char **argv) { uid_t uid = getuid(); @@ -2549,6 +2556,9 @@ int main(int argc, char **argv) int ret = EXIT_FAILURE; int ch; char *tmp; + struct list_head envl = LIST_HEAD_INIT(envl); + struct env_e *enve, *tmpenve; + unsigned short int envn = 0, envc = 0; if (uid) { ERROR("not root, aborting: %m\n"); @@ -2578,6 +2588,11 @@ int main(int argc, char **argv) case 'd': debug = atoi(optarg); break; + case 'e': + enve = calloc(1, sizeof(*enve)); + enve->envarg = optarg; + list_add_tail(&enve->list, &envl); + break; case 'p': opts.namespace |= CLONE_NEWNS; opts.procfs = 1; @@ -2683,6 +2698,34 @@ int main(int argc, char **argv) if (opts.namespace && !opts.ocibundle) opts.namespace |= CLONE_NEWIPC | CLONE_NEWPID; + /* + * env import from cmdline is not available for OCI containers + */ + if (opts.ocibundle && !list_empty(&envl)) { + ret=-ENOTSUP; + goto errout; + } + + /* + * prepare list of env variables to import for slim containers + */ + if (!list_empty(&envl)) { + list_for_each_entry(enve, &envl, list) + ++envn; + + opts.envp = calloc(1 + envn, sizeof(char*)); + list_for_each_entry_safe(enve, tmpenve, &envl, list) { + tmp = getenv(enve->envarg); + if (tmp) + asprintf(&opts.envp[envc++], "%s=%s", enve->envarg, tmp); + + list_del(&enve->list); + free(enve); + } + + opts.envp[envc] = NULL; + } + /* * uid in parent user namespace representing root user in new * user namespace, defaults to nobody unless specified in uidMappings diff --git a/service/instance.c b/service/instance.c index 701ca00..8cabedb 100644 --- a/service/instance.c +++ b/service/instance.c @@ -385,6 +385,11 @@ jail_run(struct service_instance *in, char **argv) if (in->require_jail) argv[argc++] = "-E"; + blobmsg_list_for_each(&in->env, var) { + argv[argc++] = "-e"; + argv[argc++] = (char *) blobmsg_name(var->data); + } + blobmsg_list_for_each(&jail->mount, var) { const char *type = blobmsg_data(var->data); @@ -1137,6 +1142,7 @@ instance_jail_parse(struct service_instance *in, struct blob_attr *attr) { struct blob_attr *tb[__JAIL_ATTR_MAX]; struct jail *jail = &in->jail; + struct blobmsg_list_node *var; blobmsg_parse(jail_attr, __JAIL_ATTR_MAX, tb, blobmsg_data(attr), blobmsg_data_len(attr)); @@ -1219,6 +1225,9 @@ instance_jail_parse(struct service_instance *in, struct blob_attr *attr) instance_fill_array(&jail->mount, tb[JAIL_ATTR_MOUNT], NULL, false); } + blobmsg_list_for_each(&in->env, var) + jail->argc += 2; + if (in->seccomp) jail->argc += 2; -- 2.30.2