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)
This commit is contained in:
Adrian Reber
2026-10-16 17:24:51 +01:00
committed by Luca Boccassi
parent 91c316859d
commit 75b8c3eff1
+2
View File
@@ -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();