]> git.ipfire.org Git - thirdparty/systemd.git/blob - test/units/testsuite-65.sh
man/systemd.mount: tmpfs automatically gains After=swap.target dep
[thirdparty/systemd.git] / test / units / testsuite-65.sh
1 #!/usr/bin/env bash
2 # SPDX-License-Identifier: LGPL-2.1-or-later
3 # shellcheck disable=SC2016
4 set -eux
5
6 # shellcheck source=test/units/util.sh
7 . "$(dirname "$0")"/util.sh
8
9 systemctl log-level debug
10 export SYSTEMD_LOG_LEVEL=debug
11
12 # Sanity checks
13 #
14 # We can't really test time, critical-chain and plot verbs here, as
15 # the testsuite service is a part of the boot transaction, so let's assume
16 # they fail
17 systemd-analyze || :
18 systemd-analyze time || :
19 systemd-analyze critical-chain || :
20 # blame
21 systemd-analyze blame
22 systemd-run --wait --user --pipe -M testuser@.host systemd-analyze blame
23 # plot
24 systemd-analyze plot >/dev/null || :
25 systemd-analyze plot --json=pretty >/dev/null || :
26 systemd-analyze plot --json=short >/dev/null || :
27 systemd-analyze plot --json=off >/dev/null || :
28 systemd-analyze plot --json=pretty --no-legend >/dev/null || :
29 systemd-analyze plot --json=short --no-legend >/dev/null || :
30 systemd-analyze plot --json=off --no-legend >/dev/null || :
31 systemd-analyze plot --table >/dev/null || :
32 systemd-analyze plot --table --no-legend >/dev/null || :
33 # legacy/deprecated options (moved to systemctl, but still usable from analyze)
34 systemd-analyze log-level
35 systemd-analyze log-level "$(systemctl log-level)"
36 systemd-analyze get-log-level
37 systemd-analyze set-log-level "$(systemctl log-level)"
38 systemd-analyze log-target
39 systemd-analyze log-target "$(systemctl log-target)"
40 systemd-analyze get-log-target
41 systemd-analyze set-log-target "$(systemctl log-target)"
42 systemd-analyze service-watchdogs
43 systemd-analyze service-watchdogs "$(systemctl service-watchdogs)"
44 # dot
45 systemd-analyze dot >/dev/null
46 systemd-analyze dot systemd-journald.service >/dev/null
47 systemd-analyze dot systemd-journald.service systemd-logind.service >/dev/null
48 systemd-analyze dot --from-pattern="*" --from-pattern="*.service" systemd-journald.service >/dev/null
49 systemd-analyze dot --to-pattern="*" --to-pattern="*.service" systemd-journald.service >/dev/null
50 systemd-analyze dot --from-pattern="*.service" --to-pattern="*.service" systemd-journald.service >/dev/null
51 systemd-analyze dot --order systemd-journald.service systemd-logind.service >/dev/null
52 systemd-analyze dot --require systemd-journald.service systemd-logind.service >/dev/null
53 systemd-analyze dot "systemd-*.service" >/dev/null
54 (! systemd-analyze dot systemd-journald.service systemd-logind.service "*" bbb ccc)
55 # dump
56 # this should be rate limited to 10 calls in 10 minutes for unprivileged callers
57 for _ in {1..10}; do
58 runas testuser systemd-analyze dump systemd-journald.service >/dev/null
59 done
60 (! runas testuser systemd-analyze dump >/dev/null)
61 # still limited after a reload
62 systemctl daemon-reload
63 (! runas testuser systemd-analyze dump >/dev/null)
64 # and a re-exec
65 systemctl daemon-reexec
66 (! runas testuser systemd-analyze dump >/dev/null)
67 # privileged call, so should not be rate limited
68 for _ in {1..10}; do
69 systemd-analyze dump systemd-journald.service >/dev/null
70 done
71 systemd-analyze dump >/dev/null
72 systemd-analyze dump "*" >/dev/null
73 systemd-analyze dump "*.socket" >/dev/null
74 systemd-analyze dump "*.socket" "*.service" aaaaaaa ... >/dev/null
75 systemd-analyze dump systemd-journald.service >/dev/null
76 systemd-analyze malloc >/dev/null
77 (! systemd-analyze dump "")
78 # unit-files
79 systemd-analyze unit-files >/dev/null
80 systemd-analyze unit-files systemd-journald.service >/dev/null
81 systemd-analyze unit-files "*" >/dev/null
82 systemd-analyze unit-files "*" aaaaaa "*.service" "*.target" >/dev/null
83 systemd-analyze unit-files --user >/dev/null
84 systemd-analyze unit-files --user "*" aaaaaa "*.service" "*.target" >/dev/null
85 # unit-paths
86 systemd-analyze unit-paths
87 systemd-analyze unit-paths --user
88 systemd-analyze unit-paths --global
89 # exist-status
90 systemd-analyze exit-status
91 systemd-analyze exit-status STDOUT BPF
92 systemd-analyze exit-status 0 1 {63..65}
93 (! systemd-analyze exit-status STDOUT BPF "hello*")
94 # capability
95 systemd-analyze capability
96 systemd-analyze capability cap_chown CAP_KILL
97 systemd-analyze capability 0 1 {30..32}
98 (! systemd-analyze capability cap_chown CAP_KILL "hello*")
99 # condition
100 mkdir -p /run/systemd/system
101 UNIT_NAME="analyze-condition-$RANDOM.service"
102 cat >"/run/systemd/system/$UNIT_NAME" <<EOF
103 [Unit]
104 AssertPathExists=/etc/os-release
105 AssertEnvironment=!FOOBAR
106 ConditionKernelVersion=>1.0
107 ConditionPathExists=/etc/os-release
108
109 [Service]
110 ExecStart=/bin/true
111 EOF
112 systemctl daemon-reload
113 systemd-analyze condition --unit="$UNIT_NAME"
114 systemd-analyze condition 'ConditionKernelVersion = ! <4.0' \
115 'ConditionKernelVersion = >=3.1' \
116 'ConditionACPower=|false' \
117 'ConditionArchitecture=|!arm' \
118 'AssertPathExists=/etc/os-release'
119 (! systemd-analyze condition 'ConditionArchitecture=|!arm' 'AssertXYZ=foo')
120 (! systemd-analyze condition 'ConditionKernelVersion=<1.0')
121 (! systemd-analyze condition 'AssertKernelVersion=<1.0')
122 # syscall-filter
123 systemd-analyze syscall-filter >/dev/null
124 systemd-analyze syscall-filter @chown @sync
125 systemd-analyze syscall-filter @sync @sync @sync
126 (! systemd-analyze syscall-filter @chown @sync @foobar)
127 # filesystems (requires libbpf support)
128 if systemctl --version | grep "+BPF_FRAMEWORK"; then
129 systemd-analyze filesystems >/dev/null
130 systemd-analyze filesystems @basic-api
131 systemd-analyze filesystems @basic-api @basic-api @basic-api
132 (! systemd-analyze filesystems @basic-api @basic-api @foobar @basic-api)
133 fi
134 # calendar
135 systemd-analyze calendar '*-2-29 0:0:0'
136 systemd-analyze calendar --iterations=5 '*-2-29 0:0:0'
137 systemd-analyze calendar '*-* *:*:*'
138 systemd-analyze calendar --iterations=5 '*-* *:*:*'
139 systemd-analyze calendar --iterations=50 '*-* *:*:*'
140 systemd-analyze calendar --iterations=0 '*-* *:*:*'
141 systemd-analyze calendar --iterations=5 '01-01-22 01:00:00'
142 systemd-analyze calendar --base-time=yesterday --iterations=5 '*-* *:*:*'
143 (! systemd-analyze calendar --iterations=0 '*-* 99:*:*')
144 (! systemd-analyze calendar --base-time=never '*-* *:*:*')
145 (! systemd-analyze calendar 1)
146 (! systemd-analyze calendar "")
147 # timestamp
148 systemd-analyze timestamp now
149 systemd-analyze timestamp -- -1
150 systemd-analyze timestamp yesterday now tomorrow
151 (! systemd-analyze timestamp yesterday never tomorrow)
152 (! systemd-analyze timestamp 1)
153 (! systemd-analyze timestamp '*-2-29 0:0:0')
154 (! systemd-analyze timestamp "")
155 # timespan
156 systemd-analyze timespan 1
157 systemd-analyze timespan 1s 300s '1year 0.000001s'
158 (! systemd-analyze timespan 1s 300s aaaaaa '1year 0.000001s')
159 (! systemd-analyze timespan -- -1)
160 (! systemd-analyze timespan '*-2-29 0:0:0')
161 (! systemd-analyze timespan "")
162 # cat-config
163 systemd-analyze cat-config systemd/system.conf >/dev/null
164 systemd-analyze cat-config /etc/systemd/system.conf >/dev/null
165 systemd-analyze cat-config systemd/system.conf systemd/journald.conf >/dev/null
166 systemd-analyze cat-config systemd/system.conf foo/bar systemd/journald.conf >/dev/null
167 systemd-analyze cat-config foo/bar
168 systemd-analyze cat-config --tldr systemd/system.conf >/dev/null
169 systemd-analyze cat-config --tldr /etc/systemd/system.conf >/dev/null
170 systemd-analyze cat-config --tldr systemd/system.conf systemd/journald.conf >/dev/null
171 systemd-analyze cat-config --tldr systemd/system.conf foo/bar systemd/journald.conf >/dev/null
172 systemd-analyze cat-config --tldr foo/bar
173 # security
174 systemd-analyze security
175 systemd-analyze security --json=off
176 systemd-analyze security --json=pretty | jq
177 systemd-analyze security --json=short | jq
178
179 if [[ ! -v ASAN_OPTIONS ]]; then
180 # check that systemd-analyze cat-config paths work in a chroot
181 mkdir -p /tmp/root
182 mount --bind / /tmp/root
183 systemd-analyze cat-config systemd/system-preset >/tmp/out1
184 chroot /tmp/root systemd-analyze cat-config systemd/system-preset >/tmp/out2
185 diff /tmp/out{1,2}
186 fi
187
188 # verify
189 mkdir -p /tmp/img/usr/lib/systemd/system/
190 mkdir -p /tmp/img/opt/
191
192 touch /tmp/img/opt/script0.sh
193 chmod +x /tmp/img/opt/script0.sh
194
195 cat <<EOF >/tmp/img/usr/lib/systemd/system/testfile.service
196 [Service]
197 ExecStart = /opt/script0.sh
198 EOF
199
200 set +e
201 # Default behaviour is to recurse through all dependencies when unit is loaded
202 (! systemd-analyze verify --root=/tmp/img/ testfile.service)
203
204 # As above, recurses through all dependencies when unit is loaded
205 (! systemd-analyze verify --recursive-errors=yes --root=/tmp/img/ testfile.service)
206
207 # Recurses through unit file and its direct dependencies when unit is loaded
208 (! systemd-analyze verify --recursive-errors=one --root=/tmp/img/ testfile.service)
209
210 set -e
211
212 # zero exit status since dependencies are ignored when unit is loaded
213 systemd-analyze verify --recursive-errors=no --root=/tmp/img/ testfile.service
214
215 rm /tmp/img/usr/lib/systemd/system/testfile.service
216
217 cat <<EOF >/tmp/testfile.service
218 [Unit]
219 foo = bar
220
221 [Service]
222 ExecStart = echo hello
223 EOF
224
225 cat <<EOF >/tmp/testfile2.service
226 [Unit]
227 Requires = testfile.service
228
229 [Service]
230 ExecStart = echo hello
231 EOF
232
233 # Zero exit status since no additional dependencies are recursively loaded when the unit file is loaded
234 systemd-analyze verify --recursive-errors=no /tmp/testfile2.service
235
236 set +e
237 # Non-zero exit status since all associated dependencies are recursively loaded when the unit file is loaded
238 (! systemd-analyze verify --recursive-errors=yes /tmp/testfile2.service)
239 set -e
240
241 rm /tmp/testfile.service
242 rm /tmp/testfile2.service
243
244 cat <<EOF >/tmp/sample.service
245 [Unit]
246 Description = A Sample Service
247
248 [Service]
249 ExecStart = echo hello
250 Slice=support.slice
251 EOF
252
253 # Zero exit status since no additional dependencies are recursively loaded when the unit file is loaded
254 systemd-analyze verify --recursive-errors=no /tmp/sample.service
255
256 cat <<EOF >/tmp/testfile.service
257 [Service]
258 ExecStart = echo hello
259 DeviceAllow=/dev/sda
260 EOF
261
262 # Prevent regression from #13380 and #20859 where we can't verify hidden files
263 cp /tmp/testfile.service /tmp/.testfile.service
264
265 systemd-analyze verify /tmp/.testfile.service
266
267 rm /tmp/.testfile.service
268
269 # Alias a unit file's name on disk (see #20061)
270 cp /tmp/testfile.service /tmp/testsrvc
271
272 (! systemd-analyze verify /tmp/testsrvc)
273
274 systemd-analyze verify /tmp/testsrvc:alias.service
275
276 # Zero exit status since the value used for comparison determine exposure to security threats is by default 100
277 systemd-analyze security --offline=true /tmp/testfile.service
278
279 #The overall exposure level assigned to the unit is greater than the set threshold
280 (! systemd-analyze security --threshold=90 --offline=true /tmp/testfile.service)
281
282 # Ensure we print the list of ACLs, see https://github.com/systemd/systemd/issues/23185
283 systemd-analyze security --offline=true /tmp/testfile.service | grep -q -F "/dev/sda"
284
285 rm /tmp/testfile.service
286
287 cat <<EOF >/tmp/img/usr/lib/systemd/system/testfile.service
288 [Service]
289 ExecStart = echo hello
290 PrivateNetwork = yes
291 PrivateDevices = yes
292 PrivateUsers = yes
293 EOF
294
295 # The new overall exposure level assigned to the unit is less than the set thresholds
296 # Verifies that the --offline= option works with --root=
297 systemd-analyze security --threshold=90 --offline=true --root=/tmp/img/ testfile.service
298
299 cat <<EOF >/tmp/foo@.service
300 [Service]
301 ExecStart=ls
302 EOF
303
304 cat <<EOF >/tmp/hoge@test.service
305 [Service]
306 ExecStart=ls
307 EOF
308
309 # issue #30357
310 pushd /tmp
311 systemd-analyze verify foo@bar.service
312 systemd-analyze verify foo@.service
313 systemd-analyze verify hoge@test.service
314 (! systemd-analyze verify hoge@nonexist.service)
315 (! systemd-analyze verify hoge@.service)
316 popd
317 pushd /
318 systemd-analyze verify tmp/foo@bar.service
319 systemd-analyze verify tmp/foo@.service
320 systemd-analyze verify tmp/hoge@test.service
321 (! systemd-analyze verify tmp/hoge@nonexist.service)
322 (! systemd-analyze verify tmp/hoge@.service)
323 popd
324 pushd /usr
325 systemd-analyze verify ../tmp/foo@bar.service
326 systemd-analyze verify ../tmp/foo@.service
327 systemd-analyze verify ../tmp/hoge@test.service
328 (! systemd-analyze verify ../tmp/hoge@nonexist.service)
329 (! systemd-analyze verify ../tmp/hoge@.service)
330 popd
331 systemd-analyze verify /tmp/foo@bar.service
332 systemd-analyze verify /tmp/foo@.service
333 systemd-analyze verify /tmp/hoge@test.service
334 (! systemd-analyze verify /tmp/hoge@nonexist.service)
335 (! systemd-analyze verify /tmp/hoge@.service)
336
337 # Added an additional "INVALID_ID" id to the .json to verify that nothing breaks when input is malformed
338 # The PrivateNetwork id description and weight was changed to verify that 'security' is actually reading in
339 # values from the .json file when required. The default weight for "PrivateNetwork" is 2500, and the new weight
340 # assigned to that id in the .json file is 6000. This increased weight means that when the "PrivateNetwork" key is
341 # set to 'yes' (as above in the case of testfile.service) in the content of the unit file, the overall exposure
342 # level for the unit file should decrease to account for that increased weight.
343 cat <<EOF >/tmp/testfile.json
344 {"UserOrDynamicUser":
345 {"description_bad": "Service runs as root user",
346 "weight": 0,
347 "range": 10
348 },
349 "SupplementaryGroups":
350 {"description_good": "Service has no supplementary groups",
351 "description_bad": "Service runs with supplementary groups",
352 "description_na": "Service runs as root, option does not matter",
353 "weight": 200,
354 "range": 1
355 },
356 "PrivateDevices":
357 {"description_good": "Service has no access to hardware devices",
358 "description_bad": "Service potentially has access to hardware devices",
359 "weight": 1000,
360 "range": 1
361 },
362 "PrivateMounts":
363 {"description_good": "Service cannot install system mounts",
364 "description_bad": "Service may install system mounts",
365 "weight": 1000,
366 "range": 1
367 },
368 "PrivateNetwork":
369 {"description_good": "Service doesn't have access to the host's network",
370 "description_bad": "Service has access to the host's network",
371 "weight": 6000,
372 "range": 1
373 },
374 "PrivateTmp":
375 {"description_good": "Service has no access to other software's temporary files",
376 "description_bad": "Service has access to other software's temporary files",
377 "weight": 1000,
378 "range": 1
379 },
380 "PrivateUsers":
381 {"description_good": "Service does not have access to other users",
382 "description_bad": "Service has access to other users",
383 "weight": 1000,
384 "range": 1
385 },
386 "ProtectControlGroups":
387 {"description_good": "Service cannot modify the control group file system",
388 "description_bad": "Service may modify the control group file system",
389 "weight": 1000,
390 "range": 1
391 },
392 "ProtectKernelModules":
393 {"description_good": "Service cannot load or read kernel modules",
394 "description_bad": "Service may load or read kernel modules",
395 "weight": 1000,
396 "range": 1
397 },
398 "ProtectKernelTunables":
399 {"description_good": "Service cannot alter kernel tunables (/proc/sys, …)",
400 "description_bad": "Service may alter kernel tunables",
401 "weight": 1000,
402 "range": 1
403 },
404 "ProtectKernelLogs":
405 {"description_good": "Service cannot read from or write to the kernel log ring buffer",
406 "description_bad": "Service may read from or write to the kernel log ring buffer",
407 "weight": 1000,
408 "range": 1
409 },
410 "ProtectClock":
411 {"description_good": "Service cannot write to the hardware clock or system clock",
412 "description_bad": "Service may write to the hardware clock or system clock",
413 "weight": 1000,
414 "range": 1
415 },
416 "ProtectHome":
417 {"weight": 1000,
418 "range": 10
419 },
420 "ProtectHostname":
421 {"description_good": "Service cannot change system host/domainname",
422 "description_bad": "Service may change system host/domainname",
423 "weight": 50,
424 "range": 1
425 },
426 "ProtectSystem":
427 {"weight": 1000,
428 "range": 10
429 },
430 "RootDirectoryOrRootImage":
431 {"description_good": "Service has its own root directory/image",
432 "description_bad": "Service runs within the host's root directory",
433 "weight": 200,
434 "range": 1
435 },
436 "LockPersonality":
437 {"description_good": "Service cannot change ABI personality",
438 "description_bad": "Service may change ABI personality",
439 "weight": 100,
440 "range": 1
441 },
442 "MemoryDenyWriteExecute":
443 {"description_good": "Service cannot create writable executable memory mappings",
444 "description_bad": "Service may create writable executable memory mappings",
445 "weight": 100,
446 "range": 1
447 },
448 "NoNewPrivileges":
449 {"description_good": "Service processes cannot acquire new privileges",
450 "description_bad": "Service processes may acquire new privileges",
451 "weight": 1000,
452 "range": 1
453 },
454 "CapabilityBoundingSet_CAP_SYS_ADMIN":
455 {"description_good": "Service has no administrator privileges",
456 "description_bad": "Service has administrator privileges",
457 "weight": 1500,
458 "range": 1
459 },
460 "CapabilityBoundingSet_CAP_SET_UID_GID_PCAP":
461 {"description_good": "Service cannot change UID/GID identities/capabilities",
462 "description_bad": "Service may change UID/GID identities/capabilities",
463 "weight": 1500,
464 "range": 1
465 },
466 "CapabilityBoundingSet_CAP_SYS_PTRACE":
467 {"description_good": "Service has no ptrace() debugging abilities",
468 "description_bad": "Service has ptrace() debugging abilities",
469 "weight": 1500,
470 "range": 1
471 },
472 "CapabilityBoundingSet_CAP_SYS_TIME":
473 {"description_good": "Service processes cannot change the system clock",
474 "description_bad": "Service processes may change the system clock",
475 "weight": 1000,
476 "range": 1
477 },
478 "CapabilityBoundingSet_CAP_NET_ADMIN":
479 {"description_good": "Service has no network configuration privileges",
480 "description_bad": "Service has network configuration privileges",
481 "weight": 1000,
482 "range": 1
483 },
484 "CapabilityBoundingSet_CAP_SYS_RAWIO":
485 {"description_good": "Service has no raw I/O access",
486 "description_bad": "Service has raw I/O access",
487 "weight": 1000,
488 "range": 1
489 },
490 "CapabilityBoundingSet_CAP_SYS_MODULE":
491 {"description_good": "Service cannot load kernel modules",
492 "description_bad": "Service may load kernel modules",
493 "weight": 1000,
494 "range": 1
495 },
496 "CapabilityBoundingSet_CAP_AUDIT":
497 {"description_good": "Service has no audit subsystem access",
498 "description_bad": "Service has audit subsystem access",
499 "weight": 500,
500 "range": 1
501 },
502 "CapabilityBoundingSet_CAP_SYSLOG":
503 {"description_good": "Service has no access to kernel logging",
504 "description_bad": "Service has access to kernel logging",
505 "weight": 500,
506 "range": 1
507 },
508 "CapabilityBoundingSet_CAP_SYS_NICE_RESOURCE":
509 {"description_good": "Service has no privileges to change resource use parameters",
510 "description_bad": "Service has privileges to change resource use parameters",
511 "weight": 500,
512 "range": 1
513 },
514 "CapabilityBoundingSet_CAP_MKNOD":
515 {"description_good": "Service cannot create device nodes",
516 "description_bad": "Service may create device nodes",
517 "weight": 500,
518 "range": 1
519 },
520 "CapabilityBoundingSet_CAP_CHOWN_FSETID_SETFCAP":
521 {"description_good": "Service cannot change file ownership/access mode/capabilities",
522 "description_bad": "Service may change file ownership/access mode/capabilities unrestricted",
523 "weight": 1000,
524 "range": 1
525 },
526 "CapabilityBoundingSet_CAP_DAC_FOWNER_IPC_OWNER":
527 {"description_good": "Service cannot override UNIX file/IPC permission checks",
528 "description_bad": "Service may override UNIX file/IPC permission checks",
529 "weight": 1000,
530 "range": 1
531 },
532 "CapabilityBoundingSet_CAP_KILL":
533 {"description_good": "Service cannot send UNIX signals to arbitrary processes",
534 "description_bad": "Service may send UNIX signals to arbitrary processes",
535 "weight": 500,
536 "range": 1
537 },
538 "CapabilityBoundingSet_CAP_NET_BIND_SERVICE_BROADCAST_RAW":
539 {"description_good": "Service has no elevated networking privileges",
540 "description_bad": "Service has elevated networking privileges",
541 "weight": 500,
542 "range": 1
543 },
544 "CapabilityBoundingSet_CAP_SYS_BOOT":
545 {"description_good": "Service cannot issue reboot()",
546 "description_bad": "Service may issue reboot()",
547 "weight": 100,
548 "range": 1
549 },
550 "CapabilityBoundingSet_CAP_MAC":
551 {"description_good": "Service cannot adjust SMACK MAC",
552 "description_bad": "Service may adjust SMACK MAC",
553 "weight": 100,
554 "range": 1
555 },
556 "CapabilityBoundingSet_CAP_LINUX_IMMUTABLE":
557 {"description_good": "Service cannot mark files immutable",
558 "description_bad": "Service may mark files immutable",
559 "weight": 75,
560 "range": 1
561 },
562 "CapabilityBoundingSet_CAP_IPC_LOCK":
563 {"description_good": "Service cannot lock memory into RAM",
564 "description_bad": "Service may lock memory into RAM",
565 "weight": 50,
566 "range": 1
567 },
568 "CapabilityBoundingSet_CAP_SYS_CHROOT":
569 {"description_good": "Service cannot issue chroot()",
570 "description_bad": "Service may issue chroot()",
571 "weight": 50,
572 "range": 1
573 },
574 "CapabilityBoundingSet_CAP_BLOCK_SUSPEND":
575 {"description_good": "Service cannot establish wake locks",
576 "description_bad": "Service may establish wake locks",
577 "weight": 25,
578 "range": 1
579 },
580 "CapabilityBoundingSet_CAP_WAKE_ALARM":
581 {"description_good": "Service cannot program timers that wake up the system",
582 "description_bad": "Service may program timers that wake up the system",
583 "weight": 25,
584 "range": 1
585 },
586 "CapabilityBoundingSet_CAP_LEASE":
587 {"description_good": "Service cannot create file leases",
588 "description_bad": "Service may create file leases",
589 "weight": 25,
590 "range": 1
591 },
592 "CapabilityBoundingSet_CAP_SYS_TTY_CONFIG":
593 {"description_good": "Service cannot issue vhangup()",
594 "description_bad": "Service may issue vhangup()",
595 "weight": 25,
596 "range": 1
597 },
598 "CapabilityBoundingSet_CAP_SYS_PACCT":
599 {"description_good": "Service cannot use acct()",
600 "description_bad": "Service may use acct()",
601 "weight": 25,
602 "range": 1
603 },
604 "CapabilityBoundingSet_CAP_BPF":
605 {"description_good": "Service may load BPF programs",
606 "description_bad": "Service may not load BPF programs",
607 "weight": 25,
608 "range": 1
609 },
610 "UMask":
611 {"weight": 100,
612 "range": 10
613 },
614 "KeyringMode":
615 {"description_good": "Service doesn't share key material with other services",
616 "description_bad": "Service shares key material with other service",
617 "weight": 1000,
618 "range": 1
619 },
620 "ProtectProc":
621 {"description_good": "Service has restricted access to process tree(/proc hidepid=)",
622 "description_bad": "Service has full access to process tree(/proc hidepid=)",
623 "weight": 1000,
624 "range": 3
625 },
626 "ProcSubset":
627 {"description_good": "Service has no access to non-process/proc files(/proc subset=)",
628 "description_bad": "Service has full access to non-process/proc files(/proc subset=)",
629 "weight": 10,
630 "range": 1
631 },
632 "NotifyAccess":
633 {"description_good": "Service child processes cannot alter service state",
634 "description_bad": "Service child processes may alter service state",
635 "weight": 1000,
636 "range": 1
637 },
638 "RemoveIPC":
639 {"description_good": "Service user cannot leave SysV IPC objects around",
640 "description_bad": "Service user may leave SysV IPC objects around",
641 "description_na": "Service runs as root, option does not apply",
642 "weight": 100,
643 "range": 1
644 },
645 "Delegate":
646 {"description_good": "Service does not maintain its own delegated control group subtree",
647 "description_bad": "Service maintains its own delegated control group subtree",
648 "weight": 100,
649 "range": 1
650 },
651 "RestrictRealtime":
652 {"description_good": "Service realtime scheduling access is restricted",
653 "description_bad": "Service may acquire realtime scheduling",
654 "weight": 500,
655 "range": 1
656 },
657 "RestrictSUIDSGID":
658 {"description_good": "SUID/SGIDfilecreationbyserviceisrestricted",
659 "description_bad": "ServicemaycreateSUID/SGIDfiles",
660 "weight": 1000,
661 "range": 1
662 },
663 "RestrictNamespaces_user":
664 {"description_good": "Servicecannotcreateusernamespaces",
665 "description_bad": "Servicemaycreateusernamespaces",
666 "weight": 1500,
667 "range": 1
668 },
669 "RestrictNamespaces_mnt":
670 {"description_good": "Service cannot create file system namespaces",
671 "description_bad": "Service may create file system namespaces",
672 "weight": 500,
673 "range": 1
674 },
675 "RestrictNamespaces_ipc":
676 {"description_good": "Service cannot create IPC namespaces",
677 "description_bad": "Service may create IPC namespaces",
678 "weight": 500,
679 "range": 1
680 },
681 "RestrictNamespaces_pid":
682 {"description_good": "Service cannot create process namespaces",
683 "description_bad": "Service may create process namespaces",
684 "weight": 500,
685 "range": 1
686 },
687 "RestrictNamespaces_cgroup":
688 {"description_good": "Service cannot create cgroup namespaces",
689 "description_bad": "Service may create cgroup namespaces",
690 "weight": 500,
691 "range": 1
692 },
693 "RestrictNamespaces_net":
694 {"description_good": "Service cannot create network namespaces",
695 "description_bad": "Service may create network namespaces",
696 "weight": 500,
697 "range": 1
698 },
699 "RestrictNamespaces_uts":
700 {"description_good": "Service cannot create hostname namespaces",
701 "description_bad": "Service may create hostname namespaces",
702 "weight": 100,
703 "range": 1
704 },
705 "RestrictAddressFamilies_AF_INET_INET6":
706 {"description_good": "Service cannot allocate Internet sockets",
707 "description_bad": "Service may allocate Internet sockets",
708 "weight": 1500,
709 "range": 1
710 },
711 "RestrictAddressFamilies_AF_UNIX":
712 {"description_good": "Service cannot allocate local sockets",
713 "description_bad": "Service may allocate local sockets",
714 "weight": 25,
715 "range": 1
716 },
717 "RestrictAddressFamilies_AF_NETLINK":
718 {"description_good": "Service cannot allocate netlink sockets",
719 "description_bad": "Service may allocate netlink sockets",
720 "weight": 200,
721 "range": 1
722 },
723 "RestrictAddressFamilies_AF_PACKET":
724 {"description_good": "Service cannot allocate packet sockets",
725 "description_bad": "Service may allocate packet sockets",
726 "weight": 1000,
727 "range": 1
728 },
729 "RestrictAddressFamilies_OTHER":
730 {"description_good": "Service cannot allocate exotic sockets",
731 "description_bad": "Service may allocate exotic sockets",
732 "weight": 1250,
733 "range": 1
734 },
735 "SystemCallArchitectures":
736 {"weight": 1000,
737 "range": 10
738 },
739 "SystemCallFilter_swap":
740 {"weight": 1000,
741 "range": 10
742 },
743 "SystemCallFilter_obsolete":
744 {"weight": 250,
745 "range": 10
746 },
747 "SystemCallFilter_clock":
748 {"weight": 1000,
749 "range": 10
750 },
751 "SystemCallFilter_cpu_emulation":
752 {"weight": 250,
753 "range": 10
754 },
755 "SystemCallFilter_debug":
756 {"weight": 1000,
757 "range": 10
758 },
759 "SystemCallFilter_mount":
760 {"weight": 1000,
761 "range": 10
762 },
763 "SystemCallFilter_module":
764 {"weight": 1000,
765 "range": 10
766 },
767 "SystemCallFilter_raw_io":
768 {"weight": 1000,
769 "range": 10
770 },
771 "SystemCallFilter_reboot":
772 {"weight": 1000,
773 "range": 10
774 },
775 "SystemCallFilter_privileged":
776 {"weight": 700,
777 "range": 10
778 },
779 "SystemCallFilter_resources":
780 {"weight": 700,
781 "range": 10
782 },
783 "IPAddressDeny":
784 {"weight": 1000,
785 "range": 10
786 },
787 "DeviceAllow":
788 {"weight": 1000,
789 "range": 10
790 },
791 "AmbientCapabilities":
792 {"description_good": "Service process does not receive ambient capabilities",
793 "description_bad": "Service process receives ambient capabilities",
794 "weight": 500,
795 "range": 1
796 },
797 "INVALID_ID":
798 {"weight": 1000,
799 "range": 10
800 }
801 }
802 EOF
803
804 # Reads in custom security requirements from the parsed .json file and uses these for comparison
805 systemd-analyze security --threshold=90 --offline=true \
806 --security-policy=/tmp/testfile.json \
807 --root=/tmp/img/ testfile.service
808
809 # The strict profile adds a lot of sanboxing options
810 systemd-analyze security --threshold=25 --offline=true \
811 --security-policy=/tmp/testfile.json \
812 --profile=strict \
813 --root=/tmp/img/ testfile.service
814
815 # The trusted profile doesn't add any sanboxing options
816 (! systemd-analyze security --threshold=25 --offline=true \
817 --security-policy=/tmp/testfile.json \
818 --profile=/usr/lib/systemd/portable/profile/trusted/service.conf \
819 --root=/tmp/img/ testfile.service)
820
821 (! systemd-analyze security --threshold=50 --offline=true \
822 --security-policy=/tmp/testfile.json \
823 --root=/tmp/img/ testfile.service)
824
825 rm /tmp/img/usr/lib/systemd/system/testfile.service
826
827 if systemd-analyze --version | grep -q -F "+ELFUTILS"; then
828 systemd-analyze inspect-elf --json=short /lib/systemd/systemd | grep -q -F '"elfType":"executable"'
829 fi
830
831 systemd-analyze --threshold=90 security systemd-journald.service
832
833 # issue 23663
834 check() {(
835 set +x
836 output=$(systemd-analyze security --offline="${2?}" "${3?}" | grep -F 'SystemCallFilter=')
837 assert_in "System call ${1?} list" "$output"
838 assert_in "[+✓] SystemCallFilter=~@swap" "$output"
839 assert_in "[+✓] SystemCallFilter=~@resources" "$output"
840 assert_in "[+✓] SystemCallFilter=~@reboot" "$output"
841 assert_in "[+✓] SystemCallFilter=~@raw-io" "$output"
842 assert_in "[-✗] SystemCallFilter=~@privileged" "$output"
843 assert_in "[+✓] SystemCallFilter=~@obsolete" "$output"
844 assert_in "[+✓] SystemCallFilter=~@mount" "$output"
845 assert_in "[+✓] SystemCallFilter=~@module" "$output"
846 assert_in "[+✓] SystemCallFilter=~@debug" "$output"
847 assert_in "[+✓] SystemCallFilter=~@cpu-emulation" "$output"
848 assert_in "[-✗] SystemCallFilter=~@clock" "$output"
849 )}
850
851 export -n SYSTEMD_LOG_LEVEL
852
853 mkdir -p /run/systemd/system
854 cat >/run/systemd/system/allow-list.service <<EOF
855 [Service]
856 ExecStart=false
857 SystemCallFilter=@system-service
858 SystemCallFilter=~@resources:ENOANO @privileged
859 SystemCallFilter=@clock
860 EOF
861
862 cat >/run/systemd/system/deny-list.service <<EOF
863 [Service]
864 ExecStart=false
865 SystemCallFilter=~@known
866 SystemCallFilter=@system-service
867 SystemCallFilter=~@resources:ENOANO @privileged
868 SystemCallFilter=@clock
869 EOF
870
871 systemctl daemon-reload
872
873 check allow yes /run/systemd/system/allow-list.service
874 check allow no allow-list.service
875 check deny yes /run/systemd/system/deny-list.service
876 check deny no deny-list.service
877
878 output=$(systemd-run -p "SystemCallFilter=@system-service" -p "SystemCallFilter=~@resources:ENOANO @privileged" -p "SystemCallFilter=@clock" sleep 60 2>&1)
879 name=$(echo "$output" | awk '{ print $4 }' | cut -d';' -f1)
880
881 check allow yes /run/systemd/transient/"$name"
882 check allow no "$name"
883
884 output=$(systemd-run -p "SystemCallFilter=~@known" -p "SystemCallFilter=@system-service" -p "SystemCallFilter=~@resources:ENOANO @privileged" -p "SystemCallFilter=@clock" sleep 60 2>&1)
885 name=$(echo "$output" | awk '{ print $4 }' | cut -d';' -f1)
886
887 check deny yes /run/systemd/transient/"$name"
888 check deny no "$name"
889
890 # Let's also test the "image-policy" verb
891
892 systemd-analyze image-policy '*' 2>&1 | grep -q -F "Long form: =verity+signed+encrypted+unprotected+unused+absent"
893 systemd-analyze image-policy '-' 2>&1 | grep -q -F "Long form: =unused+absent"
894 systemd-analyze image-policy 'home=encrypted:usr=verity' 2>&1 | grep -q -F "Long form: usr=verity:home=encrypted:=unused+absent"
895 systemd-analyze image-policy 'home=encrypted:usr=verity' 2>&1 | grep -q -e '^home \+encrypted \+'
896 systemd-analyze image-policy 'home=encrypted:usr=verity' 2>&1 | grep -q -e '^usr \+verity \+'
897 systemd-analyze image-policy 'home=encrypted:usr=verity' 2>&1 | grep -q -e '^root \+ignore \+'
898 systemd-analyze image-policy 'home=encrypted:usr=verity' 2>&1 | grep -q -e '^usr-verity \+unprotected \+'
899
900 (! systemd-analyze image-policy 'doedel')
901
902 # Output is very hard to predict, but let's run it for coverage anyway
903 systemd-analyze pcrs
904 systemd-analyze pcrs --json=pretty
905 systemd-analyze pcrs 14 7 0 ima
906
907 systemd-analyze architectures
908 systemd-analyze architectures --json=pretty
909 systemd-analyze architectures x86
910 systemd-analyze architectures x86-64
911 systemd-analyze architectures native
912 systemd-analyze architectures uname
913
914 systemd-analyze log-level info
915
916 touch /testok