From bd9971cd25f452e164e6c5af798a73d16aadbbd9 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Thu, 30 Apr 2026 16:44:39 +0200 Subject: [PATCH 1/2] cryptsetup: avoid a segfault when a keyfile is passed along with a TPM device When a keyfile is passed with tpm2-device=, e.g., systemd-cryptsetup attach test_data /vol /my-pass tpm2-device=auto the logic in attach_luks_or_plain_or_bitlk_by_tpm2() tries to process it as a TPM blob first. This did not work properly because it passes n_blobs=1 to acquire_tpm2_key(), and the key_file is only read when n_blobs == 0. As a result, the code ends up calling tpm2_unseal(..., blobs=NULL, n_blobs=1, ...). Before commit 5c6aad9 ("cryptsetup-tokens: Print tpm2-primary-alg: only when it is known"), the segfault was not observed because tpm2_unseal() was bailing out early when primary_alg == 0. However, after that change, it attempts to process the blob (which is NULL) and crashes. Fix this logic by passing n_blobs=0 to acquire_tpm2_key() so that it actually reads the key_file. Additionally, assert 'blobs' in tpm2_unseal() as a safeguard. Fixes #41867 --- src/cryptsetup/cryptsetup.c | 2 +- src/shared/tpm2-util.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index 2130c54047..bf313340bf 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -2060,7 +2060,7 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2( /* pcrlock_path= */ NULL, /* primary_alg= */ 0, key_file, arg_keyfile_size, arg_keyfile_offset, - key_data, /* n_blobs= */ 1, + key_data, /* n_blobs= */ iovec_is_set(key_data) ? 1 : 0, /* policy_hash= */ NULL, /* we don't know the policy hash */ /* n_policy_hash= */ 0, /* salt= */ NULL, diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 9fe3e01869..091a4dba89 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -5804,6 +5804,7 @@ int tpm2_unseal(Tpm2Context *c, int r; assert(n_blobs > 0); + assert(blobs); assert(iovec_is_valid(pubkey)); assert(ret_secret); From 4820d57eeec98385c25a47e427826f466590360a Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Thu, 30 Apr 2026 16:44:45 +0200 Subject: [PATCH 2/2] TEST-70-TPM2: Test the key_file + tpm2-device= combo When key_file is passed along with tpm2-device= to systemd-cryptsetup, the logic is to try the blob as a TPM blob first, and then fall back to trying the file as a regular key file. Check that this fallback works. --- test/units/TEST-70-TPM2.cryptsetup.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/units/TEST-70-TPM2.cryptsetup.sh b/test/units/TEST-70-TPM2.cryptsetup.sh index 5a7f0facfc..a40f739689 100755 --- a/test/units/TEST-70-TPM2.cryptsetup.sh +++ b/test/units/TEST-70-TPM2.cryptsetup.sh @@ -57,8 +57,9 @@ IMAGE="$(mktemp /tmp/systemd-cryptsetup-XXX.IMAGE)" truncate -s 20M "$IMAGE" echo -n passphrase >/tmp/passphrase +echo -n wrong_passphrase >/tmp/wrong_passphrase # Change file mode to avoid "/tmp/passphrase has 0644 mode that is too permissive" messages -chmod 0600 /tmp/passphrase +chmod 0600 /tmp/passphrase /tmp/wrong_passphrase cryptsetup luksFormat -q --pbkdf pbkdf2 --pbkdf-force-iterations 1000 --use-urandom "$IMAGE" /tmp/passphrase # Unlocking via keyfile @@ -237,4 +238,11 @@ EOF rmdir /tmp/dditest fi -rm -f "$IMAGE" "$PRIMARY" +# Key file can contain a TPM blob but in case it doesn't fallback should also work. +systemd-cryptsetup attach test-volume "$IMAGE" /tmp/passphrase tpm2-device=auto,headless=1 +systemd-cryptsetup detach test-volume + +# Negative test: invalid passphrase should not work. +(! systemd-cryptsetup attach test-volume "$IMAGE" /tmp/wrong_passphrase tpm2-device=auto,headless=1) + +rm -f "$IMAGE" "$PRIMARY" /tmp/passphrase /tmp/wrong_passphrase