diff mbox series

[RFC,v2,3/3] tpm: of: If available use linux,sml-log to get the log and its size

Message ID 20240311132030.1103122-4-stefanb@linux.ibm.com (mailing list archive)
State New
Headers show
Series Preserve TPM log across kexec | expand

Commit Message

Stefan Berger March 11, 2024, 1:20 p.m. UTC
If linux,sml-log is available use it to get the TPM log rather than the
pointer found in linux,sml-base. This resolves an issue on PowerVM and KVM
on Power where after a kexec the memory pointed to by linux,sml-base may
have become inaccessible or corrupted. Also, linux,sml-log has replaced
linux,sml-base and linux,sml-size on these two platforms.

Keep the handling of linux,sml-base/sml-size for powernv platforms that
provide the two properties via skiboot.

Fixes: c5df39262dd5 ("drivers/char/tpm: Add securityfs support for event log")
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 drivers/char/tpm/eventlog/of.c | 36 +++++++++++-----------------------
 1 file changed, 11 insertions(+), 25 deletions(-)

Comments

Jarkko Sakkinen March 11, 2024, 8:25 p.m. UTC | #1
On Mon Mar 11, 2024 at 3:20 PM EET, Stefan Berger wrote:
> If linux,sml-log is available use it to get the TPM log rather than the
> pointer found in linux,sml-base. This resolves an issue on PowerVM and KVM
> on Power where after a kexec the memory pointed to by linux,sml-base may
> have become inaccessible or corrupted. Also, linux,sml-log has replaced
> linux,sml-base and linux,sml-size on these two platforms.
>
> Keep the handling of linux,sml-base/sml-size for powernv platforms that
> provide the two properties via skiboot.
>
> Fixes: c5df39262dd5 ("drivers/char/tpm: Add securityfs support for event log")
> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>

I'm worried about not being up to date and instead using "cached" values
when verifying anything from a security chip. Does this guarantee that
TPM log is corrupted and will not get updated somehow?

BR, Jarkko
Stefan Berger March 11, 2024, 8:33 p.m. UTC | #2
On 3/11/24 16:25, Jarkko Sakkinen wrote:
> On Mon Mar 11, 2024 at 3:20 PM EET, Stefan Berger wrote:
>> If linux,sml-log is available use it to get the TPM log rather than the
>> pointer found in linux,sml-base. This resolves an issue on PowerVM and KVM
>> on Power where after a kexec the memory pointed to by linux,sml-base may
>> have become inaccessible or corrupted. Also, linux,sml-log has replaced
>> linux,sml-base and linux,sml-size on these two platforms.
>>
>> Keep the handling of linux,sml-base/sml-size for powernv platforms that
>> provide the two properties via skiboot.
>>
>> Fixes: c5df39262dd5 ("drivers/char/tpm: Add securityfs support for event log")
>> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
> 
> I'm worried about not being up to date and instead using "cached" values
> when verifying anything from a security chip. Does this guarantee that
> TPM log is corrupted and will not get updated somehow?


What do you mean 'guarantee that TPM log is corrupted'?

The TPM was handed over from the firmware to Linux and the firmware then 
freed all memory associated with the log and will then not create a new 
log or touch the TPM or do anything that would require an update to the 
handed-over log. Linux also does not append to the firmware log. So 
whatever we now find in linux,sml-log would be the latest firmware log 
and the state of the 'firmware PCRs' computed from it should correspond 
to the current state of the 'firmware PCRs'.

