diff mbox series

[1/2] tpm: Fix buffer access in tpm2_get_tpm_pt()

Message ID 20220506123145.229058-1-stefan.mahnke-hartmann@infineon.com (mailing list archive)
State New
Headers show
Series [1/2] tpm: Fix buffer access in tpm2_get_tpm_pt() | expand

Commit Message

Stefan Mahnke-Hartmann May 6, 2022, 12:31 p.m. UTC
Under certain conditions uninitialized memory will be accessed.
As described by TCG Trusted Platform Module Library Specification,
rev. 1.59 (Part 3: Commands), if a TPM2_GetCapability is received,
requesting a capability, the TPM in Field Upgrade mode may return a
zero length list.
Check the property count in tpm2_get_tpm_pt().

Fixes: 2ab3241161b3 ("tpm: migrate tpm2_get_tpm_pt() to use struct tpm_buf")
Cc: stable@vger.kernel.org
Signed-off-by: Stefan Mahnke-Hartmann <stefan.mahnke-hartmann@infineon.com>
---
 drivers/char/tpm/tpm2-cmd.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Comments

Jarkko Sakkinen May 7, 2022, 7:43 p.m. UTC | #1
On Fri, May 06, 2022 at 02:31:46PM +0200, Stefan Mahnke-Hartmann wrote:
> Under certain conditions uninitialized memory will be accessed.
> As described by TCG Trusted Platform Module Library Specification,
> rev. 1.59 (Part 3: Commands), if a TPM2_GetCapability is received,
> requesting a capability, the TPM in Field Upgrade mode may return a
                                      ~~~~~~~~~~~~~~~~~~

Looks like random picks for casing: two words with upper case letter and
one with lowe case.

> zero length list.
> Check the property count in tpm2_get_tpm_pt().
> 
> Fixes: 2ab3241161b3 ("tpm: migrate tpm2_get_tpm_pt() to use struct tpm_buf")
> Cc: stable@vger.kernel.org
> Signed-off-by: Stefan Mahnke-Hartmann <stefan.mahnke-hartmann@infineon.com>

Which section is this in that specification documented?

I looked into section 30.2 but could not find the part that documents this
behaviour, i.e. returning success in FW upgrade mode. Why it wouldn't just
return TPM_RC_UPGRADE?

BR, Jarkko
Stefan Mahnke-Hartmann May 9, 2022, 11:48 a.m. UTC | #2
On 07.05.22 21:43, Jarkko Sakkinen wrote:
> On Fri, May 06, 2022 at 02:31:46PM +0200, Stefan Mahnke-Hartmann wrote:
>> Under certain conditions uninitialized memory will be accessed.
>> As described by TCG Trusted Platform Module Library Specification,
>> rev. 1.59 (Part 3: Commands), if a TPM2_GetCapability is received,
>> requesting a capability, the TPM in Field Upgrade mode may return a
>                                       ~~~~~~~~~~~~~~~~~~
>
> Looks like random picks for casing: two words with upper case letter and
> one with lowe case.

In the TCG specification it is unfortunately also inconsistent.
I will change it to lower case then.

>
>> zero length list.
>> Check the property count in tpm2_get_tpm_pt().
>>
>> Fixes: 2ab3241161b3 ("tpm: migrate tpm2_get_tpm_pt() to use struct tpm_buf")
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Stefan Mahnke-Hartmann <stefan.mahnke-hartmann@infineon.com>
>
> Which section is this in that specification documented?

It is described in the TCG Trusted Platform Module Library Specification,
rev. 1.59 (Part 3: Commands) in Chapter 30.2.1, Example 3. This example
describes the behavior in failure mode, but it may occur in other
circumstances, such as field upgrade mode.

>
> I looked into section 30.2 but could not find the part that documents this
> behaviour, i.e. returning success in FW upgrade mode. Why it wouldn't just
> return TPM_RC_UPGRADE?

Since some computer system failed booting up in case the TPM returned
anything else than SUCCESS, therefore Infineon decided to return SUCCESS
when TPM is in field upgrade mode.

BR, Stefan

>
> BR, Jarkko
>
>
Jarkko Sakkinen May 11, 2022, 3:11 p.m. UTC | #3
On Mon, May 09, 2022 at 01:48:09PM +0200, Stefan Mahnke-Hartmann wrote:
> On 07.05.22 21:43, Jarkko Sakkinen wrote:
> > On Fri, May 06, 2022 at 02:31:46PM +0200, Stefan Mahnke-Hartmann wrote:
> >> Under certain conditions uninitialized memory will be accessed.
> >> As described by TCG Trusted Platform Module Library Specification,
> >> rev. 1.59 (Part 3: Commands), if a TPM2_GetCapability is received,
> >> requesting a capability, the TPM in Field Upgrade mode may return a
> >                                       ~~~~~~~~~~~~~~~~~~
> >
> > Looks like random picks for casing: two words with upper case letter and
> > one with lowe case.
> 
> In the TCG specification it is unfortunately also inconsistent.
> I will change it to lower case then.
> 
> >
> >> zero length list.
> >> Check the property count in tpm2_get_tpm_pt().
> >>
> >> Fixes: 2ab3241161b3 ("tpm: migrate tpm2_get_tpm_pt() to use struct tpm_buf")
> >> Cc: stable@vger.kernel.org
> >> Signed-off-by: Stefan Mahnke-Hartmann <stefan.mahnke-hartmann@infineon.com>
> >
> > Which section is this in that specification documented?
> 
> It is described in the TCG Trusted Platform Module Library Specification,
> rev. 1.59 (Part 3: Commands) in Chapter 30.2.1, Example 3. This example
> describes the behavior in failure mode, but it may occur in other
> circumstances, such as field upgrade mode.
> 
> >
> > I looked into section 30.2 but could not find the part that documents this
> > behaviour, i.e. returning success in FW upgrade mode. Why it wouldn't just
> > return TPM_RC_UPGRADE?
> 
> Since some computer system failed booting up in case the TPM returned
> anything else than SUCCESS, therefore Infineon decided to return SUCCESS
> when TPM is in field upgrade mode.

OK, fair enough. This would be a place for inline comment though, given
that it is not obvious by intuition.

BR, Jarkko
diff mbox series

Patch

diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 4704fa553098..e62a644ce26b 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -400,7 +400,10 @@  ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id,  u32 *value,
 	if (!rc) {
 		out = (struct tpm2_get_cap_out *)
 			&buf.data[TPM_HEADER_SIZE];
-		*value = be32_to_cpu(out->value);
+		if (be32_to_cpu(out->property_cnt) > 0)
+			*value = be32_to_cpu(out->value);
+		else
+			rc = -ENODATA;
 	}
 	tpm_buf_destroy(&buf);
 	return rc;