diff mbox series

tpm/eventlog: Limit memory allocations for event logs with excessive size

Message ID 20241210222608.598424-1-stefanb@linux.ibm.com (mailing list archive)
State New
Headers show
Series tpm/eventlog: Limit memory allocations for event logs with excessive size | expand

Commit Message

Stefan Berger Dec. 10, 2024, 10:26 p.m. UTC
The TPM2 ACPI BIOS eventlog of a particular machine indicates that the
length of the log is 4MB, even though the actual length of its useful data,
when dumped, are only 69kb. To avoid allocating excessive amounts of memory
for the event log, limit the size of any eventlog to 128kb. This should be
sufficient memory and also not unnecessarily truncate event logs on any
other machine.

Reported-by: Andy Liang <andy.liang@hpe.com>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219495
Cc: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 drivers/char/tpm/eventlog/acpi.c | 8 ++++++++
 1 file changed, 8 insertions(+)

Comments

Jarkko Sakkinen Dec. 14, 2024, 3:51 a.m. UTC | #1
On Wed Dec 11, 2024 at 12:26 AM EET, Stefan Berger wrote:
> The TPM2 ACPI BIOS eventlog of a particular machine indicates that the
> length of the log is 4MB, even though the actual length of its useful data,
> when dumped, are only 69kb. To avoid allocating excessive amounts of memory
> for the event log, limit the size of any eventlog to 128kb. This should be
> sufficient memory and also not unnecessarily truncate event logs on any
> other machine.
>
> Reported-by: Andy Liang <andy.liang@hpe.com>
> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219495
> Cc: Takashi Iwai <tiwai@suse.de>
> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
> ---
>  drivers/char/tpm/eventlog/acpi.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c
> index 69533d0bfb51..701fd7d4cc28 100644
> --- a/drivers/char/tpm/eventlog/acpi.c
> +++ b/drivers/char/tpm/eventlog/acpi.c
> @@ -26,6 +26,8 @@
>  #include "../tpm.h"
>  #include "common.h"
>  
> +#define MAX_TPM_LOG_LEN		(128 * 1024)

Instead, to common.h:

/* 
 * Cap the log size to the given number of bytes. Applied to the TPM2
 * ACPI logs.
 */
#define TPM_MAX_LOG_SIZE (128 * 1024)

>
> +
>  struct acpi_tcpa {
>  	struct acpi_table_header hdr;
>  	u16 platform_class;
> @@ -135,6 +137,12 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
>  		return -EIO;
>  	}
>  
> +	if (len > MAX_TPM_LOG_LEN) {
> +		dev_warn(&chip->dev, "Excessive TCPA log len %llu truncated to %u bytes\n",
> +			 len, MAX_TPM_LOG_LEN);
> +		len = MAX_TPM_LOG_LEN;
> +	}

First, you are changing also TPM1 code path. Also in the case of
TPM2 code path the log message is incorrect as TCPA does not exist.

Second, this does not make sense as the log ends up to be corrupted
(i.e. not complete).

Instead, in the TPM2 code path:

		start = tpm2_phy->log_area_start_address;
		if (!start || !len) {
			acpi_put_table((struct acpi_table_header *)tbl);
			return -ENODEV;
		}

		if (len > TPM_MAX_LOG_SIZE) {
			dev_warn(&chip->dev, "Excessive TPM2 log size of %llu bytes (> %u)\n",
				 len, MAX_TPM_LOG_LEN);
			log->bios_event_log = start;
			chip->flags |= TPM_CHIP_FLAG_TPM2_ACPI;
			return 0;
		}

This can then be used in tpm2.c to create a "slow path" in tpm2.c for
parsing TPM2 ACPI log directly by mapping IO memory.