> 
> BR, Jarkko
>
Jarkko Sakkinen March 12, 2024, 3:43 p.m. UTC | #3
On Mon Mar 11, 2024 at 10:33 PM EET, Stefan Berger wrote:
>
>
> On 3/11/24 16:25, Jarkko Sakkinen wrote:
> > On Mon Mar 11, 2024 at 3:20 PM EET, Stefan Berger wrote:
> >> If linux,sml-log is available use it to get the TPM log rather than the
> >> pointer found in linux,sml-base. This resolves an issue on PowerVM and KVM
> >> on Power where after a kexec the memory pointed to by linux,sml-base may
> >> have become inaccessible or corrupted. Also, linux,sml-log has replaced
> >> linux,sml-base and linux,sml-size on these two platforms.
> >>
> >> Keep the handling of linux,sml-base/sml-size for powernv platforms that
> >> provide the two properties via skiboot.
> >>
> >> Fixes: c5df39262dd5 ("drivers/char/tpm: Add securityfs support for event log")
> >> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
> > 
> > I'm worried about not being up to date and instead using "cached" values
> > when verifying anything from a security chip. Does this guarantee that
> > TPM log is corrupted and will not get updated somehow?
>
>
> What do you mean 'guarantee that TPM log is corrupted'?

I presume that this is for power architecture but I have no idea what
leads log being corrupted, and is the scope all of that that arch or
some subset of CPUs.

The commit message is not very detailed on kexec scenario. It more like
assumes that reader knows all the detail beforehand. So probably this
will start to make sense once the backing story is improved, that's
all.

> The TPM was handed over from the firmware to Linux and the firmware then 
> freed all memory associated with the log and will then not create a new 
> log or touch the TPM or do anything that would require an update to the 
> handed-over log. Linux also does not append to the firmware log. So 
> whatever we now find in linux,sml-log would be the latest firmware log 
> and the state of the 'firmware PCRs' computed from it should correspond 
> to the current state of the 'firmware PCRs'.

So on what CPU this happens and is there any bigger picture for that
design choice in the firmware?

If it is a firmware bug, this should emit FW_BUG log message. If not,
then this commit message should provide the necessary context.

BR, Jarkko
Stefan Berger March 12, 2024, 7:37 p.m. UTC | #4
On 3/12/24 11:43, Jarkko Sakkinen wrote:
> On Mon Mar 11, 2024 at 10:33 PM EET, Stefan Berger wrote:
>>
>>
>> On 3/11/24 16:25, Jarkko Sakkinen wrote:
>>> On Mon Mar 11, 2024 at 3:20 PM EET, Stefan Berger wrote:
>>>> If linux,sml-log is available use it to get the TPM log rather than the
>>>> pointer found in linux,sml-base. This resolves an issue on PowerVM and KVM
>>>> on Power where after a kexec the memory pointed to by linux,sml-base may
>>>> have become inaccessible or corrupted. Also, linux,sml-log has replaced
>>>> linux,sml-base and linux,sml-size on these two platforms.
>>>>
>>>> Keep the handling of linux,sml-base/sml-size for powernv platforms that
>>>> provide the two properties via skiboot.
>>>>
>>>> Fixes: c5df39262dd5 ("drivers/char/tpm: Add securityfs support for event log")
>>>> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
>>>
>>> I'm worried about not being up to date and instead using "cached" values
>>> when verifying anything from a security chip. Does this guarantee that
>>> TPM log is corrupted and will not get updated somehow?
>>
>>
>> What do you mean 'guarantee that TPM log is corrupted'?
> 
> I presume that this is for power architecture but I have no idea what

Yes it is for Power. From commit message above: "This resolves an issue 
on PowerVM and KVM on Power where after a kexec the memory pointed to by 
linux,sml-base may have become inaccessible or corrupted."

> leads log being corrupted, and is the scope all of that that arch or
> some subset of CPUs.

Every CPU will see a corrupted log.

> 
> The commit message is not very detailed on kexec scenario. It more like

I guess what is missing in the message that the buffer was not properly 
protected during the kexec and may have been overwritten for example 
since it was mistakenly assumed to be free memory?

