Now that run_subtests() understands 77 as skipped, make the subtests that bail out early on a missing capability or precondition exit 77 instead of exit 0. Partial skips that run after real assertions, and exits from inside subshells, are deliberately left untouched. Signed-off-by: Paul Meyer <katexochen0@gmail.com>
108 lines
3.6 KiB
Bash
Executable File
108 lines
3.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
#
|
|
# Exercise the dedicated .dm-verity keyring trust path (kernel commit
|
|
# 033724b1c627, v7.0+): boot with linux-noinitrd so .platform stays empty,
|
|
# provision the mkosi cert into .dm-verity via keyctl, then verify a signed
|
|
# verity image still loads and execs under the BPF policy.
|
|
set -eux
|
|
set -o pipefail
|
|
|
|
# shellcheck source=test/units/util.sh
|
|
. "$(dirname "$0")"/util.sh
|
|
|
|
if systemctl --version | grep -F -- "-BPF_FRAMEWORK" >/dev/null; then
|
|
echo "BPF framework not compiled in, skipping"
|
|
exit 77
|
|
fi
|
|
|
|
if ! kernel_supports_lsm bpf; then
|
|
echo "BPF LSM not available in kernel, skipping"
|
|
exit 77
|
|
fi
|
|
|
|
if command -v bpftool >/dev/null 2>&1; then
|
|
if ! bpftool btf dump file /sys/kernel/btf/vmlinux 2>/dev/null | grep 'bpf_lsm_bdev_setintegrity' >/dev/null; then
|
|
echo "Kernel lacks bdev_setintegrity LSM hook, skipping"
|
|
exit 77
|
|
fi
|
|
fi
|
|
|
|
if [[ -v ASAN_OPTIONS ]]; then
|
|
echo "Skipping under sanitizers"
|
|
exit 77
|
|
fi
|
|
|
|
HELPER="/usr/lib/systemd/tests/unit-tests/manual/test-bpf-restrict-fsaccess"
|
|
if [[ ! -x "$HELPER" ]]; then
|
|
echo "ERROR: test-bpf-restrict-fsaccess helper not found at $HELPER" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Helper exits 77 when systemd was built with bpf-framework=enabled but no
|
|
# vmlinux.h (HAVE_LSM_INTEGRITY_TYPE=0), so the BPF program isn't compiled in.
|
|
rc=0
|
|
"$HELPER" check >/dev/null 2>&1 || rc=$?
|
|
if [[ "$rc" -eq 77 ]]; then
|
|
echo "test-bpf-restrict-fsaccess built without BPF attach support, skipping"
|
|
exit 77
|
|
fi
|
|
|
|
if [[ ! -e /sys/module/dm_verity/parameters/require_signatures ]]; then
|
|
modprobe dm_verity 2>/dev/null || true
|
|
fi
|
|
val="$(cat /sys/module/dm_verity/parameters/require_signatures 2>/dev/null || echo)"
|
|
if [[ "$val" != "Y" && "$val" != "1" ]]; then
|
|
echo "require_signatures not enabled, skipping"
|
|
exit 77
|
|
fi
|
|
|
|
# Provision the .dm-verity keyring. Empty description lets the kernel derive
|
|
# one from the X.509 subject so machine_supports_verity_keyring finds the CN.
|
|
keyid=$(openssl x509 -in /usr/share/mkosi.crt -outform DER |
|
|
keyctl padd asymmetric '' %:.dm-verity 2>/dev/null) || keyid=""
|
|
if [[ -z "$keyid" ]]; then
|
|
echo ".dm-verity keyring not provisionable (kernel < v7.0?), skipping"
|
|
exit 77
|
|
fi
|
|
if ! keyctl restrict_keyring %:.dm-verity; then
|
|
keyctl unlink "$keyid" %:.dm-verity 2>/dev/null || true
|
|
echo "ERROR: keyctl restrict_keyring failed" >&2
|
|
exit 1
|
|
fi
|
|
echo "Provisioned .dm-verity keyring with mkosi.crt"
|
|
|
|
at_exit() {
|
|
set +e
|
|
[[ -n "${HELPER_PID:-}" ]] && kill "$HELPER_PID" 2>/dev/null && wait "$HELPER_PID" 2>/dev/null || true
|
|
rm -rf /tmp/restrict-fsaccess-dvk-attach.out
|
|
}
|
|
trap at_exit EXIT
|
|
|
|
HELPER_PID=
|
|
exec 3< <(exec "$HELPER" attach)
|
|
HELPER_PID=$!
|
|
while IFS= read -r -t 60 line <&3; do
|
|
echo "$line"
|
|
[[ "$line" == LINK_IDS=* ]] && break
|
|
done >/tmp/restrict-fsaccess-dvk-attach.out
|
|
|
|
# Fail closed if helper died before printing the full handshake: an unattached
|
|
# program would let the subsequent verity exec test pass trivially.
|
|
if ! kill -0 "$HELPER_PID" 2>/dev/null; then
|
|
echo "ERROR: helper exited before BPF programs were attached" >&2
|
|
exit 1
|
|
fi
|
|
grep -E '^LINK_IDS="[^"]+"' /tmp/restrict-fsaccess-dvk-attach.out >/dev/null || {
|
|
echo "ERROR: helper did not report LINK_IDS, BPF programs not attached" >&2
|
|
exit 1
|
|
}
|
|
|
|
# Run a binary off the signed minimal_0 verity image. Trust path is exclusively
|
|
# the .dm-verity keyring we just provisioned; .platform is empty under
|
|
# linux-noinitrd.
|
|
systemd-run --pipe --wait \
|
|
--property RootImage=/usr/share/minimal_0.raw \
|
|
bash --version >/dev/null
|
|
echo "Execution from signed dm-verity device (via .dm-verity keyring): OK"
|