BR, Jarkko
Stefan Berger Dec. 16, 2024, 7:29 p.m. UTC | #2
On 12/13/24 10:51 PM, Jarkko Sakkinen wrote:
> On Wed Dec 11, 2024 at 12:26 AM EET, Stefan Berger wrote:
>> The TPM2 ACPI BIOS eventlog of a particular machine indicates that the
>> length of the log is 4MB, even though the actual length of its useful data,
>> when dumped, are only 69kb. To avoid allocating excessive amounts of memory
>> for the event log, limit the size of any eventlog to 128kb. This should be
>> sufficient memory and also not unnecessarily truncate event logs on any
>> other machine.
>>
>> Reported-by: Andy Liang <andy.liang@hpe.com>
>> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219495
>> Cc: Takashi Iwai <tiwai@suse.de>
>> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
>> ---
>>   drivers/char/tpm/eventlog/acpi.c | 8 ++++++++
>>   1 file changed, 8 insertions(+)
>>
>> diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c
>> index 69533d0bfb51..701fd7d4cc28 100644
>> --- a/drivers/char/tpm/eventlog/acpi.c
>> +++ b/drivers/char/tpm/eventlog/acpi.c
>> @@ -26,6 +26,8 @@
>>   #include "../tpm.h"
>>   #include "common.h"
>>   
>> +#define MAX_TPM_LOG_LEN		(128 * 1024)
> 
> Instead, to common.h:
> 
> /*
>   * Cap the log size to the given number of bytes. Applied to the TPM2
>   * ACPI logs.
>   */
> #define TPM_MAX_LOG_SIZE (128 * 1024)

Done.

> 
>>
>> +
>>   struct acpi_tcpa {
>>   	struct acpi_table_header hdr;
>>   	u16 platform_class;
>> @@ -135,6 +137,12 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
>>   		return -EIO;
>>   	}
>>   
>> +	if (len > MAX_TPM_LOG_LEN) {
>> +		dev_warn(&chip->dev, "Excessive TCPA log len %llu truncated to %u bytes\n",
>> +			 len, MAX_TPM_LOG_LEN);
>> +		len = MAX_TPM_LOG_LEN;
>> +	}
> 
> First, you are changing also TPM1 code path. Also in the case of

Ok, let's move it into the TPM2 code path then.

> TPM2 code path the log message is incorrect as TCPA does not exist.
> 
> Second, this does not make sense as the log ends up to be corrupted
> (i.e. not complete).

Truncating the log is something I am trying to prevent by giving it a 
generous size of 128 kb:
"To avoid allocating excessive amounts of memory
for the event log, limit the size of any eventlog to 128kb. This should be
sufficient memory and also not unnecessarily truncate event logs on any
other machine."

The 8MB the machine with the faulty BIOS indicates are holding 69kb of 
log data at the beginning and then unnecessary data after that. So 
truncating this one to 128kb doesn't affect the 69kb at the beginning.

> 
> Instead, in the TPM2 code path:
> 
> 		start = tpm2_phy->log_area_start_address;
> 		if (!start || !len) {
> 			acpi_put_table((struct acpi_table_header *)tbl);
> 			return -ENODEV;
> 		}
> 
> 		if (len > TPM_MAX_LOG_SIZE) {
> 			dev_warn(&chip->dev, "Excessive TPM2 log size of %llu bytes (> %u)\n",
> 				 len, MAX_TPM_LOG_LEN);
> 			log->bios_event_log = start;
> 			chip->flags |= TPM_CHIP_FLAG_TPM2_ACPI;
> 			return 0;
> 		}
> 
> This can then be used in tpm2.c to create a "slow path" in tpm2.c for
> parsing TPM2 ACPI log directly by mapping IO memory.

I thought the problem when getting request for 8MB is the code a bit 
further below from here that cannot allocated the 8MB.

  	/* malloc EventLog space */
  	log->bios_event_log = devm_kmalloc(&chip->dev, len, GFP_KERNEL);
  	if (!log->bios_event_log)





