]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: do not attempt to add 'private' symlinks when RootImage/RootDirectory are used 22272/head
authorLuca Boccassi <luca.boccassi@microsoft.com>
Thu, 27 Jan 2022 14:10:34 +0000 (14:10 +0000)
committerLuca Boccassi <luca.boccassi@microsoft.com>
Fri, 28 Jan 2022 00:54:10 +0000 (00:54 +0000)
A bind mount is added directly from private on the host to the actual
destination directory, no need for the symlinks (which cannot be created
as the bind mount happens first and creates the target as an actual directory)

Fixes https://github.com/systemd/systemd/issues/22264

src/core/execute.c
test/test-functions
test/units/testsuite-29.sh
test/units/testsuite-50.sh

index acc59ef9db07aa7a1185ef3f3a2056e10b5f0fef..d3266a9ab53ac296942cd13bb10aa8a0b7099563 100644 (file)
@@ -3373,7 +3373,7 @@ static int compile_symlinks(
                                         return r;
                         }
 
-                        if (!exec_directory_is_private(context, dt))
+                        if (!exec_directory_is_private(context, dt) || exec_context_with_rootfs(context))
                                 continue;
 
                         private_path = path_join(params->prefix[dt], "private", context->directories[dt].items[i].path);
index f03a63ac0410a0bc54fbcb911d2594fd4a512233..dcb54ec2433ad790cc198da6f3837352018a6181 100644 (file)
@@ -576,7 +576,8 @@ install_verity_minimal() {
         oldinitdir="$initdir"
         rm -rfv "$TESTDIR/minimal"
         export initdir="$TESTDIR/minimal"
-        mkdir -p "$initdir/usr/lib/systemd/system" "$initdir/usr/lib/extension-release.d" "$initdir/etc" "$initdir/var/tmp" "$initdir/opt"
+        # app0 will use TemporaryFileSystem=/var/lib, app1 will need the mount point in the base image
+        mkdir -p "$initdir/usr/lib/systemd/system" "$initdir/usr/lib/extension-release.d" "$initdir/etc" "$initdir/var/tmp" "$initdir/opt" "$initdir/var/lib/app1"
         setup_basic_dirs
         install_basic_tools
         # Shellcheck treats [[ -v VAR ]] as an assignment to avoid a different
@@ -633,11 +634,15 @@ EOF
 Type=oneshot
 RemainAfterExit=yes
 ExecStart=/opt/script0.sh
+TemporaryFileSystem=/var/lib
+StateDirectory=app0
+RuntimeDirectory=app0
 EOF
         cat >"$initdir/opt/script0.sh" <<EOF
 #!/bin/bash
 set -e
 test -e /usr/lib/os-release
+echo bar > \${STATE_DIRECTORY}/foo
 cat /usr/lib/extension-release.d/extension-release.app0
 EOF
         chmod +x "$initdir/opt/script0.sh"
@@ -656,11 +661,14 @@ EOF
 Type=oneshot
 RemainAfterExit=yes
 ExecStart=/opt/script1.sh
+StateDirectory=app1
+RuntimeDirectory=app1
 EOF
         cat >"$initdir/opt/script1.sh" <<EOF
 #!/bin/bash
 set -e
 test -e /usr/lib/os-release
+echo baz > \${STATE_DIRECTORY}/foo
 cat /usr/lib/extension-release.d/extension-release.app2
 EOF
         chmod +x "$initdir/opt/script1.sh"
index 4dbb3a07520b0b8f4c66537126e9d2c441fadd87..1b927a83052dbee7e960cfcf189d11f72c7a6b75 100755 (executable)
@@ -6,10 +6,13 @@ set -eux
 set -o pipefail
 
 ARGS=()
+state_directory=/var/lib/private/
 if [[ -v ASAN_OPTIONS || -v UBSAN_OPTIONS ]]; then
     # If we're running under sanitizers, we need to use a less restrictive
     # profile, otherwise LSan syscall would get blocked by seccomp
     ARGS+=(--profile=trusted)
+    # With the trusted profile DynamicUser is disabled, so the storage is not in private/
+    state_directory=/var/lib/
 fi
 
 systemd-dissect --no-pager /usr/share/minimal_0.raw | grep -q '✓ portable service'
@@ -109,6 +112,12 @@ status="$(portablectl is-attached --extension app1 minimal_1)"
 
 portablectl detach --now --runtime --extension /usr/share/app1.raw /usr/share/minimal_1.raw app1
 
+# Ensure that the combination of read-only images, state directory and dynamic user works, and that
+# state is retained. Check after detaching, as on slow systems (eg: sanitizers) it might take a while
+# after the service is attached before the file appears.
+grep -q -F bar "${state_directory}/app0/foo"
+grep -q -F baz "${state_directory}/app1/foo"
+
 # portablectl also works with directory paths rather than images
 
 mkdir /tmp/rootdir /tmp/app0 /tmp/app1 /tmp/overlay /tmp/os-release-fix /tmp/os-release-fix/etc
index ff4f77def2d59415e4363f99b0738b388c9d86d5..c79adba5e17c23f70b2774cf774fe5d280370400 100755 (executable)
@@ -308,7 +308,8 @@ systemd-run -P --property ExtensionImages="/usr/share/app0.raw /usr/share/app1.r
 cat >/run/systemd/system/testservice-50e.service <<EOF
 [Service]
 MountAPIVFS=yes
-TemporaryFileSystem=/run
+TemporaryFileSystem=/run /var/lib
+StateDirectory=app0
 RootImage=${image}.raw
 ExtensionImages=/usr/share/app0.raw /usr/share/app1.raw:nosuid
 # Relevant only for sanitizer runs
@@ -336,7 +337,8 @@ systemd-run -P --property ExtensionDirectories="${image_dir}/app0 ${image_dir}/a
 cat >/run/systemd/system/testservice-50f.service <<EOF
 [Service]
 MountAPIVFS=yes
-TemporaryFileSystem=/run
+TemporaryFileSystem=/run /var/lib
+StateDirectory=app0
 RootImage=${image}.raw
 ExtensionDirectories=${image_dir}/app0 ${image_dir}/app1
 # Relevant only for sanitizer runs