linux-i2c.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Fix Bug for cadence i2c interrupt overrunning buffer
@ 2017-09-16  3:02 Andrew Worsley
  2017-10-05 12:01 ` Wolfram Sang
  0 siblings, 1 reply; 14+ messages in thread
From: Andrew Worsley @ 2017-09-16  3:02 UTC (permalink / raw)
  To: michal.simek; +Cc: soren.brinkmann, linux-arm-kernel, linux-i2c, Andrew Worsley

The i2c interrupt handler was not checking against the length of
supplied buffer so if the hardware supplied more data than requested in
the i2c transfer it happily copies it right past the end of the buffer!

Signed-off-by: Andrew Worsley <amworsley@gmail.com>
---

  This bug reliably caused a stack corruption when the hardware provided more data than
asked for in the i2c request. The hardware (a tpm) very occasionally appends a burst of
0xff to the end of the data requested and the i2c interrupt handler mindlessly copies all
the data right past the end of the buffer and in my case across the stack. :-(

  With this patch the transfer now terminates with an -EIO but with out voilating the
buffer boundaries. I would prefer to just make the transfer succeed while not retrieving
additional bytes but I wasn't able to find an easy way to do this. As this is definitely a
fault that causes a kernel oops I just wanted to get a fix out there for others to avoid
the problem as it has taken me a few weeks to chase down this oops. If someone has a
better or nicer fix I would appreciate it or a pointer to how to do this.

    Thanks

    Andrew
 drivers/i2c/busses/i2c-cadence.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
index b13605718291..c1f61ca6843e 100644
--- a/drivers/i2c/busses/i2c-cadence.c
+++ b/drivers/i2c/busses/i2c-cadence.c
@@ -234,6 +234,7 @@ static irqreturn_t cdns_i2c_isr(int irq, void *ptr)
 	if (id->p_recv_buf &&
 	    ((isr_status & CDNS_I2C_IXR_COMP) ||
 	     (isr_status & CDNS_I2C_IXR_DATA))) {
+		unsigned char *p = id->p_recv_buf;
 		/* Read data if receive data valid is set */
 		while (cdns_i2c_readreg(CDNS_I2C_SR_OFFSET) &
 		       CDNS_I2C_SR_RXDV) {
@@ -246,6 +247,12 @@ static irqreturn_t cdns_i2c_isr(int irq, void *ptr)
 			    !id->bus_hold_flag)
 				cdns_i2c_clear_bus_hold(id);
 
+			if (id->recv_count == 0) {
+				pr_notice("%s: i2c receive buffer filled : %u aborting transfer %p - %p\n",
+					__func__, (id->p_recv_buf - p));
+				break;
+			}
+
 			*(id->p_recv_buf)++ =
 				cdns_i2c_readreg(CDNS_I2C_DATA_OFFSET);
 			id->recv_count--;
-- 
2.11.0

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

end of thread, other threads:[~2019-12-17  7:38 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-09-16  3:02 [PATCH] Fix Bug for cadence i2c interrupt overrunning buffer Andrew Worsley
2017-10-05 12:01 ` Wolfram Sang
2017-10-07  5:32   ` Andrew Worsley
2017-10-13 18:46     ` Wolfram Sang
2017-10-16  5:49       ` Michal Simek
2017-10-16  5:55       ` Harini Katakam
2017-10-16  9:18         ` Andrew Worsley
2017-10-16 10:38           ` Harini Katakam
2017-10-18  9:41             ` Andrew Worsley
2017-10-20  5:04               ` Harini Katakam
2017-12-07 10:49                 ` Wolfram Sang
2017-12-07 13:30                   ` Harini Katakam
     [not found]                     ` <CA+Y=x3nZsfJ+hE5YjvYLM0tdaRX9hX1G6crAjOmmnks-9Rekqg@mail.gmail.com>
2018-01-18  2:20                       ` Andrew Worsley
2019-12-17  7:38                         ` Shubhrajyoti Datta

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).