From 75b8c3eff1daedbb1ee7346bcb871b339e261d81 Mon Sep 17 00:00:00 2001 From: Adrian Reber Date: Tue, 13 Oct 2026 10:29:12 +0000 Subject: [PATCH] tpm2-util: refuse tokens with public key policy reference but no key tpm2_parse_luks2_json() only insists on "tpm2_pubkey" being present when "tpm2_pubkey_pcrs" is set, but happily accepts a token carrying "tpm2_pubkey_ref" without a public key. tpm2_unseal() then trips over its assert(!pubkey_policy_ref || iovec_is_set(pubkey)), i.e. a crafted LUKS2 header aborts whatever tries to unlock it instead of being rejected. tpm2_make_luks2_json() never writes that combination (it asserts the same invariant), hence refuse it when parsing, as is already done for a PCR mask without a public key. This matters more now that systemd-dissect, systemd-nspawn and systemd-sysext unlock images via these tokens, as the headers they see are less trusted than the host's own volumes. (cherry picked from commit 3520b44f7e398f924c267ee4527941924297c6bc) --- src/shared/tpm2-util.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 7cbfa3aec5..4aac853833 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -11664,6 +11664,8 @@ int tpm2_parse_luks2_json( const char *s = sd_json_variant_string(w); if (!s) return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Public key policy reference is not a string."); + if (!iovec_is_set(&pubkey)) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Public key policy reference set, but no public key included in JSON data, refusing."); pubkey_ref = strdup(s); if (!pubkey_ref) return log_oom_debug();