diff options
author | Luca Boccassi <luca.boccassi@microsoft.com> | 2022-01-27 15:10:34 +0100 |
---|---|---|
committer | Luca Boccassi <luca.boccassi@microsoft.com> | 2022-01-28 01:54:10 +0100 |
commit | 3fa80e5e75a98ef6f9a84b01770b71a1774478dc (patch) | |
tree | 52fcb950118bde2160cd1e51219ee8aa056db592 | |
parent | core: add clearer debug log when setting up ExecDirectories symlinks fails (diff) | |
download | systemd-3fa80e5e75a98ef6f9a84b01770b71a1774478dc.tar.xz systemd-3fa80e5e75a98ef6f9a84b01770b71a1774478dc.zip |
core: do not attempt to add 'private' symlinks when RootImage/RootDirectory are used
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
-rw-r--r-- | src/core/execute.c | 2 | ||||
-rw-r--r-- | test/test-functions | 10 | ||||
-rwxr-xr-x | test/units/testsuite-29.sh | 9 | ||||
-rwxr-xr-x | test/units/testsuite-50.sh | 6 |
4 files changed, 23 insertions, 4 deletions
diff --git a/src/core/execute.c b/src/core/execute.c index acc59ef9db..d3266a9ab5 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -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); diff --git a/test/test-functions b/test/test-functions index f03a63ac04..dcb54ec243 100644 --- a/test/test-functions +++ b/test/test-functions @@ -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" diff --git a/test/units/testsuite-29.sh b/test/units/testsuite-29.sh index 4dbb3a0752..1b927a8305 100755 --- a/test/units/testsuite-29.sh +++ b/test/units/testsuite-29.sh @@ -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 diff --git a/test/units/testsuite-50.sh b/test/units/testsuite-50.sh index ff4f77def2..c79adba5e1 100755 --- a/test/units/testsuite-50.sh +++ b/test/units/testsuite-50.sh @@ -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 |