public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] tpmdd fixes for Linux 4.9 stable branch
@ 2018-03-05  8:20 Jarkko Sakkinen
  2018-03-05  8:20 ` [PATCH 1/3] tpm: constify transmit data pointers Jarkko Sakkinen
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Jarkko Sakkinen @ 2018-03-05  8:20 UTC (permalink / raw)
  To: stable; +Cc: Arnd Bergmann, Alexander Steffen, Jarkko Sakkinen

Alexader's patches had merge conflicts. This patch set sorts them out.

Alexander Steffen (2):
  tpm_tis_spi: Use DMA-safe memory for SPI transfers
  tpm-dev-common: Reject too short writes

Arnd Bergmann (1):
  tpm: constify transmit data pointers

 drivers/char/tpm/tpm-dev.c      |  6 ++++++
 drivers/char/tpm/tpm_tis.c      |  2 +-
 drivers/char/tpm/tpm_tis_core.c |  4 ++--
 drivers/char/tpm/tpm_tis_core.h |  4 ++--
 drivers/char/tpm/tpm_tis_spi.c  | 48 +++++++++++++++++++++++------------------
 5 files changed, 38 insertions(+), 26 deletions(-)

-- 
2.15.1

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

* [PATCH 1/3] tpm: constify transmit data pointers
  2018-03-05  8:20 [PATCH 0/3] tpmdd fixes for Linux 4.9 stable branch Jarkko Sakkinen
@ 2018-03-05  8:20 ` Jarkko Sakkinen
  2018-03-05  8:20 ` [PATCH 2/3] tpm_tis_spi: Use DMA-safe memory for SPI transfers Jarkko Sakkinen
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Jarkko Sakkinen @ 2018-03-05  8:20 UTC (permalink / raw)
  To: stable; +Cc: Arnd Bergmann, Alexander Steffen, Jarkko Sakkinen

From: Arnd Bergmann <arnd@arndb.de>

commit c37fbc09bd4977736f6bc4050c6f099c587052a7 upstream.

Making cmd_getticks 'const' introduced a couple of harmless warnings:

drivers/char/tpm/tpm_tis_core.c: In function 'probe_itpm':
drivers/char/tpm/tpm_tis_core.c:469:31: error: passing argument 2 of 'tpm_tis_send_data' discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
  rc = tpm_tis_send_data(chip, cmd_getticks, len);
drivers/char/tpm/tpm_tis_core.c:477:31: error: passing argument 2 of 'tpm_tis_send_data' discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
  rc = tpm_tis_send_data(chip, cmd_getticks, len);
drivers/char/tpm/tpm_tis_core.c:255:12: note: expected 'u8 * {aka unsigned char *}' but argument is of type 'const u8 * {aka const unsigned char *}'
 static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)

This changes the related functions to all take 'const' pointers
so that gcc can see this as being correct. I had to slightly
modify the logic around tpm_tis_spi_transfer() for this to work
without introducing ugly casts.

Cc: stable@vger.kernel.org
Fixes: 5e35bd8e06b9 ("tpm_tis: make array cmd_getticks static const to shink object code size")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 drivers/char/tpm/tpm_tis.c      |  2 +-
 drivers/char/tpm/tpm_tis_core.c |  4 ++--
 drivers/char/tpm/tpm_tis_core.h |  4 ++--
 drivers/char/tpm/tpm_tis_spi.c  | 25 +++++++++++--------------
 4 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 8022bea27fed..06173d2e316f 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -98,7 +98,7 @@ static int tpm_tcg_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
 }
 
 static int tpm_tcg_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
-			       u8 *value)
+			       const u8 *value)
 {
 	struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
 
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 4d24ec3d7cd6..8c9bd4b80a43 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -256,7 +256,7 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
  * tpm.c can skip polling for the data to be available as the interrupt is
  * waited for here
  */
-static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
+static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
 {
 	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
 	int rc, status, burstcnt;
@@ -345,7 +345,7 @@ static void disable_interrupts(struct tpm_chip *chip)
  * tpm.c can skip polling for the data to be available as the interrupt is
  * waited for here
  */
-static int tpm_tis_send_main(struct tpm_chip *chip, u8 *buf, size_t len)
+static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
 {
 	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
 	int rc;
diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
index 9191aabbf9c2..e1c2193f2ed3 100644
--- a/drivers/char/tpm/tpm_tis_core.h
+++ b/drivers/char/tpm/tpm_tis_core.h
@@ -98,7 +98,7 @@ struct tpm_tis_phy_ops {
 	int (*read_bytes)(struct tpm_tis_data *data, u32 addr, u16 len,
 			  u8 *result);
 	int (*write_bytes)(struct tpm_tis_data *data, u32 addr, u16 len,
-			   u8 *value);
+			   const u8 *value);
 	int (*read16)(struct tpm_tis_data *data, u32 addr, u16 *result);
 	int (*read32)(struct tpm_tis_data *data, u32 addr, u32 *result);
 	int (*write32)(struct tpm_tis_data *data, u32 addr, u32 src);
@@ -128,7 +128,7 @@ static inline int tpm_tis_read32(struct tpm_tis_data *data, u32 addr,
 }
 
 static inline int tpm_tis_write_bytes(struct tpm_tis_data *data, u32 addr,
-				      u16 len, u8 *value)
+				      u16 len, const u8 *value)
 {
 	return data->phy_ops->write_bytes(data, addr, len, value);
 }
diff --git a/drivers/char/tpm/tpm_tis_spi.c b/drivers/char/tpm/tpm_tis_spi.c
index 3b97b14c3417..1a09a7491019 100644
--- a/drivers/char/tpm/tpm_tis_spi.c
+++ b/drivers/char/tpm/tpm_tis_spi.c
@@ -58,7 +58,7 @@ static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data *da
 }
 
 static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
-				u8 *buffer, u8 direction)
+				u8 *in, const u8 *out)
 {
 	struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data);
 	int ret = 0;
@@ -72,7 +72,7 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
 	while (len) {
 		transfer_len = min_t(u16, len, MAX_SPI_FRAMESIZE);
 
-		phy->tx_buf[0] = direction | (transfer_len - 1);
+		phy->tx_buf[0] = (in ? 0x80 : 0) | (transfer_len - 1);
 		phy->tx_buf[1] = 0xd4;
 		phy->tx_buf[2] = addr >> 8;
 		phy->tx_buf[3] = addr;
@@ -113,14 +113,8 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
 		spi_xfer.cs_change = 0;
 		spi_xfer.len = transfer_len;
 		spi_xfer.delay_usecs = 5;
-
-		if (direction) {
-			spi_xfer.tx_buf = NULL;
-			spi_xfer.rx_buf = buffer;
-		} else {
-			spi_xfer.tx_buf = buffer;
-			spi_xfer.rx_buf = NULL;
-		}
+		spi_xfer.tx_buf = out;
+		spi_xfer.rx_buf = in;
 
 		spi_message_init(&m);
 		spi_message_add_tail(&spi_xfer, &m);
@@ -129,7 +123,10 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
 			goto exit;
 
 		len -= transfer_len;
-		buffer += transfer_len;
+		if (in)
+			in += transfer_len;
+		if (out)
+			out += transfer_len;
 	}
 
 exit:
@@ -140,13 +137,13 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
 static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr,
 				  u16 len, u8 *result)
 {
-	return tpm_tis_spi_transfer(data, addr, len, result, 0x80);
+	return tpm_tis_spi_transfer(data, addr, len, result, NULL);
 }
 
 static int tpm_tis_spi_write_bytes(struct tpm_tis_data *data, u32 addr,
-				   u16 len, u8 *value)
+				   u16 len, const u8 *value)
 {
-	return tpm_tis_spi_transfer(data, addr, len, value, 0);
+	return tpm_tis_spi_transfer(data, addr, len, NULL, value);
 }
 
 static int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result)
-- 
2.15.1

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

* [PATCH 2/3] tpm_tis_spi: Use DMA-safe memory for SPI transfers
  2018-03-05  8:20 [PATCH 0/3] tpmdd fixes for Linux 4.9 stable branch Jarkko Sakkinen
  2018-03-05  8:20 ` [PATCH 1/3] tpm: constify transmit data pointers Jarkko Sakkinen
