All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv()
@ 2019-04-10 13:54 Jarkko Sakkinen
  2019-04-15 10:48 ` Greg KH
  0 siblings, 1 reply; 15+ messages in thread
From: Jarkko Sakkinen @ 2019-04-10 13:54 UTC (permalink / raw)
  To: stable; +Cc: Jarkko Sakkinen, James Morris, Tomas Winkler, Jerry Snitselaar

commit 3d7a850fdc1a2e4d2adbc95cc0fc962974725e88 upstream

The current approach to read first 6 bytes from the response and then tail
of the response, can cause the 2nd memcpy_fromio() to do an unaligned read
(e.g. read 32-bit word from address aligned to a 16-bits), depending on how
memcpy_fromio() is implemented. If this happens, the read will fail and the
memory controller will fill the read with 1's.

This was triggered by 170d13ca3a2f, which should be probably refined to
check and react to the address alignment. Before that commit, on x86
memcpy_fromio() turned out to be memcpy(). By a luck GCC has done the right
thing (from tpm_crb's perspective) for us so far, but we should not rely on
that. Thus, it makes sense to fix this also in tpm_crb, not least because
the fix can be then backported to stable kernels and make them more robust
when compiled in differing environments.

Cc: stable@vger.kernel.org
Cc: James Morris <jmorris@namei.org>
Cc: Tomas Winkler <tomas.winkler@intel.com>
Cc: Jerry Snitselaar <jsnitsel@redhat.com>
Fixes: 30fc8d138e91 ("tpm: TPM 2.0 CRB Interface")
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
Acked-by: Tomas Winkler <tomas.winkler@intel.com>
---
backport v4.4.178
 drivers/char/tpm/tpm_crb.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index 35308dfff754..8226e3b6dc1f 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -109,19 +109,29 @@ static int crb_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 	struct crb_priv *priv = chip->vendor.priv;
 	unsigned int expected;
 
-	/* sanity check */
-	if (count < 6)
+	/* A sanity check that the upper layer wants to get at least the header
+	 * as that is the minimum size for any TPM response.
+	 */
+	if (count < TPM_HEADER_SIZE)
 		return -EIO;
 
+	/* If this bit is set, according to the spec, the TPM is in
+	 * unrecoverable condition.
+	 */
 	if (le32_to_cpu(ioread32(&priv->cca->sts)) & CRB_CA_STS_ERROR)
 		return -EIO;
 
-	memcpy_fromio(buf, priv->rsp, 6);
-	expected = be32_to_cpup((__be32 *) &buf[2]);
-	if (expected > count || expected < 6)
+	/* Read the first 8 bytes in order to get the length of the response.
+	 * We read exactly a quad word in order to make sure that the remaining
+	 * reads will be aligned.
+	 */
+	memcpy_fromio(buf, priv->rsp, 8);
+
+	expected = be32_to_cpup((__be32 *)&buf[2]);
+	if (expected > count || expected < TPM_HEADER_SIZE)
 		return -EIO;
 
-	memcpy_fromio(&buf[6], &priv->rsp[6], expected - 6);
+	memcpy_fromio(&buf[8], &priv->rsp[8], expected - 8);
 
 	return expected;
 }
-- 
2.19.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv()
  2019-04-10 13:54 [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv() Jarkko Sakkinen
@ 2019-04-15 10:48 ` Greg KH
  2019-04-16  7:25   ` Jarkko Sakkinen
  0 siblings, 1 reply; 15+ messages in thread
From: Greg KH @ 2019-04-15 10:48 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: stable, James Morris, Tomas Winkler, Jerry Snitselaar

On Wed, Apr 10, 2019 at 04:54:32PM +0300, Jarkko Sakkinen wrote:
> commit 3d7a850fdc1a2e4d2adbc95cc0fc962974725e88 upstream
> 
> The current approach to read first 6 bytes from the response and then tail
> of the response, can cause the 2nd memcpy_fromio() to do an unaligned read
> (e.g. read 32-bit word from address aligned to a 16-bits), depending on how
> memcpy_fromio() is implemented. If this happens, the read will fail and the
> memory controller will fill the read with 1's.
> 
> This was triggered by 170d13ca3a2f, which should be probably refined to
> check and react to the address alignment. Before that commit, on x86
> memcpy_fromio() turned out to be memcpy(). By a luck GCC has done the right
> thing (from tpm_crb's perspective) for us so far, but we should not rely on
> that. Thus, it makes sense to fix this also in tpm_crb, not least because
> the fix can be then backported to stable kernels and make them more robust
> when compiled in differing environments.
> 
> Cc: stable@vger.kernel.org
> Cc: James Morris <jmorris@namei.org>
> Cc: Tomas Winkler <tomas.winkler@intel.com>
> Cc: Jerry Snitselaar <jsnitsel@redhat.com>
> Fixes: 30fc8d138e91 ("tpm: TPM 2.0 CRB Interface")
> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
> Acked-by: Tomas Winkler <tomas.winkler@intel.com>
> ---
> backport v4.4.178
>  drivers/char/tpm/tpm_crb.c | 22 ++++++++++++++++------
>  1 file changed, 16 insertions(+), 6 deletions(-)

I need a 4.9.y version first before I can take a 4.4.y version, as we do
not want anyone to have a regression moving from 4.4.y to a newer
kernel.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv()
  2019-04-15 10:48 ` Greg KH
