Re: [Bug Report] Bug in "efi/libstub: Add get_event_log() support for CC platforms"

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

 



On Thu, 7 Mar 2024 at 16:36, Kuppuswamy Sathyanarayanan
<sathyanarayanan.kuppuswamy@xxxxxxxxxxxxxxx> wrote:
>
>
> On 3/7/24 3:30 AM, Ard Biesheuvel wrote:
> > On Thu, 7 Mar 2024 at 12:13, Ard Biesheuvel <ardb@xxxxxxxxxx> wrote:
> >> On Thu, 7 Mar 2024 at 12:08, Ard Biesheuvel <ardb@xxxxxxxxxx> wrote:
> >>> Hi Muhammad,
> >>>
> >>> Thanks for the report.
> >>>
> >>> On Thu, 7 Mar 2024 at 12:02, Muhammad Usama Anjum
> >>> <usama.anjum@xxxxxxxxxxxxx> wrote:
> >>>> Hi,
> >>>>
> >>>> The recent patch:
> >>>> 276805fb9c305: efi/libstub: Add get_event_log() support for CC platforms
> >>>> has introduced
> >>>> #define EFI_CC_EVENT_LOG_FORMAT_TCG_2   0x00000002
> >>>>
> >>>> But EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 has the same numerical value:
> >>>> #define EFI_TCG2_EVENT_LOG_FORMAT_TCG_2   0x2
> >>>>
> >>>> Thus there is dead code in efi_retrieve_tcg2_eventlog() i.e, multiple if
> >>>> conditions with (version == 2) I'm unable to decide on what is wrong and
> >>>> what is right here. Please have a look.
> >>>>
> >>> Why is this a problem? The compiler will recognize this and simplify
> >>> the conditional. The code as written is semantically correct, the fact
> >>> that the symbolic constants resolve to the same numerical value is
> >>> just an implementation detail.
> >> Ah hold on. I see what you mean now:
> >>
> >> if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
> >> final_events_table = get_efi_config_table(LINUX_EFI_TPM_FINAL_LOG_GUID);
> >> + else if (version == EFI_CC_EVENT_LOG_FORMAT_TCG_2)
> >> + final_events_table = get_efi_config_table(LINUX_EFI_CC_FINAL_LOG_GUID);
> >>
> >> Yes, that is broken.
> > Could we fix it like this perhaps?
> >
> > --- a/drivers/firmware/efi/libstub/tpm.c
> > +++ b/drivers/firmware/efi/libstub/tpm.c
> > @@ -75,8 +75,7 @@
> >          *
> >          * CC Event log also uses TCG2 format, handle it same as TPM2.
> >          */
> >        if (version > EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) {
> >             /*
> >              * The TCG2 log format has variable length entries,
> >              * and the information to decode the hash algorithms
> > @@ -109,10 +108,11 @@
> >      * 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_1_2)
> >        final_events_table =
> >            get_efi_config_table(LINUX_EFI_TPM_FINAL_LOG_GUID) ?:
> >            get_efi_config_table(LINUX_EFI_CC_FINAL_LOG_GUID);
>
> Looks good to me. If there is a concern that a TPM config table may exists
> even in CC case, we can get the table pointer under protocol check and pass
> it as argument to this function.
>

Yeah, that makes sense. I'll fold this into the patch too.

I did realize, though, that we are still missing some pieces to allow
the kernel to make use of this. Only the TCG2 final events log is
accessed by the kernel proper, and AFAICT, this all happens in the
context of a char driver attached to a TPM device.

So I'd like to understand if there are any plans to follow up?






> diff --git a/drivers/firmware/efi/libstub/tpm.c b/drivers/firmware/efi/libstub/tpm.c
> index c35f99f259c1..2ef1e4cd6bb2 100644
> --- a/drivers/firmware/efi/libstub/tpm.c
> +++ b/drivers/firmware/efi/libstub/tpm.c
> @@ -49,12 +49,12 @@ void efi_enable_reset_attack_mitigation(void)
>
>  static void efi_retrieve_tcg2_eventlog(int version, efi_physical_addr_t log_location,
>                                        efi_physical_addr_t log_last_entry,
> -                                      efi_bool_t truncated)
> +                                     efi_bool_t truncated,
> +                                     struct efi_tcg2_final_events_table *final_events_table)
>  {
>         efi_guid_t linux_eventlog_guid = LINUX_EFI_TPM_EVENT_LOG_GUID;
>         efi_status_t status;
>         struct linux_efi_tpm_eventlog *log_tbl = NULL;
> -       struct efi_tcg2_final_events_table *final_events_table = NULL;
>         unsigned long first_entry_addr, last_entry_addr;
>         size_t log_size, last_entry_size;
>         int final_events_size = 0;
> @@ -109,10 +109,6 @@ static void efi_retrieve_tcg2_eventlog(int version, efi_physical_addr_t log_loca
>          * 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);
> -       else if (version == EFI_CC_EVENT_LOG_FORMAT_TCG_2)
> -               final_events_table = get_efi_config_table(LINUX_EFI_CC_FINAL_LOG_GUID);
>         if (final_events_table && final_events_table->nr_events) {
>                 struct tcg_pcr_event2_head *header;
>                 int offset;
> @@ -152,6 +148,7 @@ static void efi_retrieve_tcg2_eventlog(int version, efi_physical_addr_t log_loca
>
>  void efi_retrieve_eventlog(void)
>  {
> +      struct efi_tcg2_final_events_table *final_events_table = NULL;
>         efi_physical_addr_t log_location = 0, log_last_entry = 0;
>         efi_guid_t tpm2_guid = EFI_TCG2_PROTOCOL_GUID;
>         int version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
> @@ -170,6 +167,8 @@ void efi_retrieve_eventlog(void)
>                                                 &log_location, &log_last_entry,
>                                                 &truncated);
>                 }
> +               if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
> +                       final_events_table = get_efi_config_table(LINUX_EFI_TPM_FINAL_LOG_GUID);
>         } else {
>                 efi_guid_t cc_guid = EFI_CC_MEASUREMENT_PROTOCOL_GUID;
>                 efi_cc_protocol_t *cc = NULL;
> @@ -179,6 +178,7 @@ void efi_retrieve_eventlog(void)
>                         return;
>
>                 version = EFI_CC_EVENT_LOG_FORMAT_TCG_2;
> +              final_events_table = get_efi_config_table(LINUX_EFI_CC_FINAL_LOG_GUID);
>                 status = efi_call_proto(cc, get_event_log, version, &log_location,
>                                         &log_last_entry, &truncated);
>         }
> @@ -187,5 +187,5 @@ void efi_retrieve_eventlog(void)
>                 return;
>
>         efi_retrieve_tcg2_eventlog(version, log_location, log_last_entry,
> -                                  truncated);
> +                                 truncated, final_events_table);
>  }
>
>
>
>
>
> --
> Sathyanarayanan Kuppuswamy
> Linux Kernel Developer
>




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux