2 # SPDX-License-Identifier: LGPL-2.1-or-later
6 systemd-analyze log-level debug
12 # cleanup for previous invocation
13 for i
in xxx xxx2 yyy zzz x
:yz x
:yz2
; do
14 rm -rf "${path:?}/${i}" "${path:?}/private/${i}"
17 # Set everything up without DynamicUser=1
19 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=0 -p "${directory}"=zzz
touch "${path}"/zzz
/test
20 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=0 -p "${directory}"=zzz
test -f "${path}"/zzz
/test
21 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=0 -p "${directory}"=zzz -p TemporaryFileSystem="${path}" test -f "${path}"/zzz
/test
22 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=0 -p "${directory}"=zzz
:yyy
test -f "${path}"/yyy
/test
23 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"
24 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=0 -p "${directory}"=zzz:xxx -p TemporaryFileSystem="${path}":ro test -f "${path}"/xxx
/test
25 (! systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=0 -p "${directory}"=zzz
test -f "${path}"/zzz
/test-missing
)
26 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=0 -p "${directory}"="www::ro www:ro:ro" test -d "${path}"/www
27 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=0 -p "${directory}"="www::ro www:ro:ro" test -L "${path}"/ro
28 (! systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=0 -p "${directory}"="www::ro www:ro:ro" sh
-c "echo foo > ${path}/www/test-missing")
31 test ! -L "${path}"/zzz
32 test ! -e "${path}"/private
/zzz
34 test ! -e "${path}"/xxx
35 test ! -e "${path}"/private
/xxx
36 test ! -e "${path}"/xxx2
37 test ! -e "${path}"/private
/xxx2
39 test ! -e "${path}"/private
/yyy
41 test -f "${path}"/zzz
/test
42 test ! -e "${path}"/zzz
/test-missing
44 # Convert to DynamicUser=1
46 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=1 -p "${directory}"=zzz
test -f "${path}"/zzz
/test
47 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=1 -p "${directory}"=zzz -p TemporaryFileSystem="${path}" test -f "${path}"/zzz
/test
48 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=1 -p "${directory}"=zzz
:yyy
test -f "${path}"/yyy
/test
49 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=1 -p "${directory}=zzz:xxx zzz:xxx2" \
50 -p TemporaryFileSystem
="${path}" -p EnvironmentFile=-/usr/lib/systemd/systemd-asan-env bash -c "test -f ${path}/xxx/test && test -f ${path}/xxx2/test"
51 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=1 -p "${directory}"=zzz:xxx -p TemporaryFileSystem="${path}":ro test -f "${path}"/xxx
/test
52 (! systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=1 -p "${directory}"=zzz
test -f "${path}"/zzz
/test-missing
)
53 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=1 -p "${directory}"="www::ro www:ro:ro" test -d "${path}"/www
54 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=1 -p "${directory}"="www::ro www:ro:ro" test -L "${path}"/ro
55 (! systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=1 -p "${directory}"="www::ro www:ro:ro" sh
-c "echo foo > ${path}/www/test-missing")
58 test -d "${path}"/private
/zzz
60 test ! -e "${path}"/xxx
61 test ! -e "${path}"/private
/xxx
62 test ! -e "${path}"/xxx2
63 test ! -e "${path}"/private
/xxx2
64 test -L "${path}"/yyy
# previous symlink is not removed
65 test ! -e "${path}"/private
/yyy
67 test -f "${path}"/zzz
/test
68 test ! -e "${path}"/zzz
/test-missing
72 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=0 -p "${directory}"=zzz
test -f "${path}"/zzz
/test
73 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=0 -p "${directory}"=zzz -p TemporaryFileSystem="${path}" test -f "${path}"/zzz
/test
74 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=0 -p "${directory}"=zzz
:yyy
test -f "${path}"/yyy
/test
75 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=0 -p "${directory}"=zzz:xxx -p TemporaryFileSystem="${path}" test -f "${path}"/xxx
/test
76 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"
77 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=0 -p "${directory}"=zzz:xxx -p TemporaryFileSystem="${path}":ro test -f "${path}"/xxx
/test
78 (! systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=0 -p "${directory}"=zzz
test -f "${path}"/zzz
/test-missing
)
79 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=0 -p "${directory}"="www::ro www:ro:ro" test -d "${path}"/www
80 systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=0 -p "${directory}"="www::ro www:ro:ro" test -L "${path}"/ro
81 (! systemd-run
--wait -p RuntimeDirectoryPreserve
=yes -p DynamicUser
=0 -p "${directory}"="www::ro www:ro:ro" sh
-c "echo foo > ${path}/www/test-missing")
84 test ! -L "${path}"/zzz
85 test ! -e "${path}"/private
/zzz
87 test ! -e "${path}"/xxx
88 test ! -e "${path}"/private
/xxx
89 test ! -e "${path}"/xxx2
90 test ! -e "${path}"/private
/xxx2
92 test ! -e "${path}"/private
/yyy
94 test -f "${path}"/zzz
/test
95 test ! -e "${path}"/zzz
/test-missing
97 test ! -e "${path}"/www
/test-missing
99 # Exercise the unit parsing paths too
100 cat >/run
/systemd
/system
/testservice-34.service
<<EOF
103 TemporaryFileSystem=${path}
104 RuntimeDirectoryPreserve=yes
105 ${directory}=zzz:x\:yz zzz:x\:yz2 www::ro www:ro:ro
106 ExecStart=test -f ${path}/x:yz2/test
107 ExecStart=test -f ${path}/x:yz/test
108 ExecStart=test -f ${path}/zzz/test
109 ExecStart=test -d ${path}/www
110 ExecStart=test -L ${path}/ro
111 ExecStart=sh -c "! test -w ${path}/www"
113 systemctl daemon-reload
114 systemctl start
--wait testservice-34.service
116 test -d "${path}"/zzz
117 test ! -L "${path}"/zzz
118 test ! -e "${path}"/private
/zzz
120 test ! -L "${path}"/x
:yz
121 test ! -L "${path}"/x
:yz2
124 test_check_writable
() {
125 # cleanup for previous invocation
126 for i
in aaa quux waldo xxx
; do
127 rm -rf "/var/lib/$i" "/var/lib/private/$i"
130 cat >/run
/systemd
/system
/testservice-34-check-writable.service
<<\EOF
132 Description
=Check writable directories when DynamicUser
= with StateDirectory
=
135 # Relevant only for sanitizer runs
136 EnvironmentFile
=-/usr
/lib
/systemd
/systemd-asan-env
140 StateDirectory
=waldo quux
/pief aaa
/bbb aaa aaa
/ccc xxx
/yyy
:aaa
/111 xxx
:aaa
/222 xxx
/zzz
:aaa
/333
142 # Make sure that the state directories are really the only writable directory besides the obvious candidates
143 ExecStart
=bash
-c ' \
146 declare -a writable_dirs; \
147 readarray -t writable_dirs < <(find / \( -path /var/tmp -o -path /tmp -o -path /proc -o -path /dev/mqueue -o -path /dev/shm -o \
148 -path /sys/fs/bpf -o -path /dev/.lxc -o -path /sys/devices/system/cpu \) \
149 -prune -o -type d -writable -print 2>/dev/null | sort -u); \
150 [[ "$${#writable_dirs[@]}" == "8" ]]; \
151 [[ "$${writable_dirs[0]}" == "/var/lib/private/aaa" ]]; \
152 [[ "$${writable_dirs[1]}" == "/var/lib/private/aaa/bbb" ]]; \
153 [[ "$${writable_dirs[2]}" == "/var/lib/private/aaa/ccc" ]]; \
154 [[ "$${writable_dirs[3]}" == "/var/lib/private/quux/pief" ]]; \
155 [[ "$${writable_dirs[4]}" == "/var/lib/private/waldo" ]]; \
156 [[ "$${writable_dirs[5]}" == "/var/lib/private/xxx" ]]; \
157 [[ "$${writable_dirs[6]}" == "/var/lib/private/xxx/yyy" ]]; \
158 [[ "$${writable_dirs[7]}" == "/var/lib/private/xxx/zzz" ]]; \
161 systemctl daemon-reload
162 systemctl start testservice-34-check-writable.service
165 test_check_idmapped_mounts
() {
166 rm -rf /var
/lib
/testidmapped
/var
/lib
/private
/testidmapped
168 cat >/run
/systemd
/system
/testservice-34-check-idmapped.service
<<\EOF
170 Description
=Check id-mapped directories when DynamicUser
=yes with StateDirectory
173 # Relevant only for sanitizer runs
174 EnvironmentFile
=-/usr
/lib
/systemd
/systemd-asan-env
180 TemporaryFileSystem
=/run
/var
/opt
/var
/lib
/vol
182 StateDirectory
=testidmapped
:sampleservice
183 ExecStart
=/bin
/bash
-c ' \
186 touch /var/lib/sampleservice/testfile; \
187 [[ $(awk "NR==2 {print \$1}" /proc/self/uid_map) == $(stat -c "%%u" /var/lib/private/testidmapped/testfile) ]]; \
191 systemctl daemon-reload
192 systemctl start testservice-34-check-idmapped.service
194 [[ $
(stat
-c "%u" /var
/lib
/private
/testidmapped
/testfile
) == 65534 ]]
197 test_check_idmapped_mounts_root
() {
198 rm -rf /var
/lib
/testidmapped
/var
/lib
/private
/testidmapped
200 cat >/run
/systemd
/system
/testservice-34-check-idmapped.service
<<\EOF
202 Description
=Check id-mapped directories when DynamicUser
=no with StateDirectory
205 # Relevant only for sanitizer runs
206 EnvironmentFile
=-/usr
/lib
/systemd
/systemd-asan-env
213 TemporaryFileSystem
=/run
/var
/opt
/var
/lib
/vol
215 StateDirectory
=testidmapped
:sampleservice
216 ExecStart
=/bin
/bash
-c ' \
219 touch /var/lib/sampleservice/testfile; \
220 [[ 0 == $(stat -c "%%u" /var/lib/testidmapped/testfile) ]]; \
224 systemctl daemon-reload
225 systemctl start testservice-34-check-idmapped.service
227 [[ $
(stat
-c "%u" /var
/lib
/testidmapped
/testfile
) == 0 ]]
230 test_directory
"StateDirectory" "/var/lib"
231 test_directory
"RuntimeDirectory" "/run"
232 test_directory
"CacheDirectory" "/var/cache"
233 test_directory
"LogsDirectory" "/var/log"
237 if systemd-analyze compare-versions
"$(uname -r)" ge
5.12; then
238 test_check_idmapped_mounts
239 test_check_idmapped_mounts_root
242 systemd-analyze log-level info