@ 2019-04-16  7:25   ` Jarkko Sakkinen
  0 siblings, 0 replies; 15+ messages in thread
From: Jarkko Sakkinen @ 2019-04-16  7:25 UTC (permalink / raw)
  To: Greg KH; +Cc: stable, James Morris, Tomas Winkler, Jerry Snitselaar

On Mon, Apr 15, 2019 at 12:48:25PM +0200, Greg KH wrote:
> On Wed, Apr 10, 2019 at 04:54:32PM +0300, Jarkko Sakkinen wrote:
> > commit 3d7a850fdc1a2e4d2adbc95cc0fc962974725e88 upstream
> > 
> > The current approach to read first 6 bytes from the response and then tail
> > of the response, can cause the 2nd memcpy_fromio() to do an unaligned read
> > (e.g. read 32-bit word from address aligned to a 16-bits), depending on how
> > memcpy_fromio() is implemented. If this happens, the read will fail and the
> > memory controller will fill the read with 1's.
> > 
> > This was triggered by 170d13ca3a2f, which should be probably refined to
> > check and react to the address alignment. Before that commit, on x86
> > memcpy_fromio() turned out to be memcpy(). By a luck GCC has done the right
> > thing (from tpm_crb's perspective) for us so far, but we should not rely on
> > that. Thus, it makes sense to fix this also in tpm_crb, not least because
> > the fix can be then backported to stable kernels and make them more robust
> > when compiled in differing environments.
> > 
> > Cc: stable@vger.kernel.org
> > Cc: James Morris <jmorris@namei.org>
> > Cc: Tomas Winkler <tomas.winkler@intel.com>
> > Cc: Jerry Snitselaar <jsnitsel@redhat.com>
> > Fixes: 30fc8d138e91 ("tpm: TPM 2.0 CRB Interface")
> > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> > Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
> > Acked-by: Tomas Winkler <tomas.winkler@intel.com>
> > ---
> > backport v4.4.178
> >  drivers/char/tpm/tpm_crb.c | 22 ++++++++++++++++------
> >  1 file changed, 16 insertions(+), 6 deletions(-)
> 
> I need a 4.9.y version first before I can take a 4.4.y version, as we do
> not want anyone to have a regression moving from 4.4.y to a newer
> kernel.

OK, will do.

/Jarkko

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv()
  2019-04-17 14:59 Jarkko Sakkinen
@ 2019-04-17 15:42 ` Sasha Levin
  0 siblings, 0 replies; 15+ messages in thread
From: Sasha Levin @ 2019-04-17 15:42 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: stable, James Morris, Tomas Winkler, Jerry Snitselaar

