test: find out tpm device rather than hardcoding it in TEST-92-TPM2-SWTPM

Looks like the device might change depending on the boot sequence, so
discover it in the test rather than hardcoding it to /dev/tpmrm0.

Fixes https://github.com/systemd/systemd/issues/43210

Follow-up for 1b1900a6f3
This commit is contained in:
Luca Boccassi
2026-07-31 11:06:30 +09:00
committed by Yu Watanabe
parent 71a2af43f9
commit fb3581af65
+24 -7
View File
@@ -23,6 +23,7 @@ CRED=/var/lib/systemd-tpm2-swtpm-test.cred
PLAINTEXT="swtpm round-trip"
# Marker (SWTPM_MANUFACTURED_MARKER) that manufacture_swtpm() indicates completion with.
MARKER=.manufactured
TPM2_DEVICE=
if [[ -n "${ASAN_OPTIONS:-}" ]]; then
# swtpm_setup is not built with sanitizers, but does NSS lookups that pull in the ASan-instrumented
@@ -37,9 +38,25 @@ if [[ ! -x /usr/lib/systemd/systemd-tpm2-swtpm ]] || ! command -v swtpm >/dev/nu
fi
assert_swtpm_up() {
local deadline tpm_device tpm_index tpmrm_device tpmrm_devices
systemctl is-active systemd-tpm2-swtpm.service
timeout 30 bash -c 'until [[ -c /dev/tpmrm0 ]]; do sleep 1; done'
test -c /dev/tpm0
deadline=$((SECONDS + 30))
while (( SECONDS < deadline )); do
mapfile -t tpmrm_devices < <(compgen -G '/sys/class/tpmrm/tpmrm*' || :)
((${#tpmrm_devices[@]} == 1)) && break
sleep .1
done
assert_eq "${#tpmrm_devices[@]}" 1
# The old initrd device number may still be reserved when the host swtpm starts, so do not assume tpm0.
tpmrm_device="${tpmrm_devices[0]##*/}"
tpm_index="${tpmrm_device#tpmrm}"
TPM2_DEVICE="/dev/$tpmrm_device"
tpm_device="/dev/tpm$tpm_index"
udevadm wait --timeout=30 --settle "$TPM2_DEVICE" "$tpm_device"
# No firmware TPM here, so has-tpm2 reports "partial"; assert the software driver is present.
assert_in '\+driver' "$(systemd-analyze has-tpm2 || :)"
}
@@ -58,8 +75,8 @@ case "$REBOOT_COUNT" in
assert_swtpm_up
# Seal a secret to the software TPM and keep the blob for the next boot.
echo -n "$PLAINTEXT" >/tmp/swtpm-plaintext
systemd-creds encrypt --name= --with-key=tpm2 /tmp/swtpm-plaintext "$CRED"
systemd-creds decrypt --name= "$CRED" - | cmp /tmp/swtpm-plaintext -
systemd-creds --tpm2-device="$TPM2_DEVICE" encrypt --name= --with-key=tpm2 /tmp/swtpm-plaintext "$CRED"
systemd-creds --tpm2-device="$TPM2_DEVICE" decrypt --name= "$CRED" - | cmp /tmp/swtpm-plaintext -
systemctl_final reboot
exec sleep infinity
;;
@@ -67,7 +84,7 @@ case "$REBOOT_COUNT" in
assert_swtpm_up
# Persistence: the TPM state survived the reboot on the ESP, so the blob still unseals.
echo -n "$PLAINTEXT" >/tmp/swtpm-plaintext
systemd-creds decrypt --name= "$CRED" - | cmp /tmp/swtpm-plaintext -
systemd-creds --tpm2-device="$TPM2_DEVICE" decrypt --name= "$CRED" - | cmp /tmp/swtpm-plaintext -
# Mimic a manufacture interrupted after swtpm began writing TPM state but before the marker: stop
# swtpm, drop everything except the three config files, then leave a partial/corrupt state file
@@ -91,8 +108,8 @@ case "$REBOOT_COUNT" in
test -e "$statedir/$MARKER"
test -e "$statedir/issuer-certificate.pem"
echo -n "$PLAINTEXT" >/tmp/swtpm-plaintext
systemd-creds encrypt --name= --with-key=tpm2 /tmp/swtpm-plaintext /tmp/swtpm-new.cred
systemd-creds decrypt --name= /tmp/swtpm-new.cred - | cmp /tmp/swtpm-plaintext -
systemd-creds --tpm2-device="$TPM2_DEVICE" encrypt --name= --with-key=tpm2 /tmp/swtpm-plaintext /tmp/swtpm-new.cred
systemd-creds --tpm2-device="$TPM2_DEVICE" decrypt --name= /tmp/swtpm-new.cred - | cmp /tmp/swtpm-plaintext -
touch /testok
;;
*)