Skip to content

Commit 7dfc06a

Browse files
Vogtinatorardbiesheuvel
authored andcommitted
efi/tpm: Verify event log header before parsing
It is possible that the first event in the event log is not actually a log header at all, but rather a normal event. This leads to the cast in __calc_tpm2_event_size being an invalid conversion, which means that the values read are effectively garbage. Depending on the first event's contents, this leads either to apparently normal behaviour, a crash or a freeze. While this behaviour of the firmware is not in accordance with the TCG Client EFI Specification, this happens on a Dell Precision 5510 with the TPM enabled but hidden from the OS ("TPM On" disabled, state otherwise untouched). The EFI firmware claims that the TPM is present and active and that it supports the TCG 2.0 event log format. Fortunately, this can be worked around by simply checking the header of the first event and the event log header signature itself. Commit b4f1874 ("tpm: check event log version before reading final events") addressed a similar issue also found on Dell models. Fixes: 6b03261 ("efi: Attempt to get the TCG2 event log in the boot stub") Signed-off-by: Fabian Vogt <[email protected]> Link: https://lore.kernel.org/r/[email protected] Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1165773 Signed-off-by: Ard Biesheuvel <[email protected]>
1 parent 5435f73 commit 7dfc06a

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

include/linux/tpm_eventlog.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ struct tcg_efi_specid_event_algs {
8181
u16 digest_size;
8282
} __packed;
8383

84+
#define TCG_SPECID_SIG "Spec ID Event03"
85+
8486
struct tcg_efi_specid_event_head {
8587
u8 signature[16];
8688
u32 platform_class;
@@ -171,6 +173,7 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
171173
int i;
172174
int j;
173175
u32 count, event_type;
176+
const u8 zero_digest[sizeof(event_header->digest)] = {0};
174177

175178
marker = event;
176179
marker_start = marker;
@@ -198,10 +201,19 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
198201
count = READ_ONCE(event->count);
199202
event_type = READ_ONCE(event->event_type);
200203

204+
/* Verify that it's the log header */
205+
if (event_header->pcr_idx != 0 ||
206+
event_header->event_type != NO_ACTION ||
207+
memcmp(event_header->digest, zero_digest, sizeof(zero_digest))) {
208+
size = 0;
209+
goto out;
210+
}
211+
201212
efispecid = (struct tcg_efi_specid_event_head *)event_header->event;
202213

203214
/* Check if event is malformed. */
204-
if (count > efispecid->num_algs) {
215+
if (memcmp(efispecid->signature, TCG_SPECID_SIG,
216+
sizeof(TCG_SPECID_SIG)) || count > efispecid->num_algs) {
205217
size = 0;
206218
goto out;
207219
}

0 commit comments

Comments
 (0)