From cc3ddc851fbe5adf9dfc7e4a702a8b5b6a1186d6 Mon Sep 17 00:00:00 2001 From: Ronny Chevalier Date: Mon, 21 Sep 2015 15:36:07 +0200 Subject: [PATCH 1/2] test-execute: add tests for RuntimeDirectory --- src/test/test-execute.c | 7 +++++++ test/exec-runtimedirectory-mode.service | 8 ++++++++ test/exec-runtimedirectory.service | 7 +++++++ 3 files changed, 22 insertions(+) create mode 100644 test/exec-runtimedirectory-mode.service create mode 100644 test/exec-runtimedirectory.service diff --git a/src/test/test-execute.c b/src/test/test-execute.c index 0f4172e722..60540f8d28 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -137,6 +137,11 @@ static void test_exec_umask(Manager *m) { test(m, "exec-umask-0177.service", 0, CLD_EXITED); } +static void test_exec_runtimedirectory(Manager *m) { + test(m, "exec-runtimedirectory.service", 0, CLD_EXITED); + test(m, "exec-runtimedirectory-mode.service", 0, CLD_EXITED); +} + int main(int argc, char *argv[]) { test_function_t tests[] = { test_exec_workingdirectory, @@ -150,6 +155,7 @@ int main(int argc, char *argv[]) { test_exec_group, test_exec_environment, test_exec_umask, + test_exec_runtimedirectory, NULL, }; test_function_t *test = NULL; @@ -165,6 +171,7 @@ int main(int argc, char *argv[]) { return EXIT_TEST_SKIP; } + assert_se(setenv("XDG_RUNTIME_DIR", "/tmp/", 1) == 0); assert_se(set_unit_path(TEST_DIR) >= 0); r = manager_new(MANAGER_USER, true, &m); diff --git a/test/exec-runtimedirectory-mode.service b/test/exec-runtimedirectory-mode.service new file mode 100644 index 0000000000..ba6d7ee39f --- /dev/null +++ b/test/exec-runtimedirectory-mode.service @@ -0,0 +1,8 @@ +[Unit] +Description=Test for RuntimeDirectoryMode + +[Service] +ExecStart=/bin/sh -c 's=$(stat -c %a /tmp/test-exec_runtimedirectory-mode); echo $s; exit $(test $s = "750")' +Type=oneshot +RuntimeDirectory=test-exec_runtimedirectory-mode +RuntimeDirectoryMode=0750 diff --git a/test/exec-runtimedirectory.service b/test/exec-runtimedirectory.service new file mode 100644 index 0000000000..c12a6c63d6 --- /dev/null +++ b/test/exec-runtimedirectory.service @@ -0,0 +1,7 @@ +[Unit] +Description=Test for RuntimeDirectory + +[Service] +ExecStart=/bin/sh -c 'exit $(test -d /tmp/test-exec_runtimedirectory)' +Type=oneshot +RuntimeDirectory=test-exec_runtimedirectory From 5bc7452b3219456e07f931e40da30bb94a884293 Mon Sep 17 00:00:00 2001 From: Ronny Chevalier Date: Mon, 21 Sep 2015 15:45:51 +0200 Subject: [PATCH 2/2] core: fix group ownership when Group is set When Group is set in the unit, the runtime directories are owned by this group and not the default group of the user (same for cgroup paths and standard outputs) Fix #1231 --- src/core/execute.c | 20 +++++++++++--------- src/test/test-execute.c | 1 + test/exec-runtimedirectory-owner.service | 9 +++++++++ 3 files changed, 21 insertions(+), 9 deletions(-) create mode 100644 test/exec-runtimedirectory-owner.service diff --git a/src/core/execute.c b/src/core/execute.c index 3c308e3e3e..6e14848cd4 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -629,15 +629,6 @@ static int enforce_groups(const ExecContext *context, const char *username, gid_ * we avoid NSS lookups for gid=0. */ if (context->group || username) { - - if (context->group) { - const char *g = context->group; - - r = get_group_creds(&g, &gid); - if (r < 0) - return r; - } - /* First step, initialize groups from /etc/groups */ if (username && gid != 0) { if (initgroups(username, gid) < 0) @@ -1414,6 +1405,17 @@ static int exec_child( } } + if (context->group) { + const char *g = context->group; + + r = get_group_creds(&g, &gid); + if (r < 0) { + *exit_status = EXIT_GROUP; + return r; + } + } + + /* If a socket is connected to STDIN/STDOUT/STDERR, we * must sure to drop O_NONBLOCK */ if (socket_fd >= 0) diff --git a/src/test/test-execute.c b/src/test/test-execute.c index 60540f8d28..dd8ab7dcb8 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -140,6 +140,7 @@ static void test_exec_umask(Manager *m) { static void test_exec_runtimedirectory(Manager *m) { test(m, "exec-runtimedirectory.service", 0, CLD_EXITED); test(m, "exec-runtimedirectory-mode.service", 0, CLD_EXITED); + test(m, "exec-runtimedirectory-owner.service", 0, CLD_EXITED); } int main(int argc, char *argv[]) { diff --git a/test/exec-runtimedirectory-owner.service b/test/exec-runtimedirectory-owner.service new file mode 100644 index 0000000000..077e08d1c5 --- /dev/null +++ b/test/exec-runtimedirectory-owner.service @@ -0,0 +1,9 @@ +[Unit] +Description=Test for RuntimeDirectory owner (must not be the default group of the user if Group is set) + +[Service] +ExecStart=/bin/sh -c 'f=/tmp/test-exec_runtimedirectory-owner;g=$(stat -c %G $f); echo "$g"; exit $(test $g = "nobody")' +Type=oneshot +Group=nobody +User=root +RuntimeDirectory=test-exec_runtimedirectory-owner