> 
> BR, Jarkko
Jarkko Sakkinen Dec. 19, 2024, 3:29 p.m. UTC | #3
On Mon Dec 16, 2024 at 9:29 PM EET, Stefan Berger wrote:
>
>
> On 12/13/24 10:51 PM, Jarkko Sakkinen wrote:
> > On Wed Dec 11, 2024 at 12:26 AM EET, Stefan Berger wrote:
> >> The TPM2 ACPI BIOS eventlog of a particular machine indicates that the
> >> length of the log is 4MB, even though the actual length of its useful data,
> >> when dumped, are only 69kb. To avoid allocating excessive amounts of memory
> >> for the event log, limit the size of any eventlog to 128kb. This should be
> >> sufficient memory and also not unnecessarily truncate event logs on any
> >> other machine.
> >>
> >> Reported-by: Andy Liang <andy.liang@hpe.com>
> >> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219495
> >> Cc: Takashi Iwai <tiwai@suse.de>
> >> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
> >> ---
> >>   drivers/char/tpm/eventlog/acpi.c | 8 ++++++++
> >>   1 file changed, 8 insertions(+)
> >>
> >> diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c
> >> index 69533d0bfb51..701fd7d4cc28 100644
> >> --- a/drivers/char/tpm/eventlog/acpi.c
> >> +++ b/drivers/char/tpm/eventlog/acpi.c
> >> @@ -26,6 +26,8 @@
> >>   #include "../tpm.h"
> >>   #include "common.h"
> >>   
> >> +#define MAX_TPM_LOG_LEN		(128 * 1024)
> > 
> > Instead, to common.h:
> > 
> > /*
> >   * Cap the log size to the given number of bytes. Applied to the TPM2
> >   * ACPI logs.
> >   */
> > #define TPM_MAX_LOG_SIZE (128 * 1024)
>
> Done.
>
> > 
> >>
q >> +
> >>   struct acpi_tcpa {
> >>   	struct acpi_table_header hdr;
> >>   	u16 platform_class;
> >> @@ -135,6 +137,12 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
> >>   		return -EIO;
> >>   	}
> >>   
> >> +	if (len > MAX_TPM_LOG_LEN) {
> >> +		dev_warn(&chip->dev, "Excessive TCPA log len %llu truncated to %u bytes\n",
> >> +			 len, MAX_TPM_LOG_LEN);
> >> +		len = MAX_TPM_LOG_LEN;
> >> +	}
> > 
> > First, you are changing also TPM1 code path. Also in the case of
>
> Ok, let's move it into the TPM2 code path then.
>
> > TPM2 code path the log message is incorrect as TCPA does not exist.
> > 
> > Second, this does not make sense as the log ends up to be corrupted
> > (i.e. not complete).
>
> Truncating the log is something I am trying to prevent by giving it a 
> generous size of 128 kb:
> "To avoid allocating excessive amounts of memory
> for the event log, limit the size of any eventlog to 128kb. This should be
> sufficient memory and also not unnecessarily truncate event logs on any
> other machine."
>
> The 8MB the machine with the faulty BIOS indicates are holding 69kb of 
> log data at the beginning and then unnecessary data after that. So 
> truncating this one to 128kb doesn't affect the 69kb at the beginning.

Hmm.. in dmesg (6.4) I see 8388608 bytes = 8 MB.

>
> > 
> > Instead, in the TPM2 code path:
> > 
> > 		start = tpm2_phy->log_area_start_address;
> > 		if (!start || !len) {
> > 			acpi_put_table((struct acpi_table_header *)tbl);
> > 			return -ENODEV;
> > 		}
> > 
> > 		if (len > TPM_MAX_LOG_SIZE) {
> > 			dev_warn(&chip->dev, "Excessive TPM2 log size of %llu bytes (> %u)\n",
> > 				 len, MAX_TPM_LOG_LEN);
> > 			log->bios_event_log = start;
> > 			chip->flags |= TPM_CHIP_FLAG_TPM2_ACPI;
> > 			return 0;
> > 		}
> > 
> > This can then be used in tpm2.c to create a "slow path" in tpm2.c for
> > parsing TPM2 ACPI log directly by mapping IO memory.
>
> I thought the problem when getting request for 8MB is the code a bit 
> further below from here that cannot allocated the 8MB.
>
>   	/* malloc EventLog space */
>   	log->bios_event_log = devm_kmalloc(&chip->dev, len, GFP_KERNEL);
>   	if (!log->bios_event_log)

Truncating the log would make it invalid, or what I'm not seeing?

1. Quick fix: Disable the log if the size surpasses the max. Export
   logs as an empty file so that user space can detect the condition.
2. Proper fix: In tpm2.c call acpi_os_map_iomem() if the size
   surpasses the max, and e.g. use memcpy_fromio() to access it.

In both cases: don't call devm_kmalloc().

Maybe I lost the track. I'm assuming here that the reporter thinks
that 8 MB is somehow legit log size since there is even this recent
comment:

"The TPM2 DUMP still shows the TPM event log size as 8MB. Thank you."

My personal opinion is that we should not fix this at all because:

1. Kernel is not the latest mainline. It's 6.4 and I'm not even
   sure if it is distribution kernel or pure mainline.
2. No detailed description of the hardware. Some imaginary
   hardware does stupid shit with unknown BIOS and ages old
   kernel that is compiled from God knows what source tree.

This does not hold:

