]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test: add more tests for StateDirectory= with DynamicUser= 24784/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 22 Sep 2022 04:08:32 +0000 (13:08 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 3 Oct 2022 00:25:00 +0000 (09:25 +0900)
This also moves the check for writable paths from test-execute to TEST-34.

Closes #10337.

test/test-execute/exec-dynamicuser-statedir.service
test/units/testsuite-34.sh

index 07692e1c1240d59954b2c9ec74b6297eaba11078..b33b4da74af9f771601eabfebbb2a70af9799d8f 100644 (file)
@@ -5,17 +5,72 @@ Description=Test DynamicUser= with StateDirectory=
 [Service]
 ExecStart=test -w /var/lib/waldo
 ExecStart=test -w /var/lib/quux/pief
-ExecStart=touch /var/lib/waldo/yay
-ExecStart=touch /var/lib/quux/pief/yayyay
-ExecStart=test -f /var/lib/waldo/yay
-ExecStart=test -f /var/lib/quux/pief/yayyay
-ExecStart=test -f /var/lib/private/waldo/yay
-ExecStart=test -f /var/lib/private/quux/pief/yayyay
-ExecStart=sh -x -c 'test "$$STATE_DIRECTORY" = "%S/waldo:%S/quux/pief"'
+ExecStart=test -w /var/lib/aaa
+ExecStart=test -w /var/lib/aaa/bbb
+ExecStart=test -w /var/lib/aaa/ccc
+ExecStart=test -w /var/lib/xxx
+ExecStart=test -w /var/lib/xxx/yyy
+ExecStart=test -w /var/lib/xxx/zzz
+ExecStart=test -w /var/lib/aaa/111
+ExecStart=test -w /var/lib/aaa/222
+ExecStart=test -w /var/lib/aaa/333
 
-# Make sure that /var/lib/private/waldo is really the only writable directory besides the obvious candidates
-ExecStart=sh -x -c 'test $$(find / \\( -path /var/tmp -o -path /tmp -o -path /proc -o -path /dev/mqueue -o -path /dev/shm -o -path /sys/fs/bpf -o -path /dev/.lxc -o -path /sys/devices/system/cpu \\) -prune -o -type d -writable -print 2>/dev/null | sort -u | tr -d "\\\\n") = /var/lib/private/quux/pief/var/lib/private/waldo'
+ExecStart=test -d /var/lib/waldo
+ExecStart=test -d /var/lib/quux/pief
+ExecStart=test -d /var/lib/aaa
+ExecStart=test -d /var/lib/aaa/bbb
+ExecStart=test -d /var/lib/aaa/ccc
+ExecStart=test -d /var/lib/xxx
+ExecStart=test -d /var/lib/xxx/yyy
+ExecStart=test -d /var/lib/xxx/zzz
+ExecStart=test -L /var/lib/aaa/111
+ExecStart=test -L /var/lib/aaa/222
+ExecStart=test -L /var/lib/aaa/333
+
+ExecStart=touch /var/lib/waldo/hoge
+ExecStart=touch /var/lib/quux/pief/hoge
+ExecStart=touch /var/lib/aaa/hoge
+ExecStart=touch /var/lib/aaa/bbb/hoge
+ExecStart=touch /var/lib/aaa/ccc/hoge
+ExecStart=touch /var/lib/xxx/hoge
+ExecStart=touch /var/lib/xxx/yyy/hoge
+ExecStart=touch /var/lib/xxx/zzz/hoge
+ExecStart=touch /var/lib/aaa/111/foo
+ExecStart=touch /var/lib/aaa/222/foo
+ExecStart=touch /var/lib/aaa/333/foo
+
+ExecStart=test -f /var/lib/waldo/hoge
+ExecStart=test -f /var/lib/quux/pief/hoge
+ExecStart=test -f /var/lib/aaa/hoge
+ExecStart=test -f /var/lib/aaa/bbb/hoge
+ExecStart=test -f /var/lib/aaa/ccc/hoge
+ExecStart=test -f /var/lib/xxx/hoge
+ExecStart=test -f /var/lib/xxx/yyy/hoge
+ExecStart=test -f /var/lib/xxx/zzz/hoge
+ExecStart=test -f /var/lib/aaa/111/foo
+ExecStart=test -f /var/lib/aaa/222/foo
+ExecStart=test -f /var/lib/aaa/333/foo
+ExecStart=test -f /var/lib/xxx/foo
+ExecStart=test -f /var/lib/xxx/yyy/foo
+ExecStart=test -f /var/lib/xxx/zzz/foo
+
+ExecStart=test -f /var/lib/private/waldo/hoge
+ExecStart=test -f /var/lib/private/quux/pief/hoge
+ExecStart=test -f /var/lib/private/aaa/hoge
+ExecStart=test -f /var/lib/private/aaa/bbb/hoge
+ExecStart=test -f /var/lib/private/aaa/ccc/hoge
+ExecStart=test -f /var/lib/private/xxx/hoge
+ExecStart=test -f /var/lib/private/xxx/yyy/hoge
+ExecStart=test -f /var/lib/private/xxx/zzz/hoge
+ExecStart=test -f /var/lib/private/aaa/111/foo
+ExecStart=test -f /var/lib/private/aaa/222/foo
+ExecStart=test -f /var/lib/private/aaa/333/foo
+ExecStart=test -f /var/lib/private/xxx/foo
+ExecStart=test -f /var/lib/private/xxx/yyy/foo
+ExecStart=test -f /var/lib/private/xxx/zzz/foo
+
+ExecStart=sh -x -c 'test "$$STATE_DIRECTORY" = "%S/aaa:%S/aaa/bbb:%S/aaa/ccc:%S/quux/pief:%S/waldo:%S/xxx:%S/xxx/yyy:%S/xxx/zzz"'
 
 Type=oneshot
 DynamicUser=yes
-StateDirectory=waldo quux/pief
+StateDirectory=waldo quux/pief aaa/bbb aaa aaa/ccc xxx/yyy:aaa/111 xxx:aaa/222 xxx/zzz:aaa/333
index e6171beaa6205b6743613f530aaae39d6a914334..beaf3ba31eae9e873711de30675beddd799f42fe 100755 (executable)
@@ -5,17 +5,22 @@ set -o pipefail
 
 systemd-analyze log-level debug
 
-function test_directory() {
+test_directory() {
     local directory="$1"
     local path="$2"
 
+    # cleanup for previous invocation
+    for i in xxx xxx2 yyy zzz x:yz x:yz2; do
+        rm -rf "${path:?}/${i}" "${path:?}/private/${i}"
+    done
+
     # Set everything up without DynamicUser=1
 
     systemd-run --wait -p RuntimeDirectoryPreserve=yes -p DynamicUser=0 -p "${directory}"=zzz touch "${path}"/zzz/test
     systemd-run --wait -p RuntimeDirectoryPreserve=yes -p DynamicUser=0 -p "${directory}"=zzz test -f "${path}"/zzz/test
     systemd-run --wait -p RuntimeDirectoryPreserve=yes -p DynamicUser=0 -p "${directory}"=zzz -p TemporaryFileSystem="${path}" test -f "${path}"/zzz/test
     systemd-run --wait -p RuntimeDirectoryPreserve=yes -p DynamicUser=0 -p "${directory}"=zzz:yyy test -f "${path}"/yyy/test
-    systemd-run --wait -p RuntimeDirectoryPreserve=yes -p DynamicUser=0 -p "${directory}"=zzz:xxx -p TemporaryFileSystem="${path}" test -f "${path}"/xxx/test
+    systemd-run --wait -p RuntimeDirectoryPreserve=yes -p DynamicUser=0 -p "${directory}=zzz:xxx zzz:xxx2" -p TemporaryFileSystem="${path}" bash -c "test -f ${path}/xxx/test && test -f ${path}/xxx2/test"
     systemd-run --wait -p RuntimeDirectoryPreserve=yes -p DynamicUser=0 -p "${directory}"=zzz:xxx -p TemporaryFileSystem="${path}":ro test -f "${path}"/xxx/test
     systemd-run --wait -p RuntimeDirectoryPreserve=yes -p DynamicUser=0 -p "${directory}"=zzz test -f "${path}"/zzz/test-missing \
         && { echo 'unexpected success'; exit 1; }
@@ -23,27 +28,40 @@ function test_directory() {
     test -d "${path}"/zzz
     test ! -L "${path}"/zzz
     test ! -e "${path}"/private/zzz
+
+    test ! -e "${path}"/xxx
+    test ! -e "${path}"/private/xxx
+    test ! -e "${path}"/xxx2
+    test ! -e "${path}"/private/xxx2
+    test -L "${path}"/yyy
+    test ! -e "${path}"/private/yyy
+
     test -f "${path}"/zzz/test
-    test ! -f "${path}"/zzz/test-missing
+    test ! -e "${path}"/zzz/test-missing
 
     # Convert to DynamicUser=1
 
     systemd-run --wait -p RuntimeDirectoryPreserve=yes -p DynamicUser=1 -p "${directory}"=zzz test -f "${path}"/zzz/test
     systemd-run --wait -p RuntimeDirectoryPreserve=yes -p DynamicUser=1 -p "${directory}"=zzz -p TemporaryFileSystem="${path}" test -f "${path}"/zzz/test
     systemd-run --wait -p RuntimeDirectoryPreserve=yes -p DynamicUser=1 -p "${directory}"=zzz:yyy test -f "${path}"/yyy/test
-    systemd-run --wait -p RuntimeDirectoryPreserve=yes -p DynamicUser=1 -p "${directory}"=zzz:xxx -p TemporaryFileSystem="${path}" test -f "${path}"/xxx/test
+    systemd-run --wait -p RuntimeDirectoryPreserve=yes -p DynamicUser=1 -p "${directory}=zzz:xxx zzz:xxx2" \
+                -p TemporaryFileSystem="${path}" -p EnvironmentFile=-/usr/lib/systemd/systemd-asan-env bash -c "test -f ${path}/xxx/test && test -f ${path}/xxx2/test"
     systemd-run --wait -p RuntimeDirectoryPreserve=yes -p DynamicUser=1 -p "${directory}"=zzz:xxx -p TemporaryFileSystem="${path}":ro test -f "${path}"/xxx/test
     systemd-run --wait -p RuntimeDirectoryPreserve=yes -p DynamicUser=1 -p "${directory}"=zzz test -f "${path}"/zzz/test-missing \
         && { echo 'unexpected success'; exit 1; }
 
     test -L "${path}"/zzz
-    test -L "${path}"/yyy
     test -d "${path}"/private/zzz
-    test ! -L "${path}"/private/xxx
-    test ! -L "${path}"/xxx
+
+    test ! -e "${path}"/xxx
+    test ! -e "${path}"/private/xxx
+    test ! -e "${path}"/xxx2
+    test ! -e "${path}"/private/xxx2
+    test -L "${path}"/yyy # previous symlink is not removed
+    test ! -e "${path}"/private/yyy
 
     test -f "${path}"/zzz/test
-    test ! -f "${path}"/zzz/test-missing
+    test ! -e "${path}"/zzz/test-missing
 
     # Convert back
 
@@ -56,6 +74,20 @@ function test_directory() {
     systemd-run --wait -p RuntimeDirectoryPreserve=yes -p DynamicUser=0 -p "${directory}"=zzz test -f "${path}"/zzz/test-missing \
         && { echo 'unexpected success'; exit 1; }
 
+    test -d "${path}"/zzz
+    test ! -L "${path}"/zzz
+    test ! -e "${path}"/private/zzz
+
+    test ! -e "${path}"/xxx
+    test ! -e "${path}"/private/xxx
+    test ! -e "${path}"/xxx2
+    test ! -e "${path}"/private/xxx2
+    test -L "${path}"/yyy
+    test ! -e "${path}"/private/yyy
+
+    test -f "${path}"/zzz/test
+    test ! -e "${path}"/zzz/test-missing
+
     # Exercise the unit parsing paths too
     cat >/run/systemd/system/testservice-34.service <<EOF
 [Service]
@@ -71,24 +103,61 @@ EOF
     systemctl start --wait testservice-34.service
 
     test -d "${path}"/zzz
-    test ! -L "${path}"/xxx
-    test ! -L "${path}"/xxx2
-    test ! -L "${path}"/private/xxx
-    test ! -L "${path}"/private/xxx2
-    test -L "${path}"/yyy
     test ! -L "${path}"/zzz
     test ! -e "${path}"/private/zzz
-    test -f "${path}"/zzz/test
-    test ! -f "${path}"/zzz/test-missing
+
     test ! -L "${path}"/x:yz
     test ! -L "${path}"/x:yz2
 }
 
+test_check_writable() {
+    # cleanup for previous invocation
+    for i in aaa quux waldo xxx; do
+        rm -rf "/var/lib/$i" "/var/lib/private/$i"
+    done
+
+    cat >/run/systemd/system/testservice-34-check-writable.service <<EOF
+[Unit]
+Description=Check writable directories when DynamicUser= with StateDirectory=
+
+[Service]
+# Relevant only for sanitizer runs
+EnvironmentFile=-/usr/lib/systemd/systemd-asan-env
+
+Type=oneshot
+DynamicUser=yes
+StateDirectory=waldo quux/pief aaa/bbb aaa aaa/ccc xxx/yyy:aaa/111 xxx:aaa/222 xxx/zzz:aaa/333
+
+# Make sure that the state directories are really the only writable directory besides the obvious candidates
+ExecStart=bash -c ' \
+    set -eux; \
+    set -o pipefail; \
+    declare -a writable_dirs; \
+    readarray -t writable_dirs < <(find / \\( -path /var/tmp -o -path /tmp -o -path /proc -o -path /dev/mqueue -o -path /dev/shm -o \
+                                              -path /sys/fs/bpf -o -path /dev/.lxc -o -path /sys/devices/system/cpu \\) \
+                                   -prune -o -type d -writable -print 2>/dev/null | sort -u); \
+    [[ "\$\${#writable_dirs[@]}" == "8" ]]; \
+    [[ "\$\${writable_dirs[0]}" == "/var/lib/private/aaa" ]]; \
+    [[ "\$\${writable_dirs[1]}" == "/var/lib/private/aaa/bbb" ]]; \
+    [[ "\$\${writable_dirs[2]}" == "/var/lib/private/aaa/ccc" ]]; \
+    [[ "\$\${writable_dirs[3]}" == "/var/lib/private/quux/pief" ]]; \
+    [[ "\$\${writable_dirs[4]}" == "/var/lib/private/waldo" ]]; \
+    [[ "\$\${writable_dirs[5]}" == "/var/lib/private/xxx" ]]; \
+    [[ "\$\${writable_dirs[6]}" == "/var/lib/private/xxx/yyy" ]]; \
+    [[ "\$\${writable_dirs[7]}" == "/var/lib/private/xxx/zzz" ]]; \
+'
+EOF
+    systemctl daemon-reload
+    systemctl start testservice-34-check-writable.service
+}
+
 test_directory "StateDirectory" "/var/lib"
 test_directory "RuntimeDirectory" "/run"
 test_directory "CacheDirectory" "/var/cache"
 test_directory "LogsDirectory" "/var/log"
 
+test_check_writable
+
 systemd-analyze log-level info
 
 echo OK >/testok