* [PATCH] i2c:at91: add bound checking on smbus block length bytes
@ 2014-07-04 7:03 Marek Roszko
[not found] ` <1404457391-22330-1-git-send-email-mark.roszko-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
0 siblings, 1 reply; 3+ messages in thread
From: Marek Roszko @ 2014-07-04 7:03 UTC (permalink / raw)
To: ludovic.desroches-AIFe0yeh4nAAvxtiuMwx3w
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
wsa-z923LK4zBo2bacvFa/9K2g, nicolas.ferre-AIFe0yeh4nAAvxtiuMwx3w,
Marek Roszko
The driver was not bound checking the recieved length byte to ensure it was less than
the buffer size that is allocated for smbus blocks. This resulted in buffer overflows
whenever an invalid byte was recieved.
It also failed to ensure the byte count was not zero. If it recieved 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 battery.
Signed-off-by: Marek Roszko <mark.roszko-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
drivers/i2c/busses/i2c-at91.c | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index e95f9ba..ec4ff33 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -101,6 +101,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;
};
@@ -267,12 +268,24 @@ static void at91_twi_read_next_byte(struct at91_twi_dev *dev)
*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 */
@@ -444,6 +457,12 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
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;
@@ -500,6 +519,7 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
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);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] i2c:at91: add bound checking on smbus block length bytes
[not found] ` <1404457391-22330-1-git-send-email-mark.roszko-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2014-08-04 16:29 ` Mark Roszko
[not found] ` <CAJjB1qJvvaO3PtN5dMAAAeABS5YMmRc1VRwKo6G_ZuDuo6L15g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 3+ messages in thread
From: Mark Roszko @ 2014-08-04 16:29 UTC (permalink / raw)
To: Ludovic Desroches
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
<linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org> mailing list,
Wolfram Sang, Nicolas Ferre, Marek Roszko
Hi Ludovic,
Have you had a chance to look? This causes kernel panic in at91 systems in
noisy environments and/or unreliable smbus slaves if left unfixed.
Regards,
Mark
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] i2c:at91: add bound checking on smbus block length bytes
[not found] ` <CAJjB1qJvvaO3PtN5dMAAAeABS5YMmRc1VRwKo6G_ZuDuo6L15g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2014-08-06 11:53 ` Ludovic Desroches
0 siblings, 0 replies; 3+ messages in thread
From: Ludovic Desroches @ 2014-08-06 11:53 UTC (permalink / raw)
To: Mark Roszko
Cc: Ludovic Desroches, linux-i2c-u79uwXL29TY76Z2rM5mHXA,
<linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org> mailing list,
Wolfram Sang, Nicolas Ferre
Hi Mark,
On Mon, Aug 04, 2014 at 12:29:56PM -0400, Mark Roszko wrote:
> Hi Ludovic,
>
> Have you had a chance to look? This causes kernel panic in at91 systems in
> noisy environments and/or unreliable smbus slaves if left unfixed.
Thanks for the reminder, I had totally missed this patch.
Seems good, no objection to include this patch.
Only one comment: s/recieved/received otherwise
Acked-By: Ludovic Desroches <ludovic.desroches-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>
Sorry for the delay.
Ludovic
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-08-06 11:53 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-04 7:03 [PATCH] i2c:at91: add bound checking on smbus block length bytes Marek Roszko
[not found] ` <1404457391-22330-1-git-send-email-mark.roszko-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2014-08-04 16:29 ` Mark Roszko
[not found] ` <CAJjB1qJvvaO3PtN5dMAAAeABS5YMmRc1VRwKo6G_ZuDuo6L15g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-08-06 11:53 ` Ludovic Desroches
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).