On Thu, 14 May 2020 at 13:33, Javier Martinez Canillas <javierm@xxxxxxxxxx> wrote: > > Hello Loïc, > > On 5/14/20 1:28 PM, Loïc Yhuel wrote: > > Le jeu. 14 mai 2020 à 12:54, Jarkko Sakkinen > > <jarkko.sakkinen@xxxxxxxxxxxxxxx> a écrit : > >> So it is clear that "pr_warn(FW_BUG ..." would be a sane to have there. > > So only to tell the UEFI might have logged events the kernel can't read ? > > There is no warning if the table is missing, which would have the same result. > > > > I can try to dump it, perhaps it is using the SHA-1 log format. > > If so, would a patch to support this non-standard behavior be accepted ? > > > > I was thinking the same and wrote the following (untested) patch that should > expose the logs from this Final Events Table that is not following the spec. > > From a08ec2b99b62b3ce97c0906527d5d11f41c255a6 Mon Sep 17 00:00:00 2001 > From: Javier Martinez Canillas <javierm@xxxxxxxxxx> > Date: Thu, 14 May 2020 13:29:42 +0200 > Subject: [RFC PATCH] tpm: Append logs from the Final Events table also for SHA1 > format > > The Final Events Table contains the logs for any events that are triggered > by ExitBootServices(). This is inaccurate afaik. The final events table contains all events that were logged since the first call to Tcg2::GetEventLog() > According to the TCG EFI Protocol Specification the > table will only contains log entries using the crypto agile log format. > > But some EFI firmwares seems to expose a Final Events Table even when the > SHA-1 log format is used. This is not supported according to the TCG spec, > but there is also no other way to get a complete TPM event log for SHA-1 > if ExitBootServices() extends PCR5. > > Currently the kernel only queries for the Final Events Log when using the > crypto agile log format, which is the correct behaviour to be compliant > with the spec. But since there are firmwares that provide the table even > for the SHA-1 log format, attempt to get it and append the final logs to > the TPM event log that is exposed to user-space. > > Signed-off-by: Javier Martinez Canillas <javierm@xxxxxxxxxx> > --- > drivers/char/tpm/eventlog/efi.c | 3 +-- > drivers/firmware/efi/libstub/tpm.c | 18 ++++++++++++------ > drivers/firmware/efi/tpm.c | 21 +++++++++++++++------ > 3 files changed, 28 insertions(+), 14 deletions(-) > > diff --git a/drivers/char/tpm/eventlog/efi.c b/drivers/char/tpm/eventlog/efi.c > index 6bb023de17f..4a8200c9445 100644 > --- a/drivers/char/tpm/eventlog/efi.c > +++ b/drivers/char/tpm/eventlog/efi.c > @@ -61,8 +61,7 @@ int tpm_read_log_efi(struct tpm_chip *chip) > ret = tpm_log_version; > > if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR || > - efi_tpm_final_log_size == 0 || > - tpm_log_version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) > + efi_tpm_final_log_size == 0) > goto out; > > final_tbl = memremap(efi.tpm_final_log, > diff --git a/drivers/firmware/efi/libstub/tpm.c b/drivers/firmware/efi/libstub/tpm.c > index e9a684637b7..ba9d3ac2e19 100644 > --- a/drivers/firmware/efi/libstub/tpm.c > +++ b/drivers/firmware/efi/libstub/tpm.c > @@ -127,10 +127,9 @@ void efi_retrieve_tpm2_eventlog(void) > * Figure out whether any events have already been logged to the > * final events structure, and if so how much space they take up > */ > - if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) > - final_events_table = get_efi_config_table(LINUX_EFI_TPM_FINAL_LOG_GUID); > + final_events_table = get_efi_config_table(LINUX_EFI_TPM_FINAL_LOG_GUID); > if (final_events_table && final_events_table->nr_events) { > - struct tcg_pcr_event2_head *header; > + void *header; > int offset; > void *data; > int event_size; > @@ -142,9 +141,16 @@ void efi_retrieve_tpm2_eventlog(void) > > while (i > 0) { > header = data + offset + final_events_size; > - event_size = __calc_tpm2_event_size(header, > - (void *)(long)log_location, > - false); > + if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) { > + event_size = __calc_tpm2_event_size(header, > + (void *)(long)log_location, > + false); > + } else { > + struct tcpa_event *event = > + (struct tcpa_event *)header; > + event_size = sizeof(*event) + event->event_size; > + } > + > final_events_size += event_size; > i--; > } > diff --git a/drivers/firmware/efi/tpm.c b/drivers/firmware/efi/tpm.c > index 77e101a395e..0962d566481 100644 > --- a/drivers/firmware/efi/tpm.c > +++ b/drivers/firmware/efi/tpm.c > @@ -16,14 +16,24 @@ > int efi_tpm_final_log_size; > EXPORT_SYMBOL(efi_tpm_final_log_size); > > -static int __init tpm2_calc_event_log_size(void *data, int count, void *size_info) > +static int __init tpm2_calc_event_log_size(void *data, int count, > + struct linux_efi_tpm_eventlog *log) > { > - struct tcg_pcr_event2_head *header; > + void *header; > int event_size, size = 0; > + struct tcpa_event *event; > > while (count > 0) { > header = data + size; > - event_size = __calc_tpm2_event_size(header, size_info, true); > + if (log->version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) { > + event_size = __calc_tpm2_event_size(header, > + (void *)log->log, > + true); > + } else { > + event = (struct tcpa_event *)header; > + event_size = sizeof(*event) + event->event_size; > + } > + > if (event_size == 0) > return -1; > size += event_size; > @@ -62,8 +72,7 @@ int __init efi_tpm_eventlog_init(void) > tbl_size = sizeof(*log_tbl) + log_tbl->size; > memblock_reserve(efi.tpm_log, tbl_size); > > - if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR || > - log_tbl->version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) > + if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR) > goto out; > > final_tbl = early_memremap(efi.tpm_final_log, sizeof(*final_tbl)); > @@ -84,7 +93,7 @@ int __init efi_tpm_eventlog_init(void) > > tbl_size = tpm2_calc_event_log_size(events, > final_tbl->nr_events, > - log_tbl->log); > + log_tbl); > } > > if (tbl_size < 0) { > -- > 2.26.2 > > Best regards, > -- > Javier Martinez Canillas > Software Engineer - Desktop Hardware Enablement > Red Hat >