1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-12 09:17:44 +03:00

Merge pull request #22272 from bluca/state_dir_private_rootfs

core: do not attempt to add 'private' symlinks when RootImage/RootDirectory are used
This commit is contained in:
Yu Watanabe 2022-01-28 12:04:41 +09:00 committed by GitHub
commit 673a181702
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 55 additions and 32 deletions

View 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);

View File

@ -1804,7 +1804,7 @@ static int apply_mounts(
* exist, which means this will be a no-op. */
r = create_symlinks_from_tuples(root, exec_dir_symlinks);
if (r < 0)
return r;
return log_debug_errno(r, "Failed to set up ExecDirectories symlinks inside mount namespace: %m");
/* Create a deny list we can pass to bind_mount_recursive() */
deny_list = new(char*, (*n_mounts)+1);

View 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
@ -598,19 +599,23 @@ install_verity_minimal() {
touch "$initdir/etc/machine-id" "$initdir/etc/resolv.conf"
touch "$initdir/opt/some_file"
echo MARKER=1 >>"$initdir/usr/lib/os-release"
echo "PORTABLE_PREFIXES=app0 minimal" >>"$initdir/usr/lib/os-release"
echo -e "[Service]\nExecStartPre=cat /usr/lib/os-release\nExecStart=sleep 120" >"$initdir/usr/lib/systemd/system/app0.service"
cp "$initdir/usr/lib/systemd/system/app0.service" "$initdir/usr/lib/systemd/system/app0-foo.service"
echo "PORTABLE_PREFIXES=app0 minimal minimal-app0" >>"$initdir/usr/lib/os-release"
cat >"$initdir/usr/lib/systemd/system/minimal-app0.service" <<EOF
[Service]
ExecStartPre=cat /usr/lib/os-release
ExecStart=sleep 120
EOF
cp "$initdir/usr/lib/systemd/system/minimal-app0.service" "$initdir/usr/lib/systemd/system/minimal-app0-foo.service"
mksquashfs "$initdir" "$oldinitdir/usr/share/minimal_0.raw"
mksquashfs "$initdir" "$oldinitdir/usr/share/minimal_0.raw" -noappend
veritysetup format "$oldinitdir/usr/share/minimal_0.raw" "$oldinitdir/usr/share/minimal_0.verity" | \
grep '^Root hash:' | cut -f2 | tr -d '\n' >"$oldinitdir/usr/share/minimal_0.roothash"
sed -i "s/MARKER=1/MARKER=2/g" "$initdir/usr/lib/os-release"
rm "$initdir/usr/lib/systemd/system/app0-foo.service"
cp "$initdir/usr/lib/systemd/system/app0.service" "$initdir/usr/lib/systemd/system/app0-bar.service"
rm "$initdir/usr/lib/systemd/system/minimal-app0-foo.service"
cp "$initdir/usr/lib/systemd/system/minimal-app0.service" "$initdir/usr/lib/systemd/system/minimal-app0-bar.service"
mksquashfs "$initdir" "$oldinitdir/usr/share/minimal_1.raw"
mksquashfs "$initdir" "$oldinitdir/usr/share/minimal_1.raw" -noappend
veritysetup format "$oldinitdir/usr/share/minimal_1.raw" "$oldinitdir/usr/share/minimal_1.verity" | \
grep '^Root hash:' | cut -f2 | tr -d '\n' >"$oldinitdir/usr/share/minimal_1.roothash"
@ -629,16 +634,20 @@ install_verity_minimal() {
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"
echo MARKER=1 >"$initdir/usr/lib/systemd/system/some_file"
mksquashfs "$initdir" "$oldinitdir/usr/share/app0.raw"
mksquashfs "$initdir" "$oldinitdir/usr/share/app0.raw" -noappend
export initdir="$TESTDIR/app1"
mkdir -p "$initdir/usr/lib/extension-release.d" "$initdir/usr/lib/systemd/system" "$initdir/opt"
@ -652,16 +661,19 @@ 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"
echo MARKER=1 >"$initdir/usr/lib/systemd/system/other_file"
mksquashfs "$initdir" "$oldinitdir/usr/share/app1.raw"
mksquashfs "$initdir" "$oldinitdir/usr/share/app1.raw" -noappend
)
}

View File

@ -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'
@ -24,29 +27,29 @@ cat <<EOF >/run/systemd/system/systemd-portabled.service.d/override.conf
Environment=SYSTEMD_LOG_LEVEL=debug
EOF
portablectl "${ARGS[@]}" attach --now --runtime /usr/share/minimal_0.raw app0
portablectl "${ARGS[@]}" attach --now --runtime /usr/share/minimal_0.raw minimal-app0
systemctl is-active app0.service
systemctl is-active app0-foo.service
systemctl is-active minimal-app0.service
systemctl is-active minimal-app0-foo.service
set +o pipefail
set +e
systemctl is-active app0-bar.service && exit 1
systemctl is-active minimal-app0-bar.service && exit 1
set -e
set -o pipefail
portablectl "${ARGS[@]}" reattach --now --runtime /usr/share/minimal_1.raw app0
portablectl "${ARGS[@]}" reattach --now --runtime /usr/share/minimal_1.raw minimal-app0
systemctl is-active app0.service
systemctl is-active app0-bar.service
systemctl is-active minimal-app0.service
systemctl is-active minimal-app0-bar.service
set +o pipefail
set +e
systemctl is-active app0-foo.service && exit 1
systemctl is-active minimal-app0-foo.service && exit 1
set -e
set -o pipefail
portablectl list | grep -q -F "minimal_1"
portablectl detach --now --runtime /usr/share/minimal_1.raw app0
portablectl detach --now --runtime /usr/share/minimal_1.raw minimal-app0
portablectl list | grep -q -F "No images."
@ -55,29 +58,29 @@ portablectl list | grep -q -F "No images."
unsquashfs -dest /tmp/minimal_0 /usr/share/minimal_0.raw
unsquashfs -dest /tmp/minimal_1 /usr/share/minimal_1.raw
portablectl "${ARGS[@]}" attach --copy=symlink --now --runtime /tmp/minimal_0 app0
portablectl "${ARGS[@]}" attach --copy=symlink --now --runtime /tmp/minimal_0 minimal-app0
systemctl is-active app0.service
systemctl is-active app0-foo.service
systemctl is-active minimal-app0.service
systemctl is-active minimal-app0-foo.service
set +o pipefail
set +e
systemctl is-active app0-bar.service && exit 1
systemctl is-active minimal-app0-bar.service && exit 1
set -e
set -o pipefail
portablectl "${ARGS[@]}" reattach --now --enable --runtime /tmp/minimal_1 app0
portablectl "${ARGS[@]}" reattach --now --enable --runtime /tmp/minimal_1 minimal-app0
systemctl is-active app0.service
systemctl is-active app0-bar.service
systemctl is-active minimal-app0.service
systemctl is-active minimal-app0-bar.service
set +o pipefail
set +e
systemctl is-active app0-foo.service && exit 1
systemctl is-active minimal-app0-foo.service && exit 1
set -e
set -o pipefail
portablectl list | grep -q -F "minimal_1"
portablectl detach --now --enable --runtime /tmp/minimal_1 app0
portablectl detach --now --enable --runtime /tmp/minimal_1 minimal-app0
portablectl list | grep -q -F "No images."
@ -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

View File

@ -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