"
Please don't shoot the messenger.  Neither of the original report and I
understand / manage the relevant code better than you subsystem
maintainers.

If you can give a patch for testing, I can build a test kernel and ask
the original reporter, of course.  Thanks!
"

A messenger telling a tale or lore is not my cup of tea, and without
better description, I don't proactively encourage to work on this...

   
BR, Jarkko
Jarkko Sakkinen Dec. 19, 2024, 3:38 p.m. UTC | #4
On Thu Dec 19, 2024 at 5:29 PM EET, Jarkko Sakkinen wrote:
> On Mon Dec 16, 2024 at 9:29 PM EET, Stefan Berger wrote:
> >
> >
> > On 12/13/24 10:51 PM, Jarkko Sakkinen wrote:
> > > On Wed Dec 11, 2024 at 12:26 AM EET, Stefan Berger wrote:
> > >> The TPM2 ACPI BIOS eventlog of a particular machine indicates that the
> > >> length of the log is 4MB, even though the actual length of its useful data,
> > >> when dumped, are only 69kb. To avoid allocating excessive amounts of memory
> > >> for the event log, limit the size of any eventlog to 128kb. This should be
> > >> sufficient memory and also not unnecessarily truncate event logs on any
> > >> other machine.
> > >>
> > >> Reported-by: Andy Liang <andy.liang@hpe.com>
> > >> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219495
> > >> Cc: Takashi Iwai <tiwai@suse.de>
> > >> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
> > >> ---
> > >>   drivers/char/tpm/eventlog/acpi.c | 8 ++++++++
> > >>   1 file changed, 8 insertions(+)
> > >>
> > >> diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c
> > >> index 69533d0bfb51..701fd7d4cc28 100644
> > >> --- a/drivers/char/tpm/eventlog/acpi.c
> > >> +++ b/drivers/char/tpm/eventlog/acpi.c
> > >> @@ -26,6 +26,8 @@
> > >>   #include "../tpm.h"
> > >>   #include "common.h"
> > >>   
> > >> +#define MAX_TPM_LOG_LEN		(128 * 1024)
> > > 
> > > Instead, to common.h:
> > > 
> > > /*
> > >   * Cap the log size to the given number of bytes. Applied to the TPM2
> > >   * ACPI logs.
> > >   */
> > > #define TPM_MAX_LOG_SIZE (128 * 1024)
> >
> > Done.
> >
> > > 
> > >>
> q >> +
> > >>   struct acpi_tcpa {
> > >>   	struct acpi_table_header hdr;
> > >>   	u16 platform_class;
> > >> @@ -135,6 +137,12 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
> > >>   		return -EIO;
> > >>   	}
> > >>   
> > >> +	if (len > MAX_TPM_LOG_LEN) {
> > >> +		dev_warn(&chip->dev, "Excessive TCPA log len %llu truncated to %u bytes\n",
> > >> +			 len, MAX_TPM_LOG_LEN);
> > >> +		len = MAX_TPM_LOG_LEN;
> > >> +	}
> > > 
> > > First, you are changing also TPM1 code path. Also in the case of
> >
> > Ok, let's move it into the TPM2 code path then.
> >
> > > TPM2 code path the log message is incorrect as TCPA does not exist.
> > > 
> > > Second, this does not make sense as the log ends up to be corrupted
> > > (i.e. not complete).
> >
> > Truncating the log is something I am trying to prevent by giving it a 
> > generous size of 128 kb:
> > "To avoid allocating excessive amounts of memory
> > for the event log, limit the size of any eventlog to 128kb. This should be
> > sufficient memory and also not unnecessarily truncate event logs on any
> > other machine."
> >
> > The 8MB the machine with the faulty BIOS indicates are holding 69kb of 
> > log data at the beginning and then unnecessary data after that. So 
> > truncating this one to 128kb doesn't affect the 69kb at the beginning.
>
> Hmm.. in dmesg (6.4) I see 8388608 bytes = 8 MB.
>
> >
> > > 
> > > Instead, in the TPM2 code path:
> > > 
> > > 		start = tpm2_phy->log_area_start_address;
> > > 		if (!start || !len) {
> > > 			acpi_put_table((struct acpi_table_header *)tbl);
> > > 			return -ENODEV;
> > > 		}
> > > 
> > > 		if (len > TPM_MAX_LOG_SIZE) {
> > > 			dev_warn(&chip->dev, "Excessive TPM2 log size of %llu bytes (> %u)\n",
> > > 				 len, MAX_TPM_LOG_LEN);
> > > 			log->bios_event_log = start;
> > > 			chip->flags |= TPM_CHIP_FLAG_TPM2_ACPI;
> > > 			return 0;
> > > 		}
> > > 
> > > This can then be used in tpm2.c to create a "slow path" in tpm2.c for
> > > parsing TPM2 ACPI log directly by mapping IO memory.
> >
> > I thought the problem when getting request for 8MB is the code a bit 
> > further below from here that cannot allocated the 8MB.
> >
> >   	/* malloc EventLog space */
> >   	log->bios_event_log = devm_kmalloc(&chip->dev, len, GFP_KERNEL);
> >   	if (!log->bios_event_log)
>
> Truncating the log would make it invalid, or what I'm not seeing?
>
> 1. Quick fix: Disable the log if the size surpasses the max. Export
>    logs as an empty file so that user space can detect the condition.
> 2. Proper fix: In tpm2.c call acpi_os_map_iomem() if the size
>    surpasses the max, and e.g. use memcpy_fromio() to access it.
>
> In both cases: don't call devm_kmalloc().
>
> Maybe I lost the track. I'm assuming here that the reporter thinks
> that 8 MB is somehow legit log size since there is even this recent
> comment:
>
> "The TPM2 DUMP still shows the TPM event log size as 8MB. Thank you."
>
> My personal opinion is that we should not fix this at all because:
>
> 1. Kernel is not the latest mainline. It's 6.4 and I'm not even
>    sure if it is distribution kernel or pure mainline.
> 2. No detailed description of the hardware. Some imaginary
>    hardware does stupid shit with unknown BIOS and ages old
>    kernel that is compiled from God knows what source tree.
>
> This does not hold:
>
> "
> Please don't shoot the messenger.  Neither of the original report and I
> understand / manage the relevant code better than you subsystem
> maintainers.
>
> If you can give a patch for testing, I can build a test kernel and ask
> the original reporter, of course.  Thanks!
> "
>
> A messenger telling a tale or lore is not my cup of tea, and without
> better description, I don't proactively encourage to work on this...

