From 7509fda90e3ba989cde813ad9b2bb85b65f710ae Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Oct 2014 12:33:06 -0700 Subject: [PATCH] 3.10-stable patches added patches: i2c-at91-add-bound-checking-on-smbus-block-length-bytes.patch i2c-at91-fix-a-race-condition-during-signal-handling-in-at91_do_twi_xfer.patch --- ...checking-on-smbus-block-length-bytes.patch | 87 +++++++++++++++++++ ...-signal-handling-in-at91_do_twi_xfer.patch | 47 ++++++++++ queue-3.10/series | 2 + 3 files changed, 136 insertions(+) create mode 100644 queue-3.10/i2c-at91-add-bound-checking-on-smbus-block-length-bytes.patch create mode 100644 queue-3.10/i2c-at91-fix-a-race-condition-during-signal-handling-in-at91_do_twi_xfer.patch diff --git a/queue-3.10/i2c-at91-add-bound-checking-on-smbus-block-length-bytes.patch b/queue-3.10/i2c-at91-add-bound-checking-on-smbus-block-length-bytes.patch new file mode 100644 index 00000000000..245e7994af5 --- /dev/null +++ b/queue-3.10/i2c-at91-add-bound-checking-on-smbus-block-length-bytes.patch @@ -0,0 +1,87 @@ +From 75b81f339c6af43f6f4a1b3eabe0603321dade65 Mon Sep 17 00:00:00 2001 +From: Marek Roszko +Date: Wed, 20 Aug 2014 21:39:41 -0400 +Subject: i2c: at91: add bound checking on SMBus block length bytes + +From: Marek Roszko + +commit 75b81f339c6af43f6f4a1b3eabe0603321dade65 upstream. + +The driver was not bound checking the received length byte to ensure it was within the +the buffer size that is allocated for SMBus blocks. This resulted in buffer overflows +whenever an invalid length byte was received. +It also failed to ensure the length byte was not zero. If it received zero, it would end up +in an infinite loop as the at91_twi_read_next_byte function returned immediately without +allowing RHR to be read to clear the RXRDY interrupt. + +Tested agaisnt a SMBus compliant battery. + +Signed-off-by: Marek Roszko +Acked-by: Ludovic Desroches +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-at91.c | 28 ++++++++++++++++++++++++---- + 1 file changed, 24 insertions(+), 4 deletions(-) + +--- a/drivers/i2c/busses/i2c-at91.c ++++ b/drivers/i2c/busses/i2c-at91.c +@@ -102,6 +102,7 @@ struct at91_twi_dev { + unsigned twi_cwgr_reg; + struct at91_twi_pdata *pdata; + bool use_dma; ++ bool recv_len_abort; + struct at91_twi_dma dma; + }; + +@@ -268,12 +269,24 @@ static void at91_twi_read_next_byte(stru + *dev->buf = at91_twi_read(dev, AT91_TWI_RHR) & 0xff; + --dev->buf_len; + ++ /* return if aborting, we only needed to read RHR to clear RXRDY*/ ++ if (dev->recv_len_abort) ++ return; ++ + /* handle I2C_SMBUS_BLOCK_DATA */ + if (unlikely(dev->msg->flags & I2C_M_RECV_LEN)) { +- dev->msg->flags &= ~I2C_M_RECV_LEN; +- dev->buf_len += *dev->buf; +- dev->msg->len = dev->buf_len + 1; +- dev_dbg(dev->dev, "received block length %d\n", dev->buf_len); ++ /* ensure length byte is a valid value */ ++ if (*dev->buf <= I2C_SMBUS_BLOCK_MAX && *dev->buf > 0) { ++ dev->msg->flags &= ~I2C_M_RECV_LEN; ++ dev->buf_len += *dev->buf; ++ dev->msg->len = dev->buf_len + 1; ++ dev_dbg(dev->dev, "received block length %d\n", ++ dev->buf_len); ++ } else { ++ /* abort and send the stop by reading one more byte */ ++ dev->recv_len_abort = true; ++ dev->buf_len = 1; ++ } + } + + /* send stop if second but last byte has been read */ +@@ -445,6 +458,12 @@ static int at91_do_twi_transfer(struct a + ret = -EIO; + goto error; + } ++ if (dev->recv_len_abort) { ++ dev_err(dev->dev, "invalid smbus block length recvd\n"); ++ ret = -EPROTO; ++ goto error; ++ } ++ + dev_dbg(dev->dev, "transfer complete\n"); + + return 0; +@@ -501,6 +520,7 @@ static int at91_twi_xfer(struct i2c_adap + dev->buf_len = m_start->len; + dev->buf = m_start->buf; + dev->msg = m_start; ++ dev->recv_len_abort = false; + + ret = at91_do_twi_transfer(dev); + diff --git a/queue-3.10/i2c-at91-fix-a-race-condition-during-signal-handling-in-at91_do_twi_xfer.patch b/queue-3.10/i2c-at91-fix-a-race-condition-during-signal-handling-in-at91_do_twi_xfer.patch new file mode 100644 index 00000000000..510a9041f08 --- /dev/null +++ b/queue-3.10/i2c-at91-fix-a-race-condition-during-signal-handling-in-at91_do_twi_xfer.patch @@ -0,0 +1,47 @@ +From 6721f28a26efd6368497abbdef5dcfc59608d899 Mon Sep 17 00:00:00 2001 +From: Simon Lindgren +Date: Tue, 26 Aug 2014 21:13:24 +0200 +Subject: i2c: at91: Fix a race condition during signal handling in at91_do_twi_xfer. + +From: Simon Lindgren + +commit 6721f28a26efd6368497abbdef5dcfc59608d899 upstream. + +There is a race condition in at91_do_twi_xfer when signals arrive. +If a signal is recieved while waiting for a transfer to complete +wait_for_completion_interruptible_timeout() will return -ERESTARTSYS. +This is not handled correctly resulting in interrupts still being +enabled and a transfer being in flight when we return. + +Symptoms include a range of oopses and bus lockups. Oopses can happen +when the transfer completes because the interrupt handler will corrupt +the stack. If a new transfer is started before the interrupt fires +the controller will start a new transfer in the middle of the old one, +resulting in confused slaves and a locked bus. + +To avoid this, use wait_for_completion_io_timeout instead so that we +don't have to deal with gracefully shutting down the transfer and +disabling the interrupts. + +Signed-off-by: Simon Lindgren +Acked-by: Ludovic Desroches +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-at91.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/i2c/busses/i2c-at91.c ++++ b/drivers/i2c/busses/i2c-at91.c +@@ -435,8 +435,8 @@ static int at91_do_twi_transfer(struct a + } + } + +- ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, +- dev->adapter.timeout); ++ ret = wait_for_completion_io_timeout(&dev->cmd_complete, ++ dev->adapter.timeout); + if (ret == 0) { + dev_err(dev->dev, "controller timed out\n"); + at91_init_twi_bus(dev); diff --git a/queue-3.10/series b/queue-3.10/series index 0311f7947b2..fb6761e2734 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -14,3 +14,5 @@ ahci-add-device-ids-for-intel-9-series-pch.patch ahci-add-pcid-for-marvel-0x9182-controller.patch ibmveth-fix-endian-issues-with-rx_no_buffer-statistic.patch arm64-flush-tls-registers-during-exec.patch +i2c-at91-add-bound-checking-on-smbus-block-length-bytes.patch +i2c-at91-fix-a-race-condition-during-signal-handling-in-at91_do_twi_xfer.patch -- 2.47.3