diff options
| author | Daniel Golle | 2020-07-18 23:35:16 +0000 |
|---|---|---|
| committer | Daniel Golle | 2020-07-19 18:26:09 +0000 |
| commit | c049047be476da6a9e044b6e16a66678c2460156 (patch) | |
| tree | fe8315cd4004fe53c19dc88f2971fae1e193cc87 | |
| parent | 1b1286bd189c6957080f98c066f7bcf83138546e (diff) | |
| download | procd-c049047be476da6a9e044b6e16a66678c2460156.tar.gz | |
jail: implement OCI user additionalGIDs
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
| -rw-r--r-- | jail/jail.c | 54 |
1 files changed, 47 insertions, 7 deletions
diff --git a/jail/jail.c b/jail/jail.c index f844b57..287307f 100644 --- a/jail/jail.c +++ b/jail/jail.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2015 John Crispin <blogic@openwrt.org> + * Copyright (C) 2020 Daniel Golle <daniel@makrotopia.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1 @@ -91,6 +92,8 @@ static struct { int pw_uid; int pw_gid; int gr_gid; + gid_t *additional_gids; + size_t num_additional_gids; int require_jail; struct { struct hook_execvpe **createRuntime; @@ -860,6 +863,18 @@ static int exec_jail(void *pipes_ptr) } run_hooks(opts.hooks.startContainer); + if (!(opts.namespace & CLONE_NEWUSER)) { + get_jail_user(&pw_uid, &pw_gid, &gr_gid); + + set_jail_user(opts.pw_uid?:pw_uid, opts.pw_gid?:pw_gid, opts.gr_gid?:gr_gid); + } + + if (opts.additional_gids && + (setgroups(opts.num_additional_gids, opts.additional_gids) < 0)) { + ERROR("setgroups failed: %m\n"); + exit(EXIT_FAILURE); + } + if (applyOCIcapabilities(opts.capset)) exit(EXIT_FAILURE); @@ -871,12 +886,6 @@ static int exec_jail(void *pipes_ptr) exit(EXIT_FAILURE); } - if (!(opts.namespace & CLONE_NEWUSER)) { - get_jail_user(&pw_uid, &pw_gid, &gr_gid); - - set_jail_user(opts.pw_uid?:pw_uid, opts.pw_gid?:pw_gid, opts.gr_gid?:gr_gid); - } - char **envp = build_envp(opts.seccomp, opts.envp); if (!envp) exit(EXIT_FAILURE); @@ -1216,6 +1225,9 @@ static const struct blobmsg_policy oci_process_user_policy[] = { static int parseOCIprocessuser(struct blob_attr *msg) { struct blob_attr *tb[__OCI_PROCESS_USER_MAX]; + struct blob_attr *cur; + int rem; + int has_gid = 0; blobmsg_parse(oci_process_user_policy, __OCI_PROCESS_USER_MAX, tb, blobmsg_data(msg), blobmsg_len(msg)); @@ -1225,9 +1237,37 @@ static int parseOCIprocessuser(struct blob_attr *msg) { if (tb[OCI_PROCESS_USER_GID]) { opts.pw_gid = blobmsg_get_u32(tb[OCI_PROCESS_USER_GID]); opts.gr_gid = blobmsg_get_u32(tb[OCI_PROCESS_USER_GID]); + has_gid = 1; + } + + if (tb[OCI_PROCESS_USER_ADDITIONALGIDS]) { + size_t gidcnt = 0; + + blobmsg_for_each_attr(cur, tb[OCI_PROCESS_USER_ADDITIONALGIDS], rem) { + ++gidcnt; + if (has_gid && (blobmsg_get_u32(cur) == opts.gr_gid)) + continue; + } + + if (gidcnt) { + opts.additional_gids = calloc(gidcnt + has_gid, sizeof(gid_t)); + gidcnt = 0; + + /* always add primary GID to set of GIDs if set */ + if (has_gid) + opts.additional_gids[gidcnt++] = opts.gr_gid; + + blobmsg_for_each_attr(cur, tb[OCI_PROCESS_USER_ADDITIONALGIDS], rem) { + if (has_gid && (blobmsg_get_u32(cur) == opts.gr_gid)) + continue; + opts.additional_gids[gidcnt++] = blobmsg_get_u32(cur); + } + opts.num_additional_gids = gidcnt; + } + DEBUG("read %lu additional groups\n", gidcnt); } - /* ToDo: umask, additional GIDs */ + /* ToDo: umask */ return 0; } |