I.e. not yet wontfix but moreinfo b4 anything further should be done.
We don't know what we are fixing.

There's no even user in this scheme as there's no target. Everything is
as imaginary as it can possibly get.

BR, Jarkko
Liang, Andy (Linux Ecosystem Engineering) Dec. 20, 2024, 1:47 a.m. UTC | #5
> On Dec 11, 2024, at 6:26 AM, Stefan Berger <stefanb@linux.ibm.com> wrote:
> 
> The TPM2 ACPI BIOS eventlog of a particular machine indicates that the
> length of the log is 4MB, even though the actual length of its useful data,
> when dumped, are only 69kb. To avoid allocating excessive amounts of memory
> for the event log, limit the size of any eventlog to 128kb. This should be
> sufficient memory and also not unnecessarily truncate event logs on any
> other machine.
> 
> Reported-by: Andy Liang <andy.liang@hpe.com>
> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219495
> Cc: Takashi Iwai <tiwai@suse.de>
> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
> ---
> drivers/char/tpm/eventlog/acpi.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c
> index 69533d0bfb51..701fd7d4cc28 100644
> --- a/drivers/char/tpm/eventlog/acpi.c
> +++ b/drivers/char/tpm/eventlog/acpi.c
> @@ -26,6 +26,8 @@
> #include "../tpm.h"
> #include "common.h"
> 
> +#define MAX_TPM_LOG_LEN (128 * 1024)
> +
> struct acpi_tcpa {
> struct acpi_table_header hdr;
> u16 platform_class;
> @@ -135,6 +137,12 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
> return -EIO;
> }
> 
> + if (len > MAX_TPM_LOG_LEN) {
> + dev_warn(&chip->dev, "Excessive TCPA log len %llu truncated to %u bytes\n",
> + len, MAX_TPM_LOG_LEN);
> + len = MAX_TPM_LOG_LEN;
> + }
> +
> /* malloc EventLog space */
> log->bios_event_log = devm_kmalloc(&chip->dev, len, GFP_KERNEL);
> if (!log->bios_event_log)
> -- 
> 2.43.0
> 

