Skip to content

Commit

Permalink
On exec, honor additional_gids from the process spec, not the contain…
Browse files Browse the repository at this point in the history
…er definition

The code was using the process defined in the container definition to find additional_gids,
not the one passed on the command line or created by default.

Fixes #644

Signed-off-by: Owen W. Taylor <otaylor@fishsoup.net>
  • Loading branch information
owtaylor committed Apr 9, 2021
1 parent 99e2dc7 commit 9effaeb
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/libcrun/container.c
Original file line number Diff line number Diff line change
Expand Up @@ -3177,7 +3177,7 @@ libcrun_container_exec (libcrun_context_t *context, const char *id, runtime_spec
close_and_reset (&seccomp_receiver_fd);
}

ret = libcrun_container_setgroups (container, err);
ret = libcrun_container_setgroups (container, process, err);
if (UNLIKELY (ret < 0))
return ret;

Expand Down
13 changes: 7 additions & 6 deletions src/libcrun/linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -2090,18 +2090,19 @@ can_setgroups (libcrun_container_t *container, libcrun_error_t *err)
}

int
libcrun_container_setgroups (libcrun_container_t *container, libcrun_error_t *err)
libcrun_container_setgroups (libcrun_container_t *container,
runtime_spec_schema_config_schema_process *process,
libcrun_error_t *err)
{
runtime_spec_schema_config_schema *def = container->container_def;
gid_t *additional_gids = NULL;
size_t additional_gids_len = 0;
int can_do_setgroups;
int ret;

if (def->process != NULL && def->process->user != NULL)
if (process != NULL && process->user != NULL)
{
additional_gids = def->process->user->additional_gids;
additional_gids_len = def->process->user->additional_gids_len;
additional_gids = process->user->additional_gids;
additional_gids_len = process->user->additional_gids_len;
}

can_do_setgroups = can_setgroups (container, err);
Expand Down Expand Up @@ -3217,7 +3218,7 @@ init_container (libcrun_container_t *container, int sync_socket_container, struc
return ret;
}

ret = libcrun_container_setgroups (container, err);
ret = libcrun_container_setgroups (container, container->container_def->process, err);
if (UNLIKELY (ret < 0))
return ret;

Expand Down
4 changes: 3 additions & 1 deletion src/libcrun/linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ int libcrun_container_restore_linux (libcrun_container_status_t *status, libcrun

int libcrun_find_namespace (const char *name);
char *libcrun_get_external_descriptors (libcrun_container_t *container);
int libcrun_container_setgroups (libcrun_container_t *container, libcrun_error_t *err);
int libcrun_container_setgroups (libcrun_container_t *container,
runtime_spec_schema_config_schema_process *process,
libcrun_error_t *err);
int libcrun_kill_linux (libcrun_container_status_t *status, int signal, libcrun_error_t *err);
int libcrun_create_final_userns (libcrun_container_t *container, libcrun_error_t *err);
#endif
13 changes: 13 additions & 0 deletions tests/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,19 @@ int main (int argc, char **argv)
exit (0);
}

if (strcmp (argv[1], "groups") == 0)
{
gid_t groups[10];
int max_groups = sizeof(groups) / sizeof(groups[0]);
int n_groups, i;
n_groups = getgroups(max_groups, groups);
fputs("GROUPS=[", stdout);
for (i = 0; i < n_groups; i++)
printf("%s%d", i == 0 ? "" : " ", groups[i]);
fputs("]\n", stdout);
exit (0);
}

if (strcmp (argv[1], "cat") == 0)
{
if (argc < 3)
Expand Down
42 changes: 41 additions & 1 deletion tests/test_exec.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import os
import shutil
import sys
import tempfile
from tests_utils import *

def test_exec():
Expand Down Expand Up @@ -62,11 +63,50 @@ def test_exec_not_exists():

def test_exec_detach_not_exists():
return test_exec_not_exists_helper(False)


def test_exec_additional_gids():
conf = base_config()
conf['process']['args'] = ['/init', 'pause']
add_all_namespaces(conf)
cid = None
tempdir = tempfile.mkdtemp()
try:
_, cid = run_and_get_output(conf, command='run', detach=True)

process_file = os.path.join(tempdir, "process.json")
with open(process_file, "w") as f:
json.dump({
"user": {
"uid": 0,
"gid": 0,
"additionalGids": [432]
},
"terminal": False,
"args": [
"/init",
"groups"
],
"env": [
"PATH=/bin",
"TERM=xterm"
],
"cwd": "/",
"noNewPrivileges": True
}, f)
out = run_crun_command(["exec", "--process", process_file, cid])
if "432" not in out:
return -1
finally:
if cid is not None:
run_crun_command(["delete", "-f", cid])
shutil.rmtree(tempdir)
return 0

all_tests = {
"exec" : test_exec,
"exec-not-exists" : test_exec_not_exists,
"exec-detach-not-exists" : test_exec_detach_not_exists,
"exec-detach-additional-gids" : test_exec_additional_gids,
}

if __name__ == "__main__":
Expand Down

0 comments on commit 9effaeb

Please sign in to comment.