]> git.ipfire.org Git - thirdparty/systemd.git/blob - test/units/testsuite-07.exec-context.sh
Merge pull request #29737 from glance-/tpm2-openssl
[thirdparty/systemd.git] / test / units / testsuite-07.exec-context.sh
1 #!/usr/bin/env bash
2 # SPDX-License-Identifier: LGPL-2.1-or-later
3 set -eux
4 set -o pipefail
5
6 # Make sure the unit's exec context matches its configuration
7 # See: https://github.com/systemd/systemd/pull/29552
8
9 # Even though hidepid= was introduced in kernel 3.3, we support only
10 # the post 5.8 implementation that allows us to apply the option per-instance,
11 # instead of the whole namespace. To distinguish between these two implementations
12 # lets check if we can mount procfs with a named value (e.g. hidepid=off), since
13 # support for this was introduced in the same commit as the per-instance stuff
14 proc_supports_option() {
15 local option="${1:?}"
16 local proc_tmp ec
17
18 proc_tmp="$(mktemp -d)"
19 mount -t proc -o "$option" proc "$proc_tmp" && ec=0 || ec=$?
20 mountpoint -q "$proc_tmp" && umount -q "$proc_tmp"
21 rm -rf "$proc_tmp"
22
23 return $ec
24 }
25
26 # In coverage builds we disable ProtectSystem= and ProtectHome= via a service.d
27 # dropin in /etc. This dropin has, unfortunately, higher priority than
28 # the transient stuff from systemd-run. Let's just skip the following tests
29 # in that case instead of complicating the test setup even more */
30 if [[ -z "${COVERAGE_BUILD_DIR:-}" ]]; then
31 systemd-run --wait --pipe -p ProtectSystem=yes \
32 bash -xec "test ! -w /usr; test ! -w /boot; test -w /etc; test -w /var"
33 systemd-run --wait --pipe -p ProtectSystem=full \
34 bash -xec "test ! -w /usr; test ! -w /boot; test ! -w /etc; test -w /var"
35 systemd-run --wait --pipe -p ProtectSystem=strict \
36 bash -xec "test ! -w /; test ! -w /etc; test ! -w /var; test -w /dev; test -w /proc"
37 systemd-run --wait --pipe -p ProtectSystem=no \
38 bash -xec "test -w /; test -w /etc; test -w /var; test -w /dev; test -w /proc"
39
40 MARK="$(mktemp /root/.exec-context.XXX)"
41 systemd-run --wait --pipe -p ProtectHome=yes \
42 bash -xec "test ! -w /home; test ! -w /root; test ! -w /run/user; test ! -e $MARK"
43 systemd-run --wait --pipe -p ProtectHome=read-only \
44 bash -xec "test ! -w /home; test ! -w /root; test ! -w /run/user; test -e $MARK"
45 systemd-run --wait --pipe -p ProtectHome=tmpfs \
46 bash -xec "test -w /home; test -w /root; test -w /run/user; test ! -e $MARK"
47 systemd-run --wait --pipe -p ProtectHome=no \
48 bash -xec "test -w /home; test -w /root; test -w /run/user; test -e $MARK"
49 rm -f "$MARK"
50 fi
51
52 if proc_supports_option "hidepid=off"; then
53 systemd-run --wait --pipe -p ProtectProc=noaccess -p User=testuser \
54 bash -xec 'test -e /proc/1; test ! -r /proc/1; test -r /proc/$$$$/comm'
55 systemd-run --wait --pipe -p ProtectProc=invisible -p User=testuser \
56 bash -xec 'test ! -e /proc/1; test -r /proc/$$$$/comm'
57 systemd-run --wait --pipe -p ProtectProc=ptraceable -p User=testuser \
58 bash -xec 'test ! -e /proc/1; test -r /proc/$$$$/comm'
59 systemd-run --wait --pipe -p ProtectProc=ptraceable -p User=testuser -p AmbientCapabilities=CAP_SYS_PTRACE \
60 bash -xec 'test -r /proc/1; test -r /proc/$$$$/comm'
61 systemd-run --wait --pipe -p ProtectProc=default -p User=testuser \
62 bash -xec 'test -r /proc/1; test -r /proc/$$$$/comm'
63 fi
64
65 if proc_supports_option "subset=pid"; then
66 systemd-run --wait --pipe -p ProcSubset=pid -p User=testuser \
67 bash -xec "test -r /proc/1/comm; test ! -e /proc/cpuinfo"
68 systemd-run --wait --pipe -p ProcSubset=all -p User=testuser \
69 bash -xec "test -r /proc/1/comm; test -r /proc/cpuinfo"
70 fi
71
72 if ! systemd-detect-virt -cq; then
73 systemd-run --wait --pipe -p ProtectKernelLogs=yes -p User=testuser \
74 bash -xec "test ! -r /dev/kmsg"
75 systemd-run --wait --pipe -p ProtectKernelLogs=no -p User=testuser \
76 bash -xec "test -r /dev/kmsg"
77
78 # Check if we correctly serialize, deserialize, and set directives that
79 # have more complex internal handling
80 #
81 # Funny detail: this originally used the underlying rootfs device, but that,
82 # for some reason, caused "divide error" in kernel, followed by a kernel panic
83 TEMPFILE="$(mktemp)"
84 LODEV="$(losetup --show -f "$TEMPFILE")"
85 ROOT_DEV_MAJ_MIN="$(lsblk -nro MAJ:MIN "$LODEV")"
86 EXPECTED_IO_MAX="$ROOT_DEV_MAJ_MIN rbps=1000 wbps=1000000000000 riops=2000000000 wiops=4000"
87 EXPECTED_IO_LATENCY="$ROOT_DEV_MAJ_MIN target=69000"
88 SERVICE_NAME="test-io-directives-$RANDOM.service"
89 CGROUP_PATH="/sys/fs/cgroup/system.slice/$SERVICE_NAME"
90
91 # IO*=
92 ARGUMENTS=(
93 # Throw in a couple of invalid entries just to test things out
94 -p IOReadBandwidthMax="/foo/bar 1M"
95 -p IOReadBandwidthMax="/foo/baz 1M"
96 -p IOReadBandwidthMax="$LODEV 1M"
97 -p IOReadBandwidthMax="$LODEV 1K"
98 -p IOWriteBandwidthMax="$LODEV 1G"
99 -p IOWriteBandwidthMax="$LODEV 1T"
100 -p IOReadIOPSMax="$LODEV 2G"
101 -p IOWriteIOPSMax="$LODEV 4K"
102 -p IODeviceLatencyTargetSec="$LODEV 666ms"
103 -p IODeviceLatencyTargetSec="/foo/bar 69ms"
104 -p IODeviceLatencyTargetSec="$LODEV 69ms"
105 -p IOReadBandwidthMax="/foo/bar 1M"
106 -p IOReadBandwidthMax="/foo/baz 1M"
107 # TODO: IODeviceWeight= doesn't work on loop devices and virtual disks
108 -p IODeviceWeight="$LODEV 999"
109 -p IODeviceWeight="/foo/bar 999"
110 )
111
112 systemd-run --wait --pipe --unit "$SERVICE_NAME" "${ARGUMENTS[@]}" \
113 bash -xec "diff <(echo $EXPECTED_IO_MAX) $CGROUP_PATH/io.max; diff <(echo $EXPECTED_IO_LATENCY) $CGROUP_PATH/io.latency"
114
115 # CPUScheduling=
116 ARGUMENTS=(
117 -p CPUSchedulingPolicy=rr # ID: 2
118 -p CPUSchedulingPolicy=fifo # ID: 1
119 -p CPUSchedulingPriority=5 # Actual prio: 94 (99 - prio)
120 -p CPUSchedulingPriority=10 # Actual prio: 89 (99 - prio)
121 )
122
123 systemd-run --wait --pipe --unit "$SERVICE_NAME" "${ARGUMENTS[@]}" \
124 bash -xec 'grep -E "^policy\s*:\s*1$" /proc/self/sched; grep -E "^prio\s*:\s*89$" /proc/self/sched'
125
126 # Device*=
127 ARGUMENTS=(
128 -p DevicePolicy=closed
129 -p DevicePolicy=strict
130 -p DeviceAllow="char-mem rm" # Allow read & mknod for /dev/{null,zero,...}
131 -p DeviceAllow="/dev/loop0 rw"
132 -p DeviceAllow="/dev/loop0 w" # Allow write for /dev/loop0
133 # Everything else should be disallowed per the strict policy
134 )
135
136 systemd-run --wait --pipe --unit "$SERVICE_NAME" "${ARGUMENTS[@]}" \
137 bash -xec 'test -r /dev/null; test ! -w /dev/null; test ! -r /dev/loop0; test -w /dev/loop0; test ! -r /dev/tty; test ! -w /dev/tty'
138
139 # SocketBind*=
140 ARGUMENTS=(
141 -p SocketBindAllow=
142 -p SocketBindAllow=1234
143 -p SocketBindAllow=ipv4:udp:any
144 -p SocketBindAllow=ipv6:6666
145 # Everything but the last assignment is superfluous, but it still excercises
146 # the parsing machinery
147 -p SocketBindDeny=
148 -p SocketBindDeny=1111
149 -p SocketBindDeny=ipv4:1111
150 -p SocketBindDeny=ipv4:any
151 -p SocketBindDeny=ipv4:tcp:any
152 -p SocketBindDeny=ipv4:udp:10000-11000
153 -p SocketBindDeny=ipv6:1111
154 -p SocketBindDeny=any
155 )
156
157 # We should fail with EPERM when trying to bind to a socket not on the allow list
158 # (nc exits with 2 in that case)
159 systemd-run --wait -p SuccessExitStatus="1 2" --pipe "${ARGUMENTS[@]}" \
160 bash -xec 'timeout 1s nc -l 127.0.0.1 9999; exit 42'
161 systemd-run --wait -p SuccessExitStatus="1 2" --pipe "${ARGUMENTS[@]}" \
162 bash -xec 'timeout 1s nc -l ::1 9999; exit 42'
163 systemd-run --wait -p SuccessExitStatus="1 2" --pipe "${ARGUMENTS[@]}" \
164 bash -xec 'timeout 1s nc -6 -u -l ::1 9999; exit 42'
165 systemd-run --wait -p SuccessExitStatus="1 2" --pipe "${ARGUMENTS[@]}" \
166 bash -xec 'timeout 1s nc -4 -l 127.0.0.1 6666; exit 42'
167 # Consequently, we should succeed when binding to a socket on the allow list
168 # and keep listening on it until we're killed by `timeout` (EC 124)
169 systemd-run --wait --pipe -p SuccessExitStatus=124 "${ARGUMENTS[@]}" \
170 bash -xec 'timeout 1s nc -4 -l 127.0.0.1 1234; exit 1'
171 systemd-run --wait --pipe -p SuccessExitStatus=124 "${ARGUMENTS[@]}" \
172 bash -xec 'timeout 1s nc -4 -u -l 127.0.0.1 5678; exit 1'
173 systemd-run --wait --pipe -p SuccessExitStatus=124 "${ARGUMENTS[@]}" \
174 bash -xec 'timeout 1s nc -6 -l ::1 1234; exit 1'
175 systemd-run --wait --pipe -p SuccessExitStatus=124 "${ARGUMENTS[@]}" \
176 bash -xec 'timeout 1s nc -6 -l ::1 6666; exit 1'
177
178 losetup -d "$LODEV"
179 rm -f "$TEMPFILE"
180 fi
181
182 systemd-run --wait --pipe -p BindPaths="/etc /home:/mnt:norbind -/foo/bar/baz:/usr:rbind" \
183 bash -xec "mountpoint /etc; test -d /etc/systemd; mountpoint /mnt; ! mountpoint /usr"
184 systemd-run --wait --pipe -p BindReadOnlyPaths="/etc /home:/mnt:norbind -/foo/bar/baz:/usr:rbind" \
185 bash -xec "test ! -w /etc; test ! -w /mnt; ! mountpoint /usr"