Tested-by: Andy Liang <andy.liang@hpe.com>
Takashi Iwai Dec. 20, 2024, 10:15 a.m. UTC | #6
On Thu, 19 Dec 2024 16:38:40 +0100,
Jarkko Sakkinen wrote:
> 
> On Thu Dec 19, 2024 at 5:29 PM EET, Jarkko Sakkinen wrote:
> > On Mon Dec 16, 2024 at 9:29 PM EET, Stefan Berger wrote:
> > >
> > >
> > > On 12/13/24 10:51 PM, Jarkko Sakkinen wrote:
> > > > On Wed Dec 11, 2024 at 12:26 AM EET, Stefan Berger wrote:
> > > >> The TPM2 ACPI BIOS eventlog of a particular machine indicates that the
> > > >> length of the log is 4MB, even though the actual length of its useful data,
> > > >> when dumped, are only 69kb. To avoid allocating excessive amounts of memory
> > > >> for the event log, limit the size of any eventlog to 128kb. This should be
> > > >> sufficient memory and also not unnecessarily truncate event logs on any
> > > >> other machine.
> > > >>
> > > >> Reported-by: Andy Liang <andy.liang@hpe.com>
> > > >> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219495
> > > >> Cc: Takashi Iwai <tiwai@suse.de>
> > > >> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
> > > >> ---
> > > >>   drivers/char/tpm/eventlog/acpi.c | 8 ++++++++
> > > >>   1 file changed, 8 insertions(+)
> > > >>
> > > >> diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c
> > > >> index 69533d0bfb51..701fd7d4cc28 100644
> > > >> --- a/drivers/char/tpm/eventlog/acpi.c
> > > >> +++ b/drivers/char/tpm/eventlog/acpi.c
> > > >> @@ -26,6 +26,8 @@
> > > >>   #include "../tpm.h"
> > > >>   #include "common.h"
> > > >>   
> > > >> +#define MAX_TPM_LOG_LEN		(128 * 1024)
> > > > 
> > > > Instead, to common.h:
> > > > 
> > > > /*
> > > >   * Cap the log size to the given number of bytes. Applied to the TPM2
> > > >   * ACPI logs.
> > > >   */
> > > > #define TPM_MAX_LOG_SIZE (128 * 1024)
> > >
> > > Done.
> > >
> > > > 
> > > >>
> > q >> +
> > > >>   struct acpi_tcpa {
> > > >>   	struct acpi_table_header hdr;
> > > >>   	u16 platform_class;
> > > >> @@ -135,6 +137,12 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
> > > >>   		return -EIO;
> > > >>   	}
> > > >>   
> > > >> +	if (len > MAX_TPM_LOG_LEN) {
> > > >> +		dev_warn(&chip->dev, "Excessive TCPA log len %llu truncated to %u bytes\n",
> > > >> +			 len, MAX_TPM_LOG_LEN);
> > > >> +		len = MAX_TPM_LOG_LEN;
> > > >> +	}
> > > > 
> > > > First, you are changing also TPM1 code path. Also in the case of
> > >
> > > Ok, let's move it into the TPM2 code path then.
> > >
> > > > TPM2 code path the log message is incorrect as TCPA does not exist.
> > > > 
> > > > Second, this does not make sense as the log ends up to be corrupted
> > > > (i.e. not complete).
> > >
> > > Truncating the log is something I am trying to prevent by giving it a 
> > > generous size of 128 kb:
> > > "To avoid allocating excessive amounts of memory
> > > for the event log, limit the size of any eventlog to 128kb. This should be
> > > sufficient memory and also not unnecessarily truncate event logs on any
> > > other machine."
> > >
> > > The 8MB the machine with the faulty BIOS indicates are holding 69kb of 
> > > log data at the beginning and then unnecessary data after that. So 
> > > truncating this one to 128kb doesn't affect the 69kb at the beginning.
> >
> > Hmm.. in dmesg (6.4) I see 8388608 bytes = 8 MB.
> >
> > >
> > > > 
> > > > Instead, in the TPM2 code path:
> > > > 
> > > > 		start = tpm2_phy->log_area_start_address;
> > > > 		if (!start || !len) {
> > > > 			acpi_put_table((struct acpi_table_header *)tbl);
> > > > 			return -ENODEV;
> > > > 		}
> > > > 
> > > > 		if (len > TPM_MAX_LOG_SIZE) {
> > > > 			dev_warn(&chip->dev, "Excessive TPM2 log size of %llu bytes (> %u)\n",
> > > > 				 len, MAX_TPM_LOG_LEN);
> > > > 			log->bios_event_log = start;
> > > > 			chip->flags |= TPM_CHIP_FLAG_TPM2_ACPI;
> > > > 			return 0;
> > > > 		}
> > > > 
> > > > This can then be used in tpm2.c to create a "slow path" in tpm2.c for
> > > > parsing TPM2 ACPI log directly by mapping IO memory.
> > >
> > > I thought the problem when getting request for 8MB is the code a bit 
> > > further below from here that cannot allocated the 8MB.
> > >
> > >   	/* malloc EventLog space */
> > >   	log->bios_event_log = devm_kmalloc(&chip->dev, len, GFP_KERNEL);
> > >   	if (!log->bios_event_log)
> >
> > Truncating the log would make it invalid, or what I'm not seeing?
> >
> > 1. Quick fix: Disable the log if the size surpasses the max. Export
> >    logs as an empty file so that user space can detect the condition.
> > 2. Proper fix: In tpm2.c call acpi_os_map_iomem() if the size
> >    surpasses the max, and e.g. use memcpy_fromio() to access it.
> >
> > In both cases: don't call devm_kmalloc().
> >
> > Maybe I lost the track. I'm assuming here that the reporter thinks
> > that 8 MB is somehow legit log size since there is even this recent
> > comment:
> >
> > "The TPM2 DUMP still shows the TPM event log size as 8MB. Thank you."
> >
> > My personal opinion is that we should not fix this at all because:
> >
> > 1. Kernel is not the latest mainline. It's 6.4 and I'm not even
> >    sure if it is distribution kernel or pure mainline.

