diff --git a/src/run/run.c b/src/run/run.c index 1f2938f9ea..5d2298a5f6 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -862,7 +862,8 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) { break; case 'D': - r = parse_path_argument(optarg, true, &arg_working_directory); + /* Root will be manually suppressed later. */ + r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_working_directory); if (r < 0) return r; @@ -901,6 +902,10 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) { if (r < 0) return log_error_errno(r, "Failed to get current working directory: %m"); } + } else { + /* Root was not suppressed earlier, to allow the above check to work properly. */ + if (empty_or_root(arg_working_directory)) + arg_working_directory = mfree(arg_working_directory); } arg_service_type = "exec"; diff --git a/test/test-functions b/test/test-functions index 269cd8812b..8a4cc55626 100644 --- a/test/test-functions +++ b/test/test-functions @@ -211,6 +211,7 @@ BASICTOOLS=( ping pkill ps + pwd readlink realpath rev diff --git a/test/units/TEST-74-AUX-UTILS.run.sh b/test/units/TEST-74-AUX-UTILS.run.sh index 9e0a429e41..5b46e11409 100755 --- a/test/units/TEST-74-AUX-UTILS.run.sh +++ b/test/units/TEST-74-AUX-UTILS.run.sh @@ -246,4 +246,16 @@ if [[ -e /usr/lib/pam.d/systemd-run0 ]] || [[ -e /etc/pam.d/systemd-run0 ]]; the # Let's chain a couple of run0 calls together, for fun readarray -t cmdline < <(printf "%.0srun0\n" {0..31}) assert_eq "$("${cmdline[@]}" bash -c 'echo $SUDO_USER')" "$USER" + + # Tests for working directory, especially for specifying "/" (see PR #34771). + cd / + assert_eq "$(run0 pwd)" "/" + assert_eq "$(run0 -D /tmp pwd)" "/tmp" + assert_eq "$(run0 --user=testuser pwd)" "/home/testuser" + assert_eq "$(run0 -D /tmp --user=testuser pwd)" "/tmp" + cd /tmp + assert_eq "$(run0 pwd)" "/tmp" + assert_eq "$(run0 -D / pwd)" "/" + assert_eq "$(run0 --user=testuser pwd)" "/home/testuser" + assert_eq "$(run0 -D / --user=testuser pwd)" "/" fi