@ 2018-03-05  8:20 ` Jarkko Sakkinen
  2018-03-05  8:20 ` [PATCH 3/3] tpm-dev-common: Reject too short writes Jarkko Sakkinen
  2018-03-06 18:22 ` [PATCH 0/3] tpmdd fixes for Linux 4.9 stable branch Greg KH
  3 siblings, 0 replies; 5+ messages in thread
From: Jarkko Sakkinen @ 2018-03-05  8:20 UTC (permalink / raw)
  To: stable; +Cc: Arnd Bergmann, Alexander Steffen, Jarkko Sakkinen

From: Alexander Steffen <Alexander.Steffen@infineon.com>

commit 6b3a13173f23e798e1ba213dd4a2c065a3b8d751 upstream

The buffers used as tx_buf/rx_buf in a SPI transfer need to be DMA-safe.
This cannot be guaranteed for the buffers passed to tpm_tis_spi_read_bytes
and tpm_tis_spi_write_bytes. Therefore, we need to use our own DMA-safe
buffer and copy the data to/from it.

The buffer needs to be allocated separately, to ensure that it is
cacheline-aligned and not shared with other data, so that DMA can work
correctly.

Fixes: 0edbfea537d1 ("tpm/tpm_tis_spi: Add support for spi phy")
Cc: stable@vger.kernel.org
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: Alexander Steffen <Alexander.Steffen@infineon.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 drivers/char/tpm/tpm_tis_spi.c | 45 +++++++++++++++++++++++++-----------------
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/drivers/char/tpm/tpm_tis_spi.c b/drivers/char/tpm/tpm_tis_spi.c
index 1a09a7491019..01eccb193b5a 100644
--- a/drivers/char/tpm/tpm_tis_spi.c
+++ b/drivers/char/tpm/tpm_tis_spi.c
@@ -47,9 +47,7 @@
 struct tpm_tis_spi_phy {
 	struct tpm_tis_data priv;
 	struct spi_device *spi_device;
-
-	u8 tx_buf[4];
-	u8 rx_buf[4];
+	u8 *iobuf;
 };
 
 static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data *data)
@@ -72,14 +70,14 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
 	while (len) {
 		transfer_len = min_t(u16, len, MAX_SPI_FRAMESIZE);
 
-		phy->tx_buf[0] = (in ? 0x80 : 0) | (transfer_len - 1);
-		phy->tx_buf[1] = 0xd4;
-		phy->tx_buf[2] = addr >> 8;
-		phy->tx_buf[3] = addr;
+		phy->iobuf[0] = (in ? 0x80 : 0) | (transfer_len - 1);
+		phy->iobuf[1] = 0xd4;
+		phy->iobuf[2] = addr >> 8;
+		phy->iobuf[3] = addr;
 
 		memset(&spi_xfer, 0, sizeof(spi_xfer));
-		spi_xfer.tx_buf = phy->tx_buf;
-		spi_xfer.rx_buf = phy->rx_buf;
+		spi_xfer.tx_buf = phy->iobuf;
+		spi_xfer.rx_buf = phy->iobuf;
 		spi_xfer.len = 4;
 		spi_xfer.cs_change = 1;
 
@@ -89,9 +87,9 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
 		if (ret < 0)
 			goto exit;
 
-		if ((phy->rx_buf[3] & 0x01) == 0) {
+		if ((phy->iobuf[3] & 0x01) == 0) {
 			// handle SPI wait states
-			phy->tx_buf[0] = 0;
+			phy->iobuf[0] = 0;
 
 			for (i = 0; i < TPM_RETRY; i++) {
 				spi_xfer.len = 1;
@@ -100,7 +98,7 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
 				ret = spi_sync_locked(phy->spi_device, &m);
 				if (ret < 0)
 					goto exit;
-				if (phy->rx_buf[0] & 0x01)
+				if (phy->iobuf[0] & 0x01)
 					break;
 			}
 
@@ -113,8 +111,14 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
 		spi_xfer.cs_change = 0;
 		spi_xfer.len = transfer_len;
 		spi_xfer.delay_usecs = 5;
-		spi_xfer.tx_buf = out;
-		spi_xfer.rx_buf = in;
+
+		if (in) {
+			spi_xfer.tx_buf = NULL;
+		} else if (out) {
+			spi_xfer.rx_buf = NULL;
+			memcpy(phy->iobuf, out, transfer_len);
+			out += transfer_len;
+		}
 
 		spi_message_init(&m);
 		spi_message_add_tail(&spi_xfer, &m);
@@ -122,11 +126,12 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
 		if (ret < 0)
 			goto exit;
 
-		len -= transfer_len;
-		if (in)
+		if (in) {
+			memcpy(in, phy->iobuf, transfer_len);
 			in += transfer_len;
-		if (out)
-			out += transfer_len;
+		}
+
+		len -= transfer_len;
 	}
 
 exit:
@@ -192,6 +197,10 @@ static int tpm_tis_spi_probe(struct spi_device *dev)
 
 	phy->spi_device = dev;
 
+	phy->iobuf = devm_kmalloc(&dev->dev, MAX_SPI_FRAMESIZE, GFP_KERNEL);
+	if (!phy->iobuf)
+		return -ENOMEM;
+
 	return tpm_tis_core_init(&dev->dev, &phy->priv, -1, &tpm_spi_phy_ops,
 				 NULL);
 }
-- 
2.15.1

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

* [PATCH 3/3] tpm-dev-common: Reject too short writes
  2018-03-05  8:20 [PATCH 0/3] tpmdd fixes for Linux 4.9 stable branch Jarkko Sakkinen
  2018-03-05  8:20 ` [PATCH 1/3] tpm: constify transmit data pointers Jarkko Sakkinen
  2018-03-05  8:20 ` [PATCH 2/3] tpm_tis_spi: Use DMA-safe memory for SPI transfers Jarkko Sakkinen
@ 2018-03-05  8:20 ` Jarkko Sakkinen
  2018-03-06 18:22 ` [PATCH 0/3] tpmdd fixes for Linux 4.9 stable branch Greg KH
  3 siblings, 0 replies; 5+ messages in thread
From: Jarkko Sakkinen @ 2018-03-05  8:20 UTC (permalink / raw)
  To: stable; +Cc: Arnd Bergmann, Alexander Steffen, Jarkko Sakkinen

From: Alexander Steffen <Alexander.Steffen@infineon.com>

commit ee70bc1e7b63ac8023c9ff9475d8741e397316e7 upstream.

tpm_transmit() does not offer an explicit interface to indicate the number
of valid bytes in the communication buffer. Instead, it relies on the
commandSize field in the TPM header that is encoded within the buffer.
Therefore, ensure that a) enough data has been written to the buffer, so
that the commandSize field is present and b) the commandSize field does not
announce more data than has been written to the buffer.

This should have been fixed with CVE-2011-1161 long ago, but apparently
a correct version of that patch never made it into the kernel.

Cc: stable@vger.kernel.org
Signed-off-by: Alexander Steffen <Alexander.Steffen@infineon.com>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 drivers/char/tpm/tpm-dev.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c
index 912ad30be585..65b824954bdc 100644
--- a/drivers/char/tpm/tpm-dev.c
+++ b/drivers/char/tpm/tpm-dev.c
@@ -136,6 +136,12 @@ static ssize_t tpm_write(struct file *file, const char __user *buf,
 		return -EFAULT;
 	}
 
+	if (in_size < 6 ||
+	    in_size < be32_to_cpu(*((__be32 *) (priv->data_buffer + 2)))) {
+		mutex_unlock(&priv->buffer_mutex);
+		return -EINVAL;
+	}
+
 	/* atomic tpm command send and result receive. We only hold the ops
 	 * lock during this period so that the tpm can be unregistered even if
 	 * the char dev is held open.
-- 
2.15.1

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

* Re: [PATCH 0/3] tpmdd fixes for Linux 4.9 stable branch
  2018-03-05  8:20 [PATCH 0/3] tpmdd fixes for Linux 4.9 stable branch Jarkko Sakkinen
                   ` (2 preceding siblings ...)
  2018-03-05  8:20 ` [PATCH 3/3] tpm-dev-common: Reject too short writes Jarkko Sakkinen
@ 2018-03-06 18:22 ` Greg KH
  3 siblings, 0 replies; 5+ messages in thread