The reporter tested the recent upstream, too.

Also I provided the reporter the build of the upstream kernel with
Stefan's patch.

> > 2. No detailed description of the hardware. Some imaginary
> >    hardware does stupid shit with unknown BIOS and ages old
> >    kernel that is compiled from God knows what source tree.

Again, you can forget about your argument about the kernel version.
The recent upstream kernel has been already checked.
The details of the hardware can be improved by the reporter, though.

About BIOS: yes, we all know that BIOS is buggy as always.  And we all
know that we do tons of workarounds in the kernel side, just because
we can't be optimistic and expect that BIOS shall be fixed later.
(With the long-time subsystem maintainer hat on, I have to tell you
that it's truth, unfortunately...) 

So, if this issue is handled exceptionally and we must ignore the bug,
we'd love to hear the compelling reason.   e.g. if the suggested fix
is way too ugly, then it'd be understandable.  But, to my eyes,
setting the upper bound of the log size is rather a safer move in
general.

> > This does not hold:
> >
> > "
> > Please don't shoot the messenger.  Neither of the original report and I
> > understand / manage the relevant code better than you subsystem
> > maintainers.
> >
> > If you can give a patch for testing, I can build a test kernel and ask
> > the original reporter, of course.  Thanks!
> > "
> >
> > A messenger telling a tale or lore is not my cup of tea, and without
> > better description, I don't proactively encourage to work on this...

Huh?  A messenger is a messenger; I don't own any relevant hardware or
whatever information you asked *at all*.  You've been simply hitting a
very wrong person.


thanks,

Takashi
diff mbox series

Patch

diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c
index 69533d0bfb51..701fd7d4cc28 100644
--- a/drivers/char/tpm/eventlog/acpi.c
+++ b/drivers/char/tpm/eventlog/acpi.c
@@ -26,6 +26,8 @@ 
 #include "../tpm.h"
 #include "common.h"
 
+#define MAX_TPM_LOG_LEN		(128 * 1024)
+
 struct acpi_tcpa {
 	struct acpi_table_header hdr;
 	u16 platform_class;
@@ -135,6 +137,12 @@  int tpm_read_log_acpi(struct tpm_chip *chip)
 		return -EIO;
 	}
 
+	if (len > MAX_TPM_LOG_LEN) {
+		dev_warn(&chip->dev, "Excessive TCPA log len %llu truncated to %u bytes\n",
+			 len, MAX_TPM_LOG_LEN);
+		len = MAX_TPM_LOG_LEN;
+	}
+
 	/* malloc EventLog space */
 	log->bios_event_log = devm_kmalloc(&chip->dev, len, GFP_KERNEL);
 	if (!log->bios_event_log)