From bfc3a5f2e895decf0bbd5a4b1febe99b36a7ec0c Mon Sep 17 00:00:00 2001 From: Mate Kukri Date: Tue, 22 Oct 2024 08:35:02 +0100 Subject: [PATCH] tpm: Boot with a warning if the event log is full The extend operation still occurs even if `*_log_extend_event` returns EFI_VOLUME_FULL. Let's print a warning when we first see this error code, but otherwise continue booting. Bailing on this condition has caused machines with limited event log space to become unbootable with TPM 2.0 enabled. (fixes #654) Signed-off-by: Mate Kukri --- tpm.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tpm.c b/tpm.c index 388f8d121..7f4a1b092 100644 --- a/tpm.c +++ b/tpm.c @@ -11,6 +11,7 @@ typedef struct { UINTN measuredcount = 0; VARIABLE_RECORD *measureddata = NULL; static BOOLEAN tpm_defective = FALSE; +static BOOLEAN log_full_already_warned = FALSE; static BOOLEAN tpm_present(efi_tpm_protocol_t *tpm) { @@ -108,6 +109,16 @@ static EFI_STATUS tpm_locate_protocol(efi_tpm_protocol_t **tpm, return EFI_NOT_FOUND; } +static void warn_first_log_full(void) +{ + if (!log_full_already_warned) { + perror(L"TPM extend operation occurred, but the event could" + " not be written to one or more event logs. Applications" + " reliant on a valid event log will not function.\n"); + log_full_already_warned = TRUE; + } +} + static EFI_STATUS cc_log_event_raw(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 pcr, const CHAR8 *log, UINTN logsize, UINT32 type, BOOLEAN is_pe_image) @@ -143,6 +154,14 @@ static EFI_STATUS cc_log_event_raw(EFI_PHYSICAL_ADDRESS buf, UINTN size, CopyMem(event->Event, (VOID *)log, logsize); efi_status = cc->hash_log_extend_event(cc, flags, buf, (UINT64)size, event); + /* Per spec: The extend operation occurred, but the event could + * not be written to one or more event logs. We can still safely + * boot in this case, but also show a warning to let the user know. + */ + if (efi_status == EFI_VOLUME_FULL) { + warn_first_log_full(); + efi_status = EFI_SUCCESS; + } FreePool(event); return efi_status; } @@ -201,11 +220,19 @@ static EFI_STATUS tpm_log_event_raw(EFI_PHYSICAL_ADDRESS buf, UINTN size, */ efi_status = tpm2->hash_log_extend_event(tpm2, PE_COFF_IMAGE, buf, (UINT64) size, event); + if (efi_status == EFI_VOLUME_FULL) { + warn_first_log_full(); + efi_status = EFI_SUCCESS; + } } if (!hash || EFI_ERROR(efi_status)) { efi_status = tpm2->hash_log_extend_event(tpm2, 0, buf, (UINT64) size, event); + if (efi_status == EFI_VOLUME_FULL) { + warn_first_log_full(); + efi_status = EFI_SUCCESS; + } } FreePool(event); return efi_status; @@ -239,10 +266,18 @@ static EFI_STATUS tpm_log_event_raw(EFI_PHYSICAL_ADDRESS buf, UINTN size, CopyMem(event->digest, hash, sizeof(event->digest)); efi_status = tpm->log_extend_event(tpm, 0, 0, TPM_ALG_SHA, event, &eventnum, &lastevent); + if (efi_status == EFI_VOLUME_FULL) { + warn_first_log_full(); + efi_status = EFI_SUCCESS; + } } else { efi_status = tpm->log_extend_event(tpm, buf, (UINT64)size, TPM_ALG_SHA, event, &eventnum, &lastevent); + if (efi_status == EFI_VOLUME_FULL) { + warn_first_log_full(); + efi_status = EFI_SUCCESS; + } } if (efi_status == EFI_UNSUPPORTED) { perror(L"Could not write TPM event: %r. Considering "