Re: [PATCH] tpm: check event log version before reading final events

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
>




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux Kernel]     [Linux Kernel Hardening]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux