From ac932253898d479ad1259184fa3045b1609cd6b5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 6 Mar 2018 10:25:12 -0800 Subject: [PATCH] 4.14-stable patches 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 --- ...-fix-crash-in-build_skb-rx-code-path.patch | 44 +++++ queue-4.14/series | 8 + .../tpm-constify-transmit-data-pointers.patch | 156 ++++++++++++++++++ ...ns-caused-by-bit-glitches-on-the-bus.patch | 55 ++++++ ...ns-caused-by-bit-glitches-on-the-bus.patch | 49 ++++++ ...ns-caused-by-bit-glitches-on-the-bus.patch | 50 ++++++ ...ns-caused-by-bit-glitches-on-the-bus.patch | 53 ++++++ ...ns-caused-by-bit-glitches-on-the-bus.patch | 51 ++++++ ...se-dma-safe-memory-for-spi-transfers.patch | 129 +++++++++++++++ 9 files changed, 595 insertions(+) create mode 100644 queue-4.14/ixgbe-fix-crash-in-build_skb-rx-code-path.patch create mode 100644 queue-4.14/tpm-constify-transmit-data-pointers.patch create mode 100644 queue-4.14/tpm-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch create mode 100644 queue-4.14/tpm-st33zp24-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch create mode 100644 queue-4.14/tpm_i2c_infineon-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch create mode 100644 queue-4.14/tpm_i2c_nuvoton-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch create mode 100644 queue-4.14/tpm_tis-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch create mode 100644 queue-4.14/tpm_tis_spi-use-dma-safe-memory-for-spi-transfers.patch 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 index 00000000000..ef11fd3b3c9 --- /dev/null +++ b/queue-4.14/ixgbe-fix-crash-in-build_skb-rx-code-path.patch @@ -0,0 +1,44 @@ +From 0c5661ecc5dd7ce296870a3eb7b62b1b280a5e89 Mon Sep 17 00:00:00 2001 +From: Emil Tantilov +Date: Fri, 23 Feb 2018 12:39:41 -0800 +Subject: ixgbe: fix crash in build_skb Rx code path + +From: Emil Tantilov + +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 +Reported-by: Ambarish Soman +Suggested-by: Alexander Duyck +Signed-off-by: Emil Tantilov +Tested-by: Andrew Bowers +Signed-off-by: Jeff Kirsher +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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]; + diff --git a/queue-4.14/series b/queue-4.14/series index 14ea8ac7a17..6a19875c2af 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -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 index 00000000000..a63e6c8b636 --- /dev/null +++ b/queue-4.14/tpm-constify-transmit-data-pointers.patch @@ -0,0 +1,156 @@ +From c37fbc09bd4977736f6bc4050c6f099c587052a7 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Thu, 7 Sep 2017 15:30:45 +0200 +Subject: tpm: constify transmit data pointers + +From: Arnd Bergmann + +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 +Reviewed-by: Jarkko Sakkinen +Tested-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..1a6d146033b --- /dev/null +++ b/queue-4.14/tpm-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch @@ -0,0 +1,55 @@ +From 3be23274755ee85771270a23af7691dc9b3a95db Mon Sep 17 00:00:00 2001 +From: Jeremy Boone +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 + +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 +Cc: stable@vger.kernel.org +Signed-off-by: James Bottomley +Reviewed-by: Jarkko Sakkinen +Tested-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..abace46ccd4 --- /dev/null +++ b/queue-4.14/tpm-st33zp24-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch @@ -0,0 +1,49 @@ +From 6d24cd186d9fead3722108dec1b1c993354645ff Mon Sep 17 00:00:00 2001 +From: Jeremy Boone +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 + +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 +Cc: stable@vger.kernel.org +Signed-off-by: James Bottomley +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..cfb53f35ac4 --- /dev/null +++ b/queue-4.14/tpm_i2c_infineon-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch @@ -0,0 +1,50 @@ +From 9b8cb28d7c62568a5916bdd7ea1c9176d7f8f2ed Mon Sep 17 00:00:00 2001 +From: Jeremy Boone +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 + +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 +Cc: stable@vger.kernel.org +Signed-off-by: James Bottomley +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..22596e753b1 --- /dev/null +++ b/queue-4.14/tpm_i2c_nuvoton-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch @@ -0,0 +1,53 @@ +From f9d4d9b5a5ef2f017bc344fb65a58a902517173b Mon Sep 17 00:00:00 2001 +From: Jeremy Boone +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 + +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 +Cc: stable@vger.kernel.org +Signed-off-by: James Bottomley +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a3f984cb733 --- /dev/null +++ b/queue-4.14/tpm_tis-fix-potential-buffer-overruns-caused-by-bit-glitches-on-the-bus.patch @@ -0,0 +1,51 @@ +From 6bb320ca4a4a7b5b3db8c8d7250cc40002046878 Mon Sep 17 00:00:00 2001 +From: Jeremy Boone +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 + +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 +Cc: stable@vger.kernel.org +Signed-off-by: James Bottomley +Tested-by: Jarkko Sakkinen +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..8e021c6b015 --- /dev/null +++ b/queue-4.14/tpm_tis_spi-use-dma-safe-memory-for-spi-transfers.patch @@ -0,0 +1,129 @@ +From 6b3a13173f23e798e1ba213dd4a2c065a3b8d751 Mon Sep 17 00:00:00 2001 +From: Alexander Steffen +Date: Mon, 11 Sep 2017 12:26:52 +0200 +Subject: tpm_tis_spi: Use DMA-safe memory for SPI transfers + +From: Alexander Steffen + +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 +Signed-off-by: Alexander Steffen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + } -- 2.47.3