]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
execute: Make '+' exec prefix ignore PrivateTmp=yes
authorNate Jones <jonesnl@umich.edu>
Sat, 29 Feb 2020 01:31:23 +0000 (20:31 -0500)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 29 Feb 2020 10:32:01 +0000 (19:32 +0900)
The man pages state that the '+' prefix in Exec* directives should
ignore filesystem namespacing options such as PrivateTmp. Now it does.

This is very similar to #8842, just with PrivateTmp instead of
PrivateDevices.

src/core/execute.c
src/test/test-execute.c
test/meson.build
test/test-execute/exec-basic.service
test/test-execute/exec-privatetmp-disabled-by-prefix.service [new file with mode: 0644]

index 27777c0d85952d1d97c8a42a242c8939933f0eaa..b05471223bdbf792da1bb7980b7f97885e47c1a4 100644 (file)
@@ -2565,17 +2565,6 @@ static int apply_mount_namespace(
 
         assert(context);
 
-        /* The runtime struct only contains the parent of the private /tmp,
-         * which is non-accessible to world users. Inside of it there's a /tmp
-         * that is sticky, and that's the one we want to use here. */
-
-        if (context->private_tmp && runtime) {
-                if (runtime->tmp_dir)
-                        tmp = strjoina(runtime->tmp_dir, "/tmp");
-                if (runtime->var_tmp_dir)
-                        var = strjoina(runtime->var_tmp_dir, "/tmp");
-        }
-
         if (params->flags & EXEC_APPLY_CHROOT) {
                 root_image = context->root_image;
 
@@ -2588,7 +2577,18 @@ static int apply_mount_namespace(
                 return r;
 
         needs_sandboxing = (params->flags & EXEC_APPLY_SANDBOXING) && !(command->flags & EXEC_COMMAND_FULLY_PRIVILEGED);
-        if (needs_sandboxing)
+        if (needs_sandboxing) {
+                /* The runtime struct only contains the parent of the private /tmp,
+                 * which is non-accessible to world users. Inside of it there's a /tmp
+                 * that is sticky, and that's the one we want to use here. */
+
+                if (context->private_tmp && runtime) {
+                        if (runtime->tmp_dir)
+                                tmp = strjoina(runtime->tmp_dir, "/tmp");
+                        if (runtime->var_tmp_dir)
+                                var = strjoina(runtime->var_tmp_dir, "/tmp");
+                }
+
                 ns_info = (NamespaceInfo) {
                         .ignore_protect_paths = false,
                         .private_dev = context->private_devices,
@@ -2600,7 +2600,7 @@ static int apply_mount_namespace(
                         .mount_apivfs = context->mount_apivfs,
                         .private_mounts = context->private_mounts,
                 };
-        else if (!context->dynamic_user && root_dir)
+        else if (!context->dynamic_user && root_dir)
                 /*
                  * If DynamicUser=no and RootDirectory= is set then lets pass a relaxed
                  * sandbox info, otherwise enforce it, don't ignore protected paths and
index ff40e0dd43dd4749a239bef701ee216194e81dd0..92a0516df7650b9f221303523fa11d50d2884f86 100644 (file)
@@ -294,6 +294,7 @@ static void test_exec_privatetmp(Manager *m) {
 
         test(__func__, m, "exec-privatetmp-yes.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
         test(__func__, m, "exec-privatetmp-no.service", 0, CLD_EXITED);
+        test(__func__, m, "exec-privatetmp-disabled-by-prefix.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
 
         unlink("/tmp/test-exec_privatetmp");
 }
index 856e4a434d0365a4320d048d5b06e45f5b67deac..2fbea31ccd9c76e406bebe772c6c713b04ab112a 100644 (file)
@@ -109,6 +109,7 @@ test_data_files = '''
         test-execute/exec-privatenetwork-yes.service
         test-execute/exec-privatetmp-no.service
         test-execute/exec-privatetmp-yes.service
+        test-execute/exec-privatetmp-disabled-by-prefix.service
         test-execute/exec-protecthome-tmpfs-vs-protectsystem-strict.service
         test-execute/exec-protectkernellogs-yes-capabilities.service
         test-execute/exec-protectkernellogs-no-capabilities.service
index ae4618c3f375f14c71a94185b074eeba3e4e5be1..60c5be6dc98c2ddce384b04d9db05597c76cb295 100644 (file)
@@ -10,7 +10,6 @@ ExecStart=touch /tmp/a ; /bin/sh -c 'touch /tmp/b' ; touch /tmp/c
 ExecStart=test -f /tmp/a
 ExecStart=!test -f /tmp/b
 ExecStart=!!test -f /tmp/c
-ExecStart=+test -f /tmp/c
 ExecStartPost=rm /tmp/a /tmp/b /tmp/c
 
 PrivateTmp=true
diff --git a/test/test-execute/exec-privatetmp-disabled-by-prefix.service b/test/test-execute/exec-privatetmp-disabled-by-prefix.service
new file mode 100644 (file)
index 0000000..009e6be
--- /dev/null
@@ -0,0 +1,8 @@
+[Unit]
+Description=Test for PrivateTmp=yes with prefix
+
+[Service]
+ExecStart=/bin/sh -x -c 'test ! -f /tmp/test-exec_privatetmp'
+ExecStart=+/bin/sh -x -c 'test -f /tmp/test-exec_privatetmp'
+Type=oneshot
+PrivateTmp=yes