diff mbox series

[2/3] tpm: acpi: Check eventlog signature before using it

Message ID 20210309031954.6232-3-stefanb@linux.ibm.com (mailing list archive)
State New
Headers show
Series Fix bugs related to TPM2 event log | expand

Commit Message

Stefan Berger March 9, 2021, 3:19 a.m. UTC
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@linux.ibm.com>
---
 drivers/char/tpm/eventlog/acpi.c | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

Comments

Jarkko Sakkinen March 10, 2021, 7:51 p.m. UTC | #1
On Mon, Mar 08, 2021 at 10:19:53PM -0500, Stefan Berger wrote:
> 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@linux.ibm.com>
> ---
>  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 */

/* Check that the given log is indeed a TPM2 log. */

> +static int tpm_check_tpm2_log_header(void *bios_event_log, u64 len)

Just by this name does not give any clue what the function does.
"check" can refer to almost anything.

Perhaps just tpm_is_tpm2_log()?

> +{
> +	struct tcg_efi_specid_event_head *efispecid;
> +	struct tcg_pcr_event *event_header = bios_event_log;

Please, reorder these declarations (reverse christmas tree).

> +
> +	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)))

Please never put memcmp() inside a conditional statement.

> +		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
> 
> 

/Jarkko
diff mbox series

Patch

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;
 
 }