]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 6 Mar 2018 18:25:12 +0000 (10:25 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 6 Mar 2018 18:25:12 +0000 (10:25 -0800)
added patches:
ixgbe-fix-crash-in-build_skb-rx-code-path.patch
tpm-constify-transmit-data-pointers.patch
tpm-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
tpm-st33zp24-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
tpm_i2c_infineon-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
tpm_i2c_nuvoton-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
tpm_tis-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
tpm_tis_spi-use-dma-safe-memory-for-spi-transfers.patch

queue-4.14/ixgbe-fix-crash-in-build_skb-rx-code-path.patch [new file with mode: 0644]
queue-4.14/series
queue-4.14/tpm-constify-transmit-data-pointers.patch [new file with mode: 0644]
queue-4.14/tpm-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch [new file with mode: 0644]
queue-4.14/tpm-st33zp24-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch [new file with mode: 0644]
queue-4.14/tpm_i2c_infineon-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch [new file with mode: 0644]
queue-4.14/tpm_i2c_nuvoton-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch [new file with mode: 0644]
queue-4.14/tpm_tis-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch [new file with mode: 0644]
queue-4.14/tpm_tis_spi-use-dma-safe-memory-for-spi-transfers.patch [new file with mode: 0644]

diff --git a/queue-4.14/ixgbe-fix-crash-in-build_skb-rx-code-path.patch b/queue-4.14/ixgbe-fix-crash-in-build_skb-rx-code-path.patch
new file mode 100644 (file)
index 0000000..ef11fd3
--- /dev/null
@@ -0,0 +1,44 @@
+From 0c5661ecc5dd7ce296870a3eb7b62b1b280a5e89 Mon Sep 17 00:00:00 2001
+From: Emil Tantilov <emil.s.tantilov@intel.com>
+Date: Fri, 23 Feb 2018 12:39:41 -0800
+Subject: ixgbe: fix crash in build_skb Rx code path
+
+From: Emil Tantilov <emil.s.tantilov@intel.com>
+
+commit 0c5661ecc5dd7ce296870a3eb7b62b1b280a5e89 upstream.
+
+Add check for build_skb enabled ring in ixgbe_dma_sync_frag().
+In that case &skb_shinfo(skb)->frags[0] may not always be set which
+can lead to a crash. Instead we derive the page offset from skb->data.
+
+Fixes: 42073d91a214 ("ixgbe: Have the CPU take ownership of the buffers sooner")
+CC: stable <stable@vger.kernel.org>
+Reported-by: Ambarish Soman <asoman@redhat.com>
+Suggested-by: Alexander Duyck <alexander.h.duyck@intel.com>
+Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
+Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+@@ -1877,6 +1877,14 @@ static void ixgbe_dma_sync_frag(struct i
+                                    ixgbe_rx_pg_size(rx_ring),
+                                    DMA_FROM_DEVICE,
+                                    IXGBE_RX_DMA_ATTR);
++      } else if (ring_uses_build_skb(rx_ring)) {
++              unsigned long offset = (unsigned long)(skb->data) & ~PAGE_MASK;
++
++              dma_sync_single_range_for_cpu(rx_ring->dev,
++                                            IXGBE_CB(skb)->dma,
++                                            offset,
++                                            skb_headlen(skb),
++                                            DMA_FROM_DEVICE);
+       } else {
+               struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[0];
index 14ea8ac7a1784541c2b8c5de8ffb2aacc1c7d1db..6a19875c2af1eb6ab735528c555baff8abfb4bc1 100644 (file)
@@ -1 +1,9 @@
 bluetooth-btusb-use-dmi-matching-for-qca-reset_resume-quirking.patch
+ixgbe-fix-crash-in-build_skb-rx-code-path.patch
+tpm-st33zp24-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
+tpm-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
+tpm_i2c_infineon-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
+tpm_i2c_nuvoton-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
+tpm_tis-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
+tpm-constify-transmit-data-pointers.patch
+tpm_tis_spi-use-dma-safe-memory-for-spi-transfers.patch
diff --git a/queue-4.14/tpm-constify-transmit-data-pointers.patch b/queue-4.14/tpm-constify-transmit-data-pointers.patch
new file mode 100644 (file)
index 0000000..a63e6c8
--- /dev/null
@@ -0,0 +1,156 @@
+From c37fbc09bd4977736f6bc4050c6f099c587052a7 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Thu, 7 Sep 2017 15:30:45 +0200
+Subject: tpm: constify transmit data pointers
+
+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>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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(-)
+
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -223,7 +223,7 @@ static int tpm_tcg_read_bytes(struct tpm
+ }
+ 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);
+--- a/drivers/char/tpm/tpm_tis_core.c
++++ b/drivers/char/tpm/tpm_tis_core.c
+@@ -253,7 +253,7 @@ out:
+  * 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;
+@@ -344,7 +344,7 @@ static void disable_interrupts(struct tp
+  * 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;
+--- 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
+ }
+ 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);
+ }
+--- a/drivers/char/tpm/tpm_tis_spi.c
++++ b/drivers/char/tpm/tpm_tis_spi.c
+@@ -57,7 +57,7 @@ static inline struct tpm_tis_spi_phy *to
+ }
+ 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;
+@@ -71,7 +71,7 @@ static int tpm_tis_spi_transfer(struct t
+       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;
+@@ -112,14 +112,8 @@ static int tpm_tis_spi_transfer(struct t
+               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);
+@@ -128,7 +122,10 @@ static int tpm_tis_spi_transfer(struct t
+                       goto exit;
+               len -= transfer_len;
+-              buffer += transfer_len;
++              if (in)
++                      in += transfer_len;
++              if (out)
++                      out += transfer_len;
+       }
+ exit:
+@@ -139,13 +136,13 @@ exit:
+ 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)
diff --git a/queue-4.14/tpm-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch b/queue-4.14/tpm-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
new file mode 100644 (file)
index 0000000..1a6d146
--- /dev/null
@@ -0,0 +1,55 @@
+From 3be23274755ee85771270a23af7691dc9b3a95db Mon Sep 17 00:00:00 2001
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Date: Thu, 8 Feb 2018 12:28:08 -0800
+Subject: tpm: fix potential buffer overruns caused by bit glitches on the bus
+
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+
+commit 3be23274755ee85771270a23af7691dc9b3a95db upstream.
+
+Discrete TPMs are often connected over slow serial buses which, on
+some platforms, can have glitches causing bit flips.  If a bit does
+flip it could cause an overrun if it's in one of the size parameters,
+so sanity check that we're not overrunning the provided buffer when
+doing a memcpy().
+
+Signed-off-by: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Cc: stable@vger.kernel.org
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.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>
+Signed-off-by: James Morris <james.morris@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm-interface.c |    4 ++++
+ drivers/char/tpm/tpm2-cmd.c      |    4 ++++
+ 2 files changed, 8 insertions(+)
+
+--- a/drivers/char/tpm/tpm-interface.c
++++ b/drivers/char/tpm/tpm-interface.c
+@@ -1228,6 +1228,10 @@ int tpm_get_random(u32 chip_num, u8 *out
+                       break;
+               recd = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len);
++              if (recd > num_bytes) {
++                      total = -EFAULT;
++                      break;
++              }
+               rlength = be32_to_cpu(tpm_cmd.header.out.length);
+               if (rlength < offsetof(struct tpm_getrandom_out, rng_data) +
+--- a/drivers/char/tpm/tpm2-cmd.c
++++ b/drivers/char/tpm/tpm2-cmd.c
+@@ -683,6 +683,10 @@ static int tpm2_unseal_cmd(struct tpm_ch
+       if (!rc) {
+               data_len = be16_to_cpup(
+                       (__be16 *) &buf.data[TPM_HEADER_SIZE + 4]);
++              if (data_len < MIN_KEY_SIZE ||  data_len > MAX_KEY_SIZE + 1) {
++                      rc = -EFAULT;
++                      goto out;
++              }
+               rlength = be32_to_cpu(((struct tpm2_cmd *)&buf)
+                                       ->header.out.length);
diff --git a/queue-4.14/tpm-st33zp24-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch b/queue-4.14/tpm-st33zp24-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
new file mode 100644 (file)
index 0000000..abace46
--- /dev/null
@@ -0,0 +1,49 @@
+From 6d24cd186d9fead3722108dec1b1c993354645ff Mon Sep 17 00:00:00 2001
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Date: Thu, 8 Feb 2018 12:29:09 -0800
+Subject: tpm: st33zp24: fix potential buffer overruns caused by bit glitches on the bus
+
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+
+commit 6d24cd186d9fead3722108dec1b1c993354645ff upstream.
+
+Discrete TPMs are often connected over slow serial buses which, on
+some platforms, can have glitches causing bit flips.  In all the
+driver _recv() functions, we need to use a u32 to unmarshal the
+response size, otherwise a bit flip of the 31st bit would cause the
+expected variable to go negative, which would then try to read a huge
+amount of data.  Also sanity check that the expected amount of data is
+large enough for the TPM header.
+
+Signed-off-by: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Cc: stable@vger.kernel.org
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: James Morris <james.morris@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/st33zp24/st33zp24.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/tpm/st33zp24/st33zp24.c
++++ b/drivers/char/tpm/st33zp24/st33zp24.c
+@@ -457,7 +457,7 @@ static int st33zp24_recv(struct tpm_chip
+                           size_t count)
+ {
+       int size = 0;
+-      int expected;
++      u32 expected;
+       if (!chip)
+               return -EBUSY;
+@@ -474,7 +474,7 @@ static int st33zp24_recv(struct tpm_chip
+       }
+       expected = be32_to_cpu(*(__be32 *)(buf + 2));
+-      if (expected > count) {
++      if (expected > count || expected < TPM_HEADER_SIZE) {
+               size = -EIO;
+               goto out;
+       }
diff --git a/queue-4.14/tpm_i2c_infineon-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch b/queue-4.14/tpm_i2c_infineon-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
new file mode 100644 (file)
index 0000000..cfb53f3
--- /dev/null
@@ -0,0 +1,50 @@
+From 9b8cb28d7c62568a5916bdd7ea1c9176d7f8f2ed Mon Sep 17 00:00:00 2001
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Date: Thu, 8 Feb 2018 12:30:01 -0800
+Subject: tpm_i2c_infineon: fix potential buffer overruns caused by bit glitches on the bus
+
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+
+commit 9b8cb28d7c62568a5916bdd7ea1c9176d7f8f2ed upstream.
+
+Discrete TPMs are often connected over slow serial buses which, on
+some platforms, can have glitches causing bit flips.  In all the
+driver _recv() functions, we need to use a u32 to unmarshal the
+response size, otherwise a bit flip of the 31st bit would cause the
+expected variable to go negative, which would then try to read a huge
+amount of data.  Also sanity check that the expected amount of data is
+large enough for the TPM header.
+
+Signed-off-by: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Cc: stable@vger.kernel.org
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: James Morris <james.morris@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm_i2c_infineon.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/tpm/tpm_i2c_infineon.c
++++ b/drivers/char/tpm/tpm_i2c_infineon.c
+@@ -473,7 +473,8 @@ static int recv_data(struct tpm_chip *ch
+ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
+ {
+       int size = 0;
+-      int expected, status;
++      int status;
++      u32 expected;
+       if (count < TPM_HEADER_SIZE) {
+               size = -EIO;
+@@ -488,7 +489,7 @@ static int tpm_tis_i2c_recv(struct tpm_c
+       }
+       expected = be32_to_cpu(*(__be32 *)(buf + 2));
+-      if ((size_t) expected > count) {
++      if (((size_t) expected > count) || (expected < TPM_HEADER_SIZE)) {
+               size = -EIO;
+               goto out;
+       }
diff --git a/queue-4.14/tpm_i2c_nuvoton-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch b/queue-4.14/tpm_i2c_nuvoton-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
new file mode 100644 (file)
index 0000000..22596e7
--- /dev/null
@@ -0,0 +1,53 @@
+From f9d4d9b5a5ef2f017bc344fb65a58a902517173b Mon Sep 17 00:00:00 2001
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Date: Thu, 8 Feb 2018 12:31:16 -0800
+Subject: tpm_i2c_nuvoton: fix potential buffer overruns caused by bit glitches on the bus
+
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+
+commit f9d4d9b5a5ef2f017bc344fb65a58a902517173b upstream.
+
+Discrete TPMs are often connected over slow serial buses which, on
+some platforms, can have glitches causing bit flips.  In all the
+driver _recv() functions, we need to use a u32 to unmarshal the
+response size, otherwise a bit flip of the 31st bit would cause the
+expected variable to go negative, which would then try to read a huge
+amount of data.  Also sanity check that the expected amount of data is
+large enough for the TPM header.
+
+Signed-off-by: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Cc: stable@vger.kernel.org
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: James Morris <james.morris@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm_i2c_nuvoton.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/tpm/tpm_i2c_nuvoton.c
++++ b/drivers/char/tpm/tpm_i2c_nuvoton.c
+@@ -281,7 +281,11 @@ static int i2c_nuvoton_recv(struct tpm_c
+       struct device *dev = chip->dev.parent;
+       struct i2c_client *client = to_i2c_client(dev);
+       s32 rc;
+-      int expected, status, burst_count, retries, size = 0;
++      int status;
++      int burst_count;
++      int retries;
++      int size = 0;
++      u32 expected;
+       if (count < TPM_HEADER_SIZE) {
+               i2c_nuvoton_ready(chip);    /* return to idle */
+@@ -323,7 +327,7 @@ static int i2c_nuvoton_recv(struct tpm_c
+                * to machine native
+                */
+               expected = be32_to_cpu(*(__be32 *) (buf + 2));
+-              if (expected > count) {
++              if (expected > count || expected < size) {
+                       dev_err(dev, "%s() expected > count\n", __func__);
+                       size = -EIO;
+                       continue;
diff --git a/queue-4.14/tpm_tis-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch b/queue-4.14/tpm_tis-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch
new file mode 100644 (file)
index 0000000..a3f984c
--- /dev/null
@@ -0,0 +1,51 @@
+From 6bb320ca4a4a7b5b3db8c8d7250cc40002046878 Mon Sep 17 00:00:00 2001
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Date: Thu, 8 Feb 2018 12:32:06 -0800
+Subject: tpm_tis: fix potential buffer overruns caused by bit glitches on the bus
+
+From: Jeremy Boone <jeremy.boone@nccgroup.trust>
+
+commit 6bb320ca4a4a7b5b3db8c8d7250cc40002046878 upstream.
+
+Discrete TPMs are often connected over slow serial buses which, on
+some platforms, can have glitches causing bit flips.  In all the
+driver _recv() functions, we need to use a u32 to unmarshal the
+response size, otherwise a bit flip of the 31st bit would cause the
+expected variable to go negative, which would then try to read a huge
+amount of data.  Also sanity check that the expected amount of data is
+large enough for the TPM header.
+
+Signed-off-by: Jeremy Boone <jeremy.boone@nccgroup.trust>
+Cc: stable@vger.kernel.org
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: James Morris <james.morris@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm_tis_core.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/tpm/tpm_tis_core.c
++++ b/drivers/char/tpm/tpm_tis_core.c
+@@ -202,7 +202,8 @@ static int tpm_tis_recv(struct tpm_chip
+ {
+       struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+       int size = 0;
+-      int expected, status;
++      int status;
++      u32 expected;
+       if (count < TPM_HEADER_SIZE) {
+               size = -EIO;
+@@ -217,7 +218,7 @@ static int tpm_tis_recv(struct tpm_chip
+       }
+       expected = be32_to_cpu(*(__be32 *) (buf + 2));
+-      if (expected > count) {
++      if (expected > count || expected < TPM_HEADER_SIZE) {
+               size = -EIO;
+               goto out;
+       }
diff --git a/queue-4.14/tpm_tis_spi-use-dma-safe-memory-for-spi-transfers.patch b/queue-4.14/tpm_tis_spi-use-dma-safe-memory-for-spi-transfers.patch
new file mode 100644 (file)
index 0000000..8e021c6
--- /dev/null
@@ -0,0 +1,129 @@
+From 6b3a13173f23e798e1ba213dd4a2c065a3b8d751 Mon Sep 17 00:00:00 2001
+From: Alexander Steffen <Alexander.Steffen@infineon.com>
+Date: Mon, 11 Sep 2017 12:26:52 +0200
+Subject: tpm_tis_spi: Use DMA-safe memory for SPI transfers
+
+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>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm_tis_spi.c |   45 ++++++++++++++++++++++++-----------------
+ 1 file changed, 27 insertions(+), 18 deletions(-)
+
+--- a/drivers/char/tpm/tpm_tis_spi.c
++++ b/drivers/char/tpm/tpm_tis_spi.c
+@@ -46,9 +46,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)
+@@ -71,14 +69,14 @@ static int tpm_tis_spi_transfer(struct t
+       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;
+@@ -88,9 +86,9 @@ static int tpm_tis_spi_transfer(struct t
+               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;
+@@ -99,7 +97,7 @@ static int tpm_tis_spi_transfer(struct t
+                               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;
+                       }
+@@ -112,8 +110,14 @@ static int tpm_tis_spi_transfer(struct t
+               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);
+@@ -121,11 +125,12 @@ static int tpm_tis_spi_transfer(struct t
+               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:
+@@ -191,6 +196,10 @@ static int tpm_tis_spi_probe(struct spi_
+       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);
+ }