]>
Commit | Line | Data |
---|---|---|
8b3d4ff0 | 1 | #!/bin/bash |
ea0999c9 | 2 | # SPDX-License-Identifier: LGPL-2.1-or-later |
6e866b33 MB |
3 | # |
4 | # Basic tests for types creating/writing files | |
8b3d4ff0 MB |
5 | set -eux |
6 | set -o pipefail | |
6e866b33 MB |
7 | |
8 | rm -fr /tmp/{f,F,w} | |
9 | mkdir /tmp/{f,F,w} | |
10 | touch /tmp/file-owned-by-root | |
11 | ||
12 | # | |
13 | # 'f' | |
14 | # | |
15 | systemd-tmpfiles --create - <<EOF | |
16 | f /tmp/f/1 0644 - - - - | |
17 | f /tmp/f/2 0644 - - - This string should be written | |
18 | EOF | |
19 | ||
20 | ### '1' should exist and be empty | |
8b3d4ff0 MB |
21 | test -f /tmp/f/1; test ! -s /tmp/f/1 |
22 | test "$(stat -c %U:%G:%a /tmp/f/1)" = "root:root:644" | |
6e866b33 | 23 | |
8b3d4ff0 | 24 | test "$(stat -c %U:%G:%a /tmp/f/2)" = "root:root:644" |
6e866b33 MB |
25 | test "$(< /tmp/f/2)" = "This string should be written" |
26 | ||
27 | ### The perms are supposed to be updated even if the file already exists. | |
28 | systemd-tmpfiles --create - <<EOF | |
29 | f /tmp/f/1 0666 daemon daemon - This string should not be written | |
30 | EOF | |
31 | ||
32 | # file should be empty | |
8b3d4ff0 MB |
33 | test ! -s /tmp/f/1 |
34 | test "$(stat -c %U:%G:%a /tmp/f/1)" = "daemon:daemon:666" | |
6e866b33 MB |
35 | |
36 | ### But we shouldn't try to set perms on an existing file which is not a | |
37 | ### regular one. | |
38 | mkfifo /tmp/f/fifo | |
39 | chmod 644 /tmp/f/fifo | |
40 | ||
ecfb185f | 41 | (! systemd-tmpfiles --create -) <<EOF |
6e866b33 MB |
42 | f /tmp/f/fifo 0666 daemon daemon - This string should not be written |
43 | EOF | |
44 | ||
45 | test -p /tmp/f/fifo | |
8b3d4ff0 | 46 | test "$(stat -c %U:%G:%a /tmp/f/fifo)" = "root:root:644" |
6e866b33 MB |
47 | |
48 | ### 'f' should not follow symlinks. | |
49 | ln -s missing /tmp/f/dangling | |
50 | ln -s /tmp/file-owned-by-root /tmp/f/symlink | |
51 | ||
ecfb185f | 52 | (! systemd-tmpfiles --create -) <<EOF |
6e866b33 MB |
53 | f /tmp/f/dangling 0644 daemon daemon - - |
54 | f /tmp/f/symlink 0644 daemon daemon - - | |
55 | EOF | |
8b3d4ff0 MB |
56 | test ! -e /tmp/f/missing |
57 | test "$(stat -c %U:%G:%a /tmp/file-owned-by-root)" = "root:root:644" | |
6e866b33 MB |
58 | |
59 | ### Handle read-only filesystem gracefully: we shouldn't fail if the target | |
60 | ### already exists and have the correct perms. | |
61 | mkdir /tmp/f/rw-fs | |
62 | mkdir /tmp/f/ro-fs | |
63 | ||
64 | touch /tmp/f/rw-fs/foo | |
65 | chmod 644 /tmp/f/rw-fs/foo | |
66 | ||
67 | mount -o bind,ro /tmp/f/rw-fs /tmp/f/ro-fs | |
68 | ||
69 | systemd-tmpfiles --create - <<EOF | |
70 | f /tmp/f/ro-fs/foo 0644 - - - - This string should not be written | |
71 | EOF | |
8b3d4ff0 | 72 | test -f /tmp/f/ro-fs/foo; test ! -s /tmp/f/ro-fs/foo |
6e866b33 | 73 | |
ecfb185f | 74 | (! systemd-tmpfiles --create -) <<EOF |
6e866b33 MB |
75 | f /tmp/f/ro-fs/foo 0666 - - - - |
76 | EOF | |
8b3d4ff0 | 77 | test "$(stat -c %U:%G:%a /tmp/f/fifo)" = "root:root:644" |
6e866b33 | 78 | |
ecfb185f | 79 | (! systemd-tmpfiles --create -) <<EOF |
6e866b33 MB |
80 | f /tmp/f/ro-fs/bar 0644 - - - - |
81 | EOF | |
8b3d4ff0 | 82 | test ! -e /tmp/f/ro-fs/bar |
6e866b33 MB |
83 | |
84 | ### 'f' shouldn't follow unsafe paths. | |
85 | mkdir /tmp/f/daemon | |
86 | ln -s /root /tmp/f/daemon/unsafe-symlink | |
87 | chown -R --no-dereference daemon:daemon /tmp/f/daemon | |
88 | ||
ecfb185f | 89 | (! systemd-tmpfiles --create -) <<EOF |
6e866b33 MB |
90 | f /tmp/f/daemon/unsafe-symlink/exploit 0644 daemon daemon - - |
91 | EOF | |
8b3d4ff0 | 92 | test ! -e /tmp/f/daemon/unsafe-symlink/exploit |
6e866b33 MB |
93 | |
94 | # | |
95 | # 'F' | |
96 | # | |
97 | echo "This should be truncated" >/tmp/F/truncated | |
98 | echo "This should be truncated" >/tmp/F/truncated-with-content | |
99 | ||
100 | systemd-tmpfiles --create - <<EOF | |
101 | F /tmp/F/created 0644 - - - - | |
102 | F /tmp/F/created-with-content 0644 - - - new content | |
103 | F /tmp/F/truncated 0666 daemon daemon - - | |
104 | F /tmp/F/truncated-with-content 0666 daemon daemon - new content | |
105 | EOF | |
106 | ||
8b3d4ff0 | 107 | test -f /tmp/F/created; test ! -s /tmp/F/created |
6e866b33 MB |
108 | test -f /tmp/F/created-with-content |
109 | test "$(< /tmp/F/created-with-content)" = "new content" | |
8b3d4ff0 MB |
110 | test -f /tmp/F/truncated; test ! -s /tmp/F/truncated |
111 | test "$(stat -c %U:%G:%a /tmp/F/truncated)" = "daemon:daemon:666" | |
6e866b33 | 112 | test -s /tmp/F/truncated-with-content |
8b3d4ff0 | 113 | test "$(stat -c %U:%G:%a /tmp/F/truncated-with-content)" = "daemon:daemon:666" |
6e866b33 MB |
114 | |
115 | ### We shouldn't try to truncate anything but regular files since the behavior is | |
116 | ### unspecified in the other cases. | |
117 | mkfifo /tmp/F/fifo | |
118 | ||
ecfb185f | 119 | (! systemd-tmpfiles --create -) <<EOF |
6e866b33 MB |
120 | F /tmp/F/fifo 0644 - - - - |
121 | EOF | |
122 | ||
123 | test -p /tmp/F/fifo | |
124 | ||
125 | ### 'F' should not follow symlinks. | |
126 | ln -s missing /tmp/F/dangling | |
127 | ln -s /tmp/file-owned-by-root /tmp/F/symlink | |
128 | ||
ecfb185f | 129 | (! systemd-tmpfiles --create -) <<EOF |
6e866b33 MB |
130 | f /tmp/F/dangling 0644 daemon daemon - - |
131 | f /tmp/F/symlink 0644 daemon daemon - - | |
132 | EOF | |
8b3d4ff0 MB |
133 | test ! -e /tmp/F/missing |
134 | test "$(stat -c %U:%G:%a /tmp/file-owned-by-root)" = "root:root:644" | |
6e866b33 MB |
135 | |
136 | ### Handle read-only filesystem gracefully: we shouldn't fail if the target | |
137 | ### already exists and is empty. | |
138 | mkdir /tmp/F/rw-fs | |
139 | mkdir /tmp/F/ro-fs | |
140 | ||
141 | touch /tmp/F/rw-fs/foo | |
142 | chmod 644 /tmp/F/rw-fs/foo | |
143 | ||
144 | mount -o bind,ro /tmp/F/rw-fs /tmp/F/ro-fs | |
145 | ||
146 | systemd-tmpfiles --create - <<EOF | |
147 | F /tmp/F/ro-fs/foo 0644 - - - - | |
148 | EOF | |
8b3d4ff0 | 149 | test -f /tmp/F/ro-fs/foo; test ! -s /tmp/F/ro-fs/foo |
6e866b33 MB |
150 | |
151 | echo "truncating is not allowed anymore" >/tmp/F/rw-fs/foo | |
ecfb185f | 152 | (! systemd-tmpfiles --create -) <<EOF |
6e866b33 MB |
153 | F /tmp/F/ro-fs/foo 0644 - - - - |
154 | EOF | |
155 | ||
ecfb185f | 156 | (! systemd-tmpfiles --create -) <<EOF |
6e866b33 MB |
157 | F /tmp/F/ro-fs/foo 0644 - - - - This string should not be written |
158 | EOF | |
8b3d4ff0 MB |
159 | test -f /tmp/F/ro-fs/foo |
160 | grep -q 'truncating is not allowed' /tmp/F/ro-fs/foo | |
6e866b33 MB |
161 | |
162 | # Trying to change the perms should fail. | |
8b3d4ff0 | 163 | : >/tmp/F/rw-fs/foo |
ecfb185f | 164 | (! systemd-tmpfiles --create -) <<EOF |
6e866b33 MB |
165 | F /tmp/F/ro-fs/foo 0666 - - - - |
166 | EOF | |
8b3d4ff0 | 167 | test "$(stat -c %U:%G:%a /tmp/F/ro-fs/foo)" = "root:root:644" |
6e866b33 MB |
168 | |
169 | ### Try to create a new file. | |
ecfb185f | 170 | (! systemd-tmpfiles --create -) <<EOF |
6e866b33 MB |
171 | F /tmp/F/ro-fs/bar 0644 - - - - |
172 | EOF | |
8b3d4ff0 | 173 | test ! -e /tmp/F/ro-fs/bar |
6e866b33 MB |
174 | |
175 | ### 'F' shouldn't follow unsafe paths. | |
176 | mkdir /tmp/F/daemon | |
177 | ln -s /root /tmp/F/daemon/unsafe-symlink | |
178 | chown -R --no-dereference daemon:daemon /tmp/F/daemon | |
179 | ||
ecfb185f | 180 | (! systemd-tmpfiles --create -) <<EOF |
6e866b33 MB |
181 | F /tmp/F/daemon/unsafe-symlink/exploit 0644 daemon daemon - - |
182 | EOF | |
8b3d4ff0 | 183 | test ! -e /tmp/F/daemon/unsafe-symlink/exploit |
6e866b33 MB |
184 | |
185 | # | |
186 | # 'w' | |
187 | # | |
188 | touch /tmp/w/overwritten | |
8f232108 | 189 | touch /tmp/w/appended |
6e866b33 MB |
190 | |
191 | ### nop if the target does not exist. | |
192 | systemd-tmpfiles --create - <<EOF | |
193 | w /tmp/w/unexistent 0644 - - - new content | |
194 | EOF | |
8b3d4ff0 | 195 | test ! -e /tmp/w/unexistent |
6e866b33 MB |
196 | |
197 | ### no argument given -> fails. | |
ecfb185f | 198 | (! systemd-tmpfiles --create -) <<EOF |
6e866b33 MB |
199 | w /tmp/w/unexistent 0644 - - - - |
200 | EOF | |
201 | ||
202 | ### write into an empty file. | |
203 | systemd-tmpfiles --create - <<EOF | |
204 | w /tmp/w/overwritten 0644 - - - old content | |
205 | EOF | |
206 | test -f /tmp/w/overwritten | |
207 | test "$(< /tmp/w/overwritten)" = "old content" | |
208 | ||
8f232108 | 209 | ### old content is overwritten |
6e866b33 MB |
210 | systemd-tmpfiles --create - <<EOF |
211 | w /tmp/w/overwritten 0644 - - - new content | |
212 | EOF | |
213 | test -f /tmp/w/overwritten | |
214 | test "$(< /tmp/w/overwritten)" = "new content" | |
215 | ||
8f232108 MB |
216 | ### append lines |
217 | systemd-tmpfiles --create - <<EOF | |
218 | w+ /tmp/w/appended 0644 - - - 1 | |
219 | w+ /tmp/w/appended 0644 - - - 2\n | |
220 | w+ /tmp/w/appended 0644 - - - 3 | |
221 | EOF | |
222 | test -f /tmp/w/appended | |
223 | test "$(< /tmp/w/appended)" = "$(echo -ne '12\n3')" | |
224 | ||
f2dec872 | 225 | ### writing into an 'exotic' file should be allowed. |
6e866b33 MB |
226 | systemd-tmpfiles --create - <<EOF |
227 | w /dev/null - - - - new content | |
228 | EOF | |
229 | ||
230 | ### 'w' follows symlinks | |
231 | ln -s ./overwritten /tmp/w/symlink | |
232 | systemd-tmpfiles --create - <<EOF | |
233 | w /tmp/w/symlink - - - - $(readlink -e /tmp/w/symlink) | |
234 | EOF | |
235 | readlink -e /tmp/w/symlink | |
236 | test "$(< /tmp/w/overwritten)" = "/tmp/w/overwritten" | |
237 | ||
238 | ### 'w' shouldn't follow unsafe paths. | |
239 | mkdir /tmp/w/daemon | |
240 | ln -s /root /tmp/w/daemon/unsafe-symlink | |
241 | chown -R --no-dereference daemon:daemon /tmp/w/daemon | |
242 | ||
ecfb185f | 243 | (! systemd-tmpfiles --create -) <<EOF |
6e866b33 MB |
244 | f /tmp/w/daemon/unsafe-symlink/exploit 0644 daemon daemon - - |
245 | EOF | |
8b3d4ff0 | 246 | test ! -e /tmp/w/daemon/unsafe-symlink/exploit |