set -eux
set -o pipefail
+# shellcheck source=test/units/util.sh
+. "$(dirname "$0")"/util.sh
+
# Make sure the unit's exec context matches its configuration
# See: https://github.com/systemd/systemd/pull/29552
# the transient stuff from systemd-run. Let's just skip the following tests
# in that case instead of complicating the test setup even more */
if [[ -z "${COVERAGE_BUILD_DIR:-}" ]]; then
+ if ! systemd-detect-virt -cq && command -v bootctl >/dev/null; then
+ boot_path="$(bootctl --print-boot-path)"
+ esp_path="$(bootctl --print-esp-path)"
+
+ # If the mount points are handled by automount units, make sure we trigger
+ # them before proceeding further
+ ls -l "$boot_path" "$esp_path"
+ fi
+
systemd-run --wait --pipe -p ProtectSystem=yes \
- bash -xec "test ! -w /usr; test ! -w /boot; test -w /etc; test -w /var"
+ bash -xec "test ! -w /usr; ${boot_path:+"test ! -w $boot_path; test ! -w $esp_path;"} test -w /etc; test -w /var"
systemd-run --wait --pipe -p ProtectSystem=full \
- bash -xec "test ! -w /usr; test ! -w /boot; test ! -w /etc; test -w /var"
+ bash -xec "test ! -w /usr; ${boot_path:+"test ! -w $boot_path; test ! -w $esp_path;"} test ! -w /etc; test -w /var"
systemd-run --wait --pipe -p ProtectSystem=strict \
bash -xec "test ! -w /; test ! -w /etc; test ! -w /var; test -w /dev; test -w /proc"
systemd-run --wait --pipe -p ProtectSystem=no \
-p IODeviceWeight="/foo/bar 999"
)
+ systemctl set-property system.slice IOAccounting=yes
# io.latency not available by default on Debian stable
- if [ -e /sys/fs/cgroup/system.slice/io.latency ]; then
+ if [[ -e /sys/fs/cgroup/system.slice/io.latency ]]; then
systemd-run --wait --pipe --unit "$SERVICE_NAME" "${ARGUMENTS[@]}" \
bash -xec "diff <(echo $EXPECTED_IO_MAX) $CGROUP_PATH/io.max; diff <(echo $EXPECTED_IO_LATENCY) $CGROUP_PATH/io.latency"
fi
ARGUMENTS=(
-p LimitCPU=15
-p LimitCPU=10:15 # ulimit -t
- -p LimitFSIZE=7K # ulimit -f
+ -p LimitFSIZE=96G # ulimit -f
-p LimitDATA=8T:infinity
-p LimitDATA=infinity # ulimit -d
-p LimitSTACK=8M # ulimit -s
systemd-run --wait --pipe "${ARGUMENTS[@]}" \
bash -xec 'KB=1; MB=$((KB * 1024)); GB=$((MB * 1024)); TB=$((GB * 1024));
: CPU; [[ $(ulimit -St) -eq 10 ]]; [[ $(ulimit -Ht) -eq 15 ]];
- : FSIZE; [[ $(ulimit -Sf) -eq $((7 * KB)) ]]; [[ $(ulimit -Hf) -eq $((7 * KB)) ]];
+ : FSIZE; [[ $(ulimit -Sf) -eq $((96 * GB)) ]]; [[ $(ulimit -Hf) -eq $((96 * GB)) ]];
: DATA; [[ $(ulimit -Sd) == unlimited ]]; [[ $(ulimit -Hd) == unlimited ]];
: STACK; [[ $(ulimit -Ss) -eq $((8 * MB)) ]]; [[ $(ulimit -Hs) -eq $((8 * MB)) ]];
: CORE; [[ $(ulimit -Sc) -eq $((17 * MB)) ]]; [[ $(ulimit -Hc) -eq $((17 * MB)) ]];
ulimit -R || exit 0;
: RTTIME; [[ $(ulimit -SR) -eq 666666 ]]; [[ $(ulimit -HR) -eq 666666 ]];'
+# RestrictFileSystems=
+#
+# Note: running instrumented binaries requires at least /proc to be accessible, so let's
+# skip the test when we're running under sanitizers
+#
+# Note: $GCOV_ERROR_LOG is used during coverage runs to suppress errors when creating *.gcda files,
+# since gcov can't access the restricted filesystem (as expected)
+if [[ ! -v ASAN_OPTIONS ]] && systemctl --version | grep "+BPF_FRAMEWORK" && kernel_supports_lsm bpf; then
+ ROOTFS="$(df --output=fstype /usr/bin | sed --quiet 2p)"
+ systemd-run --wait --pipe -p RestrictFileSystems="" ls /
+ systemd-run --wait --pipe -p RestrictFileSystems="$ROOTFS foo bar" ls /
+ (! systemd-run --wait --pipe -p RestrictFileSystems="$ROOTFS" ls /proc)
+ (! systemd-run --wait --pipe -p GCOV_ERROR_LOG=/dev/null -p RestrictFileSystems="foo" ls /)
+ systemd-run --wait --pipe -p RestrictFileSystems="$ROOTFS foo bar baz proc" ls /proc
+ systemd-run --wait --pipe -p RestrictFileSystems="$ROOTFS @foo @basic-api" ls /proc
+ systemd-run --wait --pipe -p RestrictFileSystems="$ROOTFS @foo @basic-api" ls /sys/fs/cgroup
+
+ systemd-run --wait --pipe -p RestrictFileSystems="~" ls /
+ systemd-run --wait --pipe -p RestrictFileSystems="~proc" ls /
+ systemd-run --wait --pipe -p RestrictFileSystems="~@basic-api" ls /
+ (! systemd-run --wait --pipe -p GCOV_ERROR_LOG=/dev/null -p RestrictFileSystems="~$ROOTFS" ls /)
+ (! systemd-run --wait --pipe -p RestrictFileSystems="~proc" ls /proc)
+ (! systemd-run --wait --pipe -p RestrictFileSystems="~@basic-api" ls /proc)
+ (! systemd-run --wait --pipe -p RestrictFileSystems="~proc foo @bar @basic-api" ls /proc)
+ (! systemd-run --wait --pipe -p RestrictFileSystems="~proc foo @bar @basic-api" ls /sys)
+ systemd-run --wait --pipe -p RestrictFileSystems="~proc devtmpfs sysfs" ls /
+ (! systemd-run --wait --pipe -p RestrictFileSystems="~proc devtmpfs sysfs" ls /proc)
+ (! systemd-run --wait --pipe -p RestrictFileSystems="~proc devtmpfs sysfs" ls /dev)
+ (! systemd-run --wait --pipe -p RestrictFileSystems="~proc devtmpfs sysfs" ls /sys)
+fi
+
# Ensure that clean-up codepaths work correctly if activation ultimately fails
touch /run/not-a-directory
mkdir /tmp/root
touch /tmp/root/foo
chmod +x /tmp/root/foo
(! systemd-run --wait --pipe false)
-(! systemd-run --wait --pipe -p DynamicUser=yes -p WorkingDirectory=/nonexistent true)
+(! systemd-run --wait --pipe --unit "test-dynamicuser-fail" -p DynamicUser=yes -p WorkingDirectory=/nonexistent true)
(! systemd-run --wait --pipe -p RuntimeDirectory=not-a-directory true)
(! systemd-run --wait --pipe -p RootDirectory=/tmp/root this-shouldnt-exist)
(! systemd-run --wait --pipe -p RootDirectory=/tmp/root /foo)