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