On Wed, Apr 17, 2019 at 05:59:15PM +0300, Jarkko Sakkinen wrote:
>commit 3d7a850fdc1a2e4d2adbc95cc0fc962974725e88 upstream
>
>The current approach to read first 6 bytes from the response and then tail
>of the response, can cause the 2nd memcpy_fromio() to do an unaligned read
>(e.g. read 32-bit word from address aligned to a 16-bits), depending on how
>memcpy_fromio() is implemented. If this happens, the read will fail and the
>memory controller will fill the read with 1's.
>
>This was triggered by 170d13ca3a2f, which should be probably refined to
>check and react to the address alignment. Before that commit, on x86
>memcpy_fromio() turned out to be memcpy(). By a luck GCC has done the right
>thing (from tpm_crb's perspective) for us so far, but we should not rely on
>that. Thus, it makes sense to fix this also in tpm_crb, not least because
>the fix can be then backported to stable kernels and make them more robust
>when compiled in differing environments.
>
>Cc: stable@vger.kernel.org
>Cc: James Morris <jmorris@namei.org>
>Cc: Tomas Winkler <tomas.winkler@intel.com>
>Cc: Jerry Snitselaar <jsnitsel@redhat.com>
>Fixes: 30fc8d138e91 ("tpm: TPM 2.0 CRB Interface")
>Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
>Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
>Acked-by: Tomas Winkler <tomas.winkler@intel.com>
>---
>backport v4.9.99
> drivers/char/tpm/tpm_crb.c | 22 ++++++++++++++++------
> 1 file changed, 16 insertions(+), 6 deletions(-)

I've queued both this and the 4.4 backport, thanks!

--
Thanks,
Sasha

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv()
@ 2019-04-17 14:59 Jarkko Sakkinen
  2019-04-17 15:42 ` Sasha Levin
  0 siblings, 1 reply; 15+ messages in thread
From: Jarkko Sakkinen @ 2019-04-17 14:59 UTC (permalink / raw)
  To: stable; +Cc: Jarkko Sakkinen, James Morris, Tomas Winkler, Jerry Snitselaar

commit 3d7a850fdc1a2e4d2adbc95cc0fc962974725e88 upstream

The current approach to read first 6 bytes from the response and then tail
of the response, can cause the 2nd memcpy_fromio() to do an unaligned read
(e.g. read 32-bit word from address aligned to a 16-bits), depending on how
memcpy_fromio() is implemented. If this happens, the read will fail and the
memory controller will fill the read with 1's.

This was triggered by 170d13ca3a2f, which should be probably refined to
check and react to the address alignment. Before that commit, on x86
memcpy_fromio() turned out to be memcpy(). By a luck GCC has done the right
thing (from tpm_crb's perspective) for us so far, but we should not rely on
that. Thus, it makes sense to fix this also in tpm_crb, not least because
the fix can be then backported to stable kernels and make them more robust
when compiled in differing environments.

Cc: stable@vger.kernel.org
Cc: James Morris <jmorris@namei.org>
Cc: Tomas Winkler <tomas.winkler@intel.com>
Cc: Jerry Snitselaar <jsnitsel@redhat.com>
Fixes: 30fc8d138e91 ("tpm: TPM 2.0 CRB Interface")
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
Acked-by: Tomas Winkler <tomas.winkler@intel.com>
---
backport v4.9.99
 drivers/char/tpm/tpm_crb.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index fa0f66809503..d29f78441cdb 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -102,19 +102,29 @@ static int crb_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
 	unsigned int expected;
 
-	/* sanity check */
-	if (count < 6)
+	/* A sanity check that the upper layer wants to get at least the header
+	 * as that is the minimum size for any TPM response.
+	 */
+	if (count < TPM_HEADER_SIZE)
 		return -EIO;
 
+	/* If this bit is set, according to the spec, the TPM is in
+	 * unrecoverable condition.
+	 */
 	if (ioread32(&priv->cca->sts) & CRB_CTRL_STS_ERROR)
 		return -EIO;
 
-	memcpy_fromio(buf, priv->rsp, 6);
-	expected = be32_to_cpup((__be32 *) &buf[2]);
-	if (expected > count || expected < 6)
+	/* Read the first 8 bytes in order to get the length of the response.
+	 * We read exactly a quad word in order to make sure that the remaining
+	 * reads will be aligned.
+	 */
+	memcpy_fromio(buf, priv->rsp, 8);
+
+	expected = be32_to_cpup((__be32 *)&buf[2]);
+	if (expected > count || expected < TPM_HEADER_SIZE)
 		return -EIO;
 
-	memcpy_fromio(&buf[6], &priv->rsp[6], expected - 6);
+	memcpy_fromio(&buf[8], &priv->rsp[8], expected - 8);
 
 	return expected;
 }
-- 
2.19.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv():
  2019-02-05 10:47     ` Jarkko Sakkinen
@ 2019-02-05 10:49       ` Jarkko Sakkinen
  0 siblings, 0 replies; 15+ messages in thread
From: Jarkko Sakkinen @ 2019-02-05 10:49 UTC (permalink / raw)
  To: David Laight
  Cc: linux-kernel, linux-integrity, linux-security-module, stable,
	Linus Torvalds, James Morris, Tomas Winkler, Jerry Snitselaar

On Tue, Feb 05, 2019 at 12:47:47PM +0200, Jarkko Sakkinen wrote:
> On Tue, Feb 05, 2019 at 12:44:06PM +0200, Jarkko Sakkinen wrote:
> > On Mon, Feb 04, 2019 at 12:17:43PM +0000, David Laight wrote:
> > > From: Jarkko Sakkinen
> > > > Sent: 01 February 2019 11:20
> > > > The current approach to read first 6 bytes from the response and then tail
> > > > of the response, can cause the 2nd memcpy_fromio() to do an unaligned read
> > > > (e.g. read 32-bit word from address aligned to a 16-bits), depending on how
> > > > memcpy_fromio() is implemented. If this happens, the read will fail and the
> > > > memory controller will fill the read with 1's.
> > > 
> > > To my mind memcpy_to/fromio() should only be used on IO addresses that are
> > > adequately like memory, and should be implemented in a way that that won't
> > > generate invalid bus cycles.
> > > Also memcpy_fromio() should also be allowed to do 'aligned' accesses that
> > > go beyond the ends of the required memory area.
> > > 
> > > ...
> > > > 
> > > > -	memcpy_fromio(buf, priv->rsp, 6);
> > > > +	memcpy_fromio(buf, priv->rsp, 8);
> > > >  	expected = be32_to_cpup((__be32 *) &buf[2]);
> > > > -	if (expected > count || expected < 6)
> > > > +	if (expected > count || expected < 8)
> > > >  		return -EIO;
> > > > 
> > > > -	memcpy_fromio(&buf[6], &priv->rsp[6], expected - 6);
> > > > +	memcpy_fromio(&buf[8], &priv->rsp[8], expected - 8);
> > > 
> > > Why not just use readl() or readq() ?
> > > 
> > > Bound to generate better code.
> > 
> > For the first read can be done. The second read is of variable
> > length.
> 
> Neither can be done to the first one, because readq() does
> le64_to_cpu(). Shoud not do any conversions, only raw read.
> So I'll just stick it to what we have.

ATM tmp_crb is only used in LE architectures (x86 and ARM64), but
I still hate to have hidden extra byte order conversions, even if
they get compiled as nil ops. It is more wrong than to use
memcpy_fromio().

/Jarkko

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv():
  2019-02-05 10:44   ` Jarkko Sakkinen
@ 2019-02-05 10:47     ` Jarkko Sakkinen
  2019-02-05 10:49       ` Jarkko Sakkinen
  0 siblings, 1 reply; 15+ messages in thread
From: Jarkko Sakkinen @ 2019-02-05 10:47 UTC (permalink / raw)
  To: David Laight
  Cc: linux-kernel, linux-integrity, linux-security-module, stable,
	Linus Torvalds, James Morris, Tomas Winkler, Jerry Snitselaar

On Tue, Feb 05, 2019 at 12:44:06PM +0200, Jarkko Sakkinen wrote:
> On Mon, Feb 04, 2019 at 12:17:43PM +0000, David Laight wrote:
> > From: Jarkko Sakkinen
> > > Sent: 01 February 2019 11:20
> > > The current approach to read first 6 bytes from the response and then tail
> > > of the response, can cause the 2nd memcpy_fromio() to do an unaligned read
> > > (e.g. read 32-bit word from address aligned to a 16-bits), depending on how
> > > memcpy_fromio() is implemented. If this happens, the read will fail and the
> > > memory controller will fill the read with 1's.
> > 
> > To my mind memcpy_to/fromio() should only be used on IO addresses that are
> > adequately like memory, and should be implemented in a way that that won't
> > generate invalid bus cycles.
> > Also memcpy_fromio() should also be allowed to do 'aligned' accesses that
> > go beyond the ends of the required memory area.
> > 
> > ...
> > > 
> > > -	memcpy_fromio(buf, priv->rsp, 6);
> > > +	memcpy_fromio(buf, priv->rsp, 8);
> > >  	expected = be32_to_cpup((__be32 *) &buf[2]);
> > > -	if (expected > count || expected < 6)
> > > +	if (expected > count || expected < 8)
> > >  		return -EIO;
> > > 
> > > -	memcpy_fromio(&buf[6], &priv->rsp[6], expected - 6);
> > > +	memcpy_fromio(&buf[8], &priv->rsp[8], expected - 8);
> > 
> > Why not just use readl() or readq() ?
> > 
> > Bound to generate better code.
> 
> For the first read can be done. The second read is of variable
> length.

Neither can be done to the first one, because readq() does
le64_to_cpu(). Shoud not do any conversions, only raw read.
So I'll just stick it to what we have.

/jarkko

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv():
  2019-02-04 12:17 ` David Laight
@ 2019-02-05 10:44   ` Jarkko Sakkinen
  2019-02-05 10:47     ` Jarkko Sakkinen
  0 siblings, 1 reply; 15+ messages in thread
From: Jarkko Sakkinen @ 2019-02-05 10:44 UTC (permalink / raw)
  To: David Laight
  Cc: linux-kernel, linux-integrity, linux-security-module, stable,
	Linus Torvalds, James Morris, Tomas Winkler, Jerry Snitselaar

On Mon, Feb 04, 2019 at 12:17:43PM +0000, David Laight wrote:
> From: Jarkko Sakkinen
> > Sent: 01 February 2019 11:20
> > The current approach to read first 6 bytes from the response and then tail
> > of the response, can cause the 2nd memcpy_fromio() to do an unaligned read
> > (e.g. read 32-bit word from address aligned to a 16-bits), depending on how
> > memcpy_fromio() is implemented. If this happens, the read will fail and the
> > memory controller will fill the read with 1's.
> 
> To my mind memcpy_to/fromio() should only be used on IO addresses that are
> adequately like memory, and should be implemented in a way that that won't
> generate invalid bus cycles.
> Also memcpy_fromio() should also be allowed to do 'aligned' accesses that
> go beyond the ends of the required memory area.
> 
> ...
> > 
> > -	memcpy_fromio(buf, priv->rsp, 6);
> > +	memcpy_fromio(buf, priv->rsp, 8);
> >  	expected = be32_to_cpup((__be32 *) &buf[2]);
> > -	if (expected > count || expected < 6)
> > +	if (expected > count || expected < 8)
> >  		return -EIO;
> > 
> > -	memcpy_fromio(&buf[6], &priv->rsp[6], expected - 6);
> > +	memcpy_fromio(&buf[8], &priv->rsp[8], expected - 8);
> 
> Why not just use readl() or readq() ?
> 
> Bound to generate better code.

For the first read can be done. The second read is of variable
length.

/Jarkko

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv():
  2019-02-01 11:19 [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv(): Jarkko Sakkinen
                   ` (2 preceding siblings ...)
  2019-02-01 19:20 ` Winkler, Tomas
@ 2019-02-04 12:17 ` David Laight
  2019-02-05 10:44   ` Jarkko Sakkinen
  3 siblings, 1 reply; 15+ messages in thread
From: David Laight @ 2019-02-04 12:17 UTC (permalink / raw)
  To: 'Jarkko Sakkinen', linux-kernel
  Cc: linux-integrity, linux-security-module, stable, Linus Torvalds,
	James Morris, Tomas Winkler, Jerry Snitselaar

From: Jarkko Sakkinen
> Sent: 01 February 2019 11:20
> The current approach to read first 6 bytes from the response and then tail
> of the response, can cause the 2nd memcpy_fromio() to do an unaligned read
> (e.g. read 32-bit word from address aligned to a 16-bits), depending on how
> memcpy_fromio() is implemented. If this happens, the read will fail and the
> memory controller will fill the read with 1's.

To my mind memcpy_to/fromio() should only be used on IO addresses that are
adequately like memory, and should be implemented in a way that that won't
generate invalid bus cycles.
Also memcpy_fromio() should also be allowed to do 'aligned' accesses that
go beyond the ends of the required memory area.

...
> 
> -	memcpy_fromio(buf, priv->rsp, 6);
> +	memcpy_fromio(buf, priv->rsp, 8);
>  	expected = be32_to_cpup((__be32 *) &buf[2]);
> -	if (expected > count || expected < 6)
> +	if (expected > count || expected < 8)
>  		return -EIO;
> 
> -	memcpy_fromio(&buf[6], &priv->rsp[6], expected - 6);
> +	memcpy_fromio(&buf[8], &priv->rsp[8], expected - 8);

Why not just use readl() or readq() ?

Bound to generate better code.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv():
  2019-02-01 17:49 ` Linus Torvalds
@ 2019-02-04 11:47   ` Jarkko Sakkinen
  0 siblings, 0 replies; 15+ messages in thread
From: Jarkko Sakkinen @ 2019-02-04 11:47 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Linux List Kernel Mailing, linux-integrity,
	linux-security-module, stable, James Morris, Tomas Winkler,
	Jerry Snitselaar

On Fri, Feb 01, 2019 at 09:49:05AM -0800, Linus Torvalds wrote:
> On Fri, Feb 1, 2019 at 3:33 AM Jarkko Sakkinen
> <jarkko.sakkinen@linux.intel.com> wrote:
> >
> > Thus, it makes sense to fix this also in tpm_crb, not least because
> > the fix can be then backported to stable kernels and make them more robust
> > when compiled in differing environments.
> 
> Ack, looks sane to me, and should help both the backport and probably
> generate better code too.
> 
> In the meantime, I've committed the iomem.c change with a *long*
> commit message. For all we know, there might be other cases like this
> lurking somewhere else that just happened to work. Plus it's the right
> thing to do anyway.
> 
>                Linus

Great!

Umh, so, should my tpm_crb change committed to 5.0 with the minor changes
implemented suggested by Tomas or not? Can also include it to my 5.1 PR.
Either WFM.

/Jarkko

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv():
  2019-02-01 19:20 ` Winkler, Tomas
@ 2019-02-04 11:44   ` Jarkko Sakkinen
  0 siblings, 0 replies; 15+ messages in thread
From: Jarkko Sakkinen @ 2019-02-04 11:44 UTC (permalink / raw)
  To: Winkler, Tomas
  Cc: linux-kernel, linux-integrity, linux-security-module, stable,
	Linus Torvalds, James Morris, Jerry Snitselaar

On Fri, Feb 01, 2019 at 07:20:42PM +0000, Winkler, Tomas wrote:
> > 
> > The current approach to read first 6 bytes from the response and then tail of
> > the response, can cause the 2nd memcpy_fromio() to do an unaligned read
> > (e.g. read 32-bit word from address aligned to a 16-bits), depending on how
> > memcpy_fromio() is implemented. If this happens, the read will fail and the
> > memory controller will fill the read with 1's.
> > 
> > This was triggered by 170d13ca3a2f, which should be probably refined to check
> > and react to the address alignment. Before that commit, on x86
> > memcpy_fromio() turned out to be memcpy(). By a luck GCC has done the right
> > thing (from tpm_crb's perspective) for us so far, but we should not rely on that.
> > Thus, it makes sense to fix this also in tpm_crb, not least because the fix can be
> > then backported to stable kernels and make them more robust when compiled
> > in differing environments.
> > 
> > Cc: stable@vger.kernel.org
> > Cc: Linus Torvalds <torvalds@linux-foundation.org>
> > Cc: James Morris <jmorris@namei.org>
> > Cc: Tomas Winkler <tomas.winkler@intel.com>
> > Cc: Jerry Snitselaar <jsnitsel@redhat.com>
> > Fixes: 30fc8d138e91 ("tpm: TPM 2.0 CRB Interface")
> > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> > ---
> >  drivers/char/tpm/tpm_crb.c | 8 ++++----
> >  1 file changed, 4 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index
> > 36952ef98f90..7f47e43aa9f1 100644
> > --- a/drivers/char/tpm/tpm_crb.c
> > +++ b/drivers/char/tpm/tpm_crb.c
> > @@ -288,18 +288,18 @@ static int crb_recv(struct tpm_chip *chip, u8 *buf,
> > size_t count)
> >  	unsigned int expected;
> > 
> >  	/* sanity check */
> > -	if (count < 6)
> > +	if (count < 8)
> >  		return -EIO;
> Why don't you already enforce reading at least the whole TPM header 10bytes, we are reading the whole buffer at one call anyway.
> Who every is asking for 8 bytes from the protocol level, is doing something wrong.
> 
> >  	if (ioread32(&priv->regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR)
> >  		return -EIO;
> > 
> > -	memcpy_fromio(buf, priv->rsp, 6);
> > +	memcpy_fromio(buf, priv->rsp, 8);
> Maybe a short comment will spare someone looking into git history 
> >  	expected = be32_to_cpup((__be32 *) &buf[2]);
> > -	if (expected > count || expected < 6)
> > +	if (expected > count || expected < 8)
> Expected should be at least tpm header, right?
> >  		return -EIO;
> > 
> > -	memcpy_fromio(&buf[6], &priv->rsp[6], expected - 6);
> > +	memcpy_fromio(&buf[8], &priv->rsp[8], expected - 8);
> > 
> >  	return expected;
> >  }
> Otherwise ready the first 8 bytes looks good. 
> Thanks 
> Tomas

Your proposals look sane, thank you.

/Jarkko

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv():
  2019-02-01 11:19 [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv(): Jarkko Sakkinen
  2019-02-01 17:49 ` Linus Torvalds
  2019-02-01 18:42 ` Jerry Snitselaar
@ 2019-02-01 19:20 ` Winkler, Tomas
  2019-02-04 11:44   ` Jarkko Sakkinen
  2019-02-04 12:17 ` David Laight
  3 siblings, 1 reply; 15+ messages in thread
From: Winkler, Tomas @ 2019-02-01 19:20 UTC (permalink / raw)
  To: Jarkko Sakkinen, linux-kernel
  Cc: linux-integrity, linux-security-module, stable, Linus Torvalds,
	James Morris, Jerry Snitselaar

> 
> The current approach to read first 6 bytes from the response and then tail of
> the response, can cause the 2nd memcpy_fromio() to do an unaligned read
> (e.g. read 32-bit word from address aligned to a 16-bits), depending on how
> memcpy_fromio() is implemented. If this happens, the read will fail and the
> memory controller will fill the read with 1's.
> 
> This was triggered by 170d13ca3a2f, which should be probably refined to check
> and react to the address alignment. Before that commit, on x86
> memcpy_fromio() turned out to be memcpy(). By a luck GCC has done the right
> thing (from tpm_crb's perspective) for us so far, but we should not rely on that.
> Thus, it makes sense to fix this also in tpm_crb, not least because the fix can be
> then backported to stable kernels and make them more robust when compiled
> in differing environments.
> 
> Cc: stable@vger.kernel.org
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Cc: James Morris <jmorris@namei.org>
> Cc: Tomas Winkler <tomas.winkler@intel.com>
> Cc: Jerry Snitselaar <jsnitsel@redhat.com>
> Fixes: 30fc8d138e91 ("tpm: TPM 2.0 CRB Interface")
> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> ---
>  drivers/char/tpm/tpm_crb.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index
> 36952ef98f90..7f47e43aa9f1 100644
> --- a/drivers/char/tpm/tpm_crb.c
> +++ b/drivers/char/tpm/tpm_crb.c
> @@ -288,18 +288,18 @@ static int crb_recv(struct tpm_chip *chip, u8 *buf,
> size_t count)
>  	unsigned int expected;
> 
>  	/* sanity check */
> -	if (count < 6)
> +	if (count < 8)
>  		return -EIO;
Why don't you already enforce reading at least the whole TPM header 10bytes, we are reading the whole buffer at one call anyway.
Who every is asking for 8 bytes from the protocol level, is doing something wrong.

>  	if (ioread32(&priv->regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR)
>  		return -EIO;
> 
> -	memcpy_fromio(buf, priv->rsp, 6);
> +	memcpy_fromio(buf, priv->rsp, 8);
Maybe a short comment will spare someone looking into git history 
>  	expected = be32_to_cpup((__be32 *) &buf[2]);
> -	if (expected > count || expected < 6)
> +	if (expected > count || expected < 8)
Expected should be at least tpm header, right?
>  		return -EIO;
> 
> -	memcpy_fromio(&buf[6], &priv->rsp[6], expected - 6);
> +	memcpy_fromio(&buf[8], &priv->rsp[8], expected - 8);
> 
>  	return expected;
>  }
Otherwise ready the first 8 bytes looks good. 
Thanks 
Tomas



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv():
  2019-02-01 11:19 [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv(): Jarkko Sakkinen
  2019-02-01 17:49 ` Linus Torvalds
@ 2019-02-01 18:42 ` Jerry Snitselaar
  2019-02-01 19:20 ` Winkler, Tomas
  2019-02-04 12:17 ` David Laight
  3 siblings, 0 replies; 15+ messages in thread
From: Jerry Snitselaar @ 2019-02-01 18:42 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: linux-kernel, linux-integrity, linux-security-module, stable,
	Linus Torvalds, James Morris, Tomas Winkler

On Fri Feb 01 19, Jarkko Sakkinen wrote:
>The current approach to read first 6 bytes from the response and then tail
>of the response, can cause the 2nd memcpy_fromio() to do an unaligned read
>(e.g. read 32-bit word from address aligned to a 16-bits), depending on how
>memcpy_fromio() is implemented. If this happens, the read will fail and the
>memory controller will fill the read with 1's.
>
>This was triggered by 170d13ca3a2f, which should be probably refined to
>check and react to the address alignment. Before that commit, on x86
>memcpy_fromio() turned out to be memcpy(). By a luck GCC has done the right
>thing (from tpm_crb's perspective) for us so far, but we should not rely on
>that. Thus, it makes sense to fix this also in tpm_crb, not least because
>the fix can be then backported to stable kernels and make them more robust
>when compiled in differing environments.
>
>Cc: stable@vger.kernel.org
>Cc: Linus Torvalds <torvalds@linux-foundation.org>
>Cc: James Morris <jmorris@namei.org>
>Cc: Tomas Winkler <tomas.winkler@intel.com>
>Cc: Jerry Snitselaar <jsnitsel@redhat.com>
>Fixes: 30fc8d138e91 ("tpm: TPM 2.0 CRB Interface")
>Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
>---
> drivers/char/tpm/tpm_crb.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
>diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
>index 36952ef98f90..7f47e43aa9f1 100644
>--- a/drivers/char/tpm/tpm_crb.c
>+++ b/drivers/char/tpm/tpm_crb.c
>@@ -288,18 +288,18 @@ static int crb_recv(struct tpm_chip *chip, u8 *buf, size_t count)
> 	unsigned int expected;
>
> 	/* sanity check */
>-	if (count < 6)
>+	if (count < 8)
> 		return -EIO;
>
> 	if (ioread32(&priv->regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR)
> 		return -EIO;
>
>-	memcpy_fromio(buf, priv->rsp, 6);
>+	memcpy_fromio(buf, priv->rsp, 8);
> 	expected = be32_to_cpup((__be32 *) &buf[2]);
>-	if (expected > count || expected < 6)
>+	if (expected > count || expected < 8)
> 		return -EIO;
>
>-	memcpy_fromio(&buf[6], &priv->rsp[6], expected - 6);
>+	memcpy_fromio(&buf[8], &priv->rsp[8], expected - 8);
>
> 	return expected;
> }
>-- 
>2.17.1
>

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv():
  2019-02-01 11:19 [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv(): Jarkko Sakkinen
@ 2019-02-01 17:49 ` Linus Torvalds
  2019-02-04 11:47   ` Jarkko Sakkinen
  2019-02-01 18:42 ` Jerry Snitselaar
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 15+ messages in thread
From: Linus Torvalds @ 2019-02-01 17:49 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: Linux List Kernel Mailing, linux-integrity,
	linux-security-module, stable, James Morris, Tomas Winkler,
	Jerry Snitselaar

On Fri, Feb 1, 2019 at 3:33 AM Jarkko Sakkinen
<jarkko.sakkinen@linux.intel.com> wrote:
>
> Thus, it makes sense to fix this also in tpm_crb, not least because
> the fix can be then backported to stable kernels and make them more robust
> when compiled in differing environments.

Ack, looks sane to me, and should help both the backport and probably
generate better code too.

In the meantime, I've committed the iomem.c change with a *long*
commit message. For all we know, there might be other cases like this
lurking somewhere else that just happened to work. Plus it's the right
thing to do anyway.

               Linus

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv():
@ 2019-02-01 11:19 Jarkko Sakkinen
  2019-02-01 17:49 ` Linus Torvalds
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Jarkko Sakkinen @ 2019-02-01 11:19 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-integrity, linux-security-module, Jarkko Sakkinen, stable,
	Linus Torvalds, James Morris, Tomas Winkler, Jerry Snitselaar

The current approach to read first 6 bytes from the response and then tail
of the response, can cause the 2nd memcpy_fromio() to do an unaligned read
(e.g. read 32-bit word from address aligned to a 16-bits), depending on how
memcpy_fromio() is implemented. If this happens, the read will fail and the
memory controller will fill the read with 1's.

This was triggered by 170d13ca3a2f, which should be probably refined to
check and react to the address alignment. Before that commit, on x86
memcpy_fromio() turned out to be memcpy(). By a luck GCC has done the right
thing (from tpm_crb's perspective) for us so far, but we should not rely on
that. Thus, it makes sense to fix this also in tpm_crb, not least because
the fix can be then backported to stable kernels and make them more robust
when compiled in differing environments.

Cc: stable@vger.kernel.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: James Morris <jmorris@namei.org>
Cc: Tomas Winkler <tomas.winkler@intel.com>
Cc: Jerry Snitselaar <jsnitsel@redhat.com>
Fixes: 30fc8d138e91 ("tpm: TPM 2.0 CRB Interface")
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 drivers/char/tpm/tpm_crb.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index 36952ef98f90..7f47e43aa9f1 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -288,18 +288,18 @@ static int crb_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 	unsigned int expected;
 
 	/* sanity check */
-	if (count < 6)
+	if (count < 8)
 		return -EIO;
 
 	if (ioread32(&priv->regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR)
 		return -EIO;
 
-	memcpy_fromio(buf, priv->rsp, 6);
+	memcpy_fromio(buf, priv->rsp, 8);
 	expected = be32_to_cpup((__be32 *) &buf[2]);
-	if (expected > count || expected < 6)
+	if (expected > count || expected < 8)
 		return -EIO;
 
-	memcpy_fromio(&buf[6], &priv->rsp[6], expected - 6);
+	memcpy_fromio(&buf[8], &priv->rsp[8], expected - 8);
 
 	return expected;
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2019-04-17 15:42 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-10 13:54 [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv() Jarkko Sakkinen
2019-04-15 10:48 ` Greg KH
2019-04-16  7:25   ` Jarkko Sakkinen
  -- strict thread matches above, loose matches on Subject: below --
2019-04-17 14:59 Jarkko Sakkinen
2019-04-17 15:42 ` Sasha Levin
2019-02-01 11:19 [PATCH] tpm/tpm_crb: Avoid unaligned reads in crb_recv(): Jarkko Sakkinen
2019-02-01 17:49 ` Linus Torvalds
2019-02-04 11:47   ` Jarkko Sakkinen
2019-02-01 18:42 ` Jerry Snitselaar
2019-02-01 19:20 ` Winkler, Tomas
2019-02-04 11:44   ` Jarkko Sakkinen
2019-02-04 12:17 ` David Laight
2019-02-05 10:44   ` Jarkko Sakkinen
2019-02-05 10:47     ` Jarkko Sakkinen
2019-02-05 10:49       ` Jarkko Sakkinen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.