> assumes that reader knows all the detail beforehand. So probably this
> will start to make sense once the backing story is improved, that's
> all.
> 
>> The TPM was handed over from the firmware to Linux and the firmware then
>> freed all memory associated with the log and will then not create a new
>> log or touch the TPM or do anything that would require an update to the
>> handed-over log. Linux also does not append to the firmware log. So
>> whatever we now find in linux,sml-log would be the latest firmware log
>> and the state of the 'firmware PCRs' computed from it should correspond
>> to the current state of the 'firmware PCRs'.
> 
> So on what CPU this happens and is there any bigger picture for that
> design choice in the firmware?

The firmware provides a call sml-handover, which hands over the TPM log 
to the caller and at the same time frees the log. You cannot call the 
firmware a 2nd time for the log.

> 
> If it is a firmware bug, this should emit FW_BUG log message. If not,
> then this commit message should provide the necessary context.

It's not a firmware bug. The issue is that the buffer holding the TPM 
log is not properly carried across a kexec soft reboot and may for 
example have been overwritten since it was assumed to be free memory.

> 
> BR, Jarkko
>
diff mbox series

Patch

diff --git a/drivers/char/tpm/eventlog/of.c b/drivers/char/tpm/eventlog/of.c
index 930fe43d5daf..dbd837d65264 100644
--- a/drivers/char/tpm/eventlog/of.c
+++ b/drivers/char/tpm/eventlog/of.c
@@ -54,8 +54,8 @@  int tpm_read_log_of(struct tpm_chip *chip)
 	const u32 *sizep;
 	const u64 *basep;
 	struct tpm_bios_log *log;
+	const void *logp;
 	u32 size;
-	u64 base;
 
 	log = &chip->log;
 	if (chip->dev.parent && chip->dev.parent->of_node)
@@ -66,37 +66,23 @@  int tpm_read_log_of(struct tpm_chip *chip)
 	if (of_property_read_bool(np, "powered-while-suspended"))
 		chip->flags |= TPM_CHIP_FLAG_ALWAYS_POWERED;
 
-	sizep = of_get_property(np, "linux,sml-size", NULL);
-	basep = of_get_property(np, "linux,sml-base", NULL);
-	if (sizep == NULL && basep == NULL)
-		return tpm_read_log_memory_region(chip);
-	if (sizep == NULL || basep == NULL)
-		return -EIO;
-
-	/*
-	 * For both vtpm/tpm, firmware has log addr and log size in big
-	 * endian format. But in case of vtpm, there is a method called
-	 * sml-handover which is run during kernel init even before
-	 * device tree is setup. This sml-handover function takes care
-	 * of endianness and writes to sml-base and sml-size in little
-	 * endian format. For this reason, vtpm doesn't need conversion
-	 * but physical tpm needs the conversion.
-	 */
-	if (of_property_match_string(np, "compatible", "IBM,vtpm") < 0 &&
-	    of_property_match_string(np, "compatible", "IBM,vtpm20") < 0) {
+	logp = of_get_property(np, "linux,sml-log", &size);
+	if (logp == NULL) {
+		sizep = of_get_property(np, "linux,sml-size", NULL);
+		basep = of_get_property(np, "linux,sml-base", NULL);
+		if (sizep == NULL && basep == NULL)
+			return tpm_read_log_memory_region(chip);
+		if (sizep == NULL || basep == NULL)
+			return -EIO;
 		size = be32_to_cpup((__force __be32 *)sizep);
-		base = be64_to_cpup((__force __be64 *)basep);
-	} else {
-		size = *sizep;
-		base = *basep;
+		logp = __va(be64_to_cpup((__force __be64 *)basep));
 	}
-
 	if (size == 0) {
 		dev_warn(&chip->dev, "%s: Event log area empty\n", __func__);
 		return -EIO;
 	}
 
-	log->bios_event_log = devm_kmemdup(&chip->dev, __va(base), size, GFP_KERNEL);
+	log->bios_event_log = devm_kmemdup(&chip->dev, logp, size, GFP_KERNEL);
 	if (!log->bios_event_log)
 		return -ENOMEM;