From a2872389e30219feb0a298c7030ab040aee28641 Mon Sep 17 00:00:00 2001 From: Andrew Potter Date: Thu, 24 Oct 2024 13:14:57 -0700 Subject: [PATCH] core: Setup ExecDirectories before stdin/stdout. Fixes #27591 --- src/core/exec-invoke.c | 17 +++++++++-------- src/test/test-execute.c | 6 ++++++ .../exec-runtimedirectory-stdoutput.service | 9 +++++++++ 3 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 test/test-execute/exec-runtimedirectory-stdoutput.service diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index cdfa9f823b1..081ac1a2814 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -4382,6 +4382,15 @@ int exec_invoke( } } + /* Setup ExecDirectories now, as they may be targeted by stdin/stdout */ + needs_mount_namespace = exec_needs_mount_namespace(context, params, runtime); + + for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) { + r = setup_exec_directory(context, params, uid, gid, dt, needs_mount_namespace, exit_status); + if (r < 0) + return log_exec_error_errno(context, params, r, "Failed to set up special execution directory in %s: %m", params->prefix[dt]); + } + r = setup_input(context, params, socket_fd, named_iofds); if (r < 0) { *exit_status = EXIT_STDIN; @@ -4602,14 +4611,6 @@ int exec_invoke( } } - needs_mount_namespace = exec_needs_mount_namespace(context, params, runtime); - - for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) { - r = setup_exec_directory(context, params, uid, gid, dt, needs_mount_namespace, exit_status); - if (r < 0) - return log_exec_error_errno(context, params, r, "Failed to set up special execution directory in %s: %m", params->prefix[dt]); - } - r = exec_setup_credentials(context, params, params->unit_id, uid, gid); if (r < 0) { *exit_status = EXIT_CREDENTIALS; diff --git a/src/test/test-execute.c b/src/test/test-execute.c index 95ccf5490de..1f0160e9bb6 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -1128,6 +1128,11 @@ static void test_exec_runtimedirectory(Manager *m) { test(m, "exec-runtimedirectory-owner-" NOBODY_GROUP_NAME ".service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP, CLD_EXITED); } +static void test_exec_runtimedirectory_stdoutput(Manager *m) { + (void) rm_rf("/run/test-exec_runtimedirectory_standardoutput", REMOVE_ROOT|REMOVE_PHYSICAL); + test(m, "exec-runtimedirectory-stdoutput.service", 0, CLD_EXITED); +} + static void test_exec_capabilityboundingset(Manager *m) { int r; @@ -1359,6 +1364,7 @@ static void run_tests(RuntimeScope scope, char **patterns) { entry(test_exec_readwritepaths), entry(test_exec_restrictnamespaces), entry(test_exec_runtimedirectory), + entry(test_exec_runtimedirectory_stdoutput), entry(test_exec_specifier), entry(test_exec_standardinput), entry(test_exec_standardoutput), diff --git a/test/test-execute/exec-runtimedirectory-stdoutput.service b/test/test-execute/exec-runtimedirectory-stdoutput.service new file mode 100644 index 00000000000..7803c3f1ab4 --- /dev/null +++ b/test/test-execute/exec-runtimedirectory-stdoutput.service @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +[Unit] +Description=Test for RuntimeDirectory used by StandardOutput + +[Service] +ExecStart=sh -c 'printf "hello\nhello\n"' +Type=oneshot +RuntimeDirectory=test-exec_runtimedirectory_standardoutput +StandardOutput=file:/run/test-exec_runtimedirectory_standardoutput/test-exec-runtimedirectory_standardoutput-output