Check the eventlog signature before using it. This avoids using an empty log, as may be the case when QEMU created the ACPI tables, rather than probing the EFI log next. This resolves an issue where the EFI log was empty since an empty ACPI log was used. Fixes: 85467f63a05c ("tpm: Add support for event log pointer found in TPM2 ACPI table") Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxxxxx> --- drivers/char/tpm/eventlog/acpi.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c index 3633ed70f48f..b6bfd22e4a2f 100644 --- a/drivers/char/tpm/eventlog/acpi.c +++ b/drivers/char/tpm/eventlog/acpi.c @@ -41,6 +41,25 @@ struct acpi_tcpa { }; }; +/* check that the given log is indeed a TPM2 log */ +static int tpm_check_tpm2_log_header(void *bios_event_log, u64 len) +{ + struct tcg_efi_specid_event_head *efispecid; + struct tcg_pcr_event *event_header = bios_event_log; + + if (len < sizeof(*event_header)) + return 1; + len -= sizeof(*event_header); + + efispecid = (struct tcg_efi_specid_event_head *)event_header->event; + if (len < sizeof(*efispecid) || + memcmp(efispecid->signature, TCG_SPECID_SIG, + sizeof(TCG_SPECID_SIG))) + return 1; + + return 0; +} + /* read binary bios log */ int tpm_read_log_acpi(struct tpm_chip *chip) { @@ -52,6 +71,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip) struct acpi_table_tpm2 *tbl; struct acpi_tpm2_phy *tpm2_phy; int format; + int ret; log = &chip->log; @@ -112,6 +132,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip) log->bios_event_log_end = log->bios_event_log + len; + ret = -EIO; virt = acpi_os_map_iomem(start, len); if (!virt) goto err; @@ -119,11 +140,19 @@ int tpm_read_log_acpi(struct tpm_chip *chip) memcpy_fromio(log->bios_event_log, virt, len); acpi_os_unmap_iomem(virt, len); + + if (chip->flags & TPM_CHIP_FLAG_TPM2 && + tpm_check_tpm2_log_header(log->bios_event_log, len)) { + /* try EFI log next */ + ret = -ENODEV; + goto err; + } + return format; err: kfree(log->bios_event_log); log->bios_event_log = NULL; - return -EIO; + return ret; } -- 2.29.2