From: Greg KH @ 2018-03-06 18:22 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: stable, Arnd Bergmann, Alexander Steffen

On Mon, Mar 05, 2018 at 10:20:21AM +0200, Jarkko Sakkinen wrote:
> Alexader's patches had merge conflicts. This patch set sorts them out.
> 
> Alexander Steffen (2):
>   tpm_tis_spi: Use DMA-safe memory for SPI transfers
>   tpm-dev-common: Reject too short writes
> 
> Arnd Bergmann (1):
>   tpm: constify transmit data pointers

The first 3 applied from upstream just fine, and the last one was
needed, all now queued up, thanks.

greg k-h

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

end of thread, other threads:[~2018-03-06 18:22 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-03-05  8:20 [PATCH 0/3] tpmdd fixes for Linux 4.9 stable branch Jarkko Sakkinen
2018-03-05  8:20 ` [PATCH 1/3] tpm: constify transmit data pointers Jarkko Sakkinen
2018-03-05  8:20 ` [PATCH 2/3] tpm_tis_spi: Use DMA-safe memory for SPI transfers Jarkko Sakkinen
2018-03-05  8:20 ` [PATCH 3/3] tpm-dev-common: Reject too short writes Jarkko Sakkinen
2018-03-06 18:22 ` [PATCH 0/3] tpmdd fixes for Linux 4.9 stable branch Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox