#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"
fprintf(stderr, " -C <file>\tcapabilities drop config\n");
fprintf(stderr, " -c\t\tset PR_SET_NO_NEW_PRIVS\n");
fprintf(stderr, " -n <name>\tthe name of the jail\n");
+ fprintf(stderr, " -e <var>\timport environment variable\n");
fprintf(stderr, "namespace jail options:\n");
fprintf(stderr, " -h <hostname>\tchange the hostname of the jail\n");
fprintf(stderr, " -N\t\tjail has network namespace\n");
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();
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");
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;
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
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);
{
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));
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;