diff mbox series

[v2,04/12] i2c: Add a length check to the SMBus write handling

Message ID 20181115192446.17187-5-minyard@acm.org
State Superseded
Headers show
Series [v2,01/12] i2c: Split smbus into parts | expand

Commit Message

Corey Minyard Nov. 15, 2018, 7:24 p.m. UTC
From: Corey Minyard <cminyard@mvista.com>


Avoid an overflow.

Signed-off-by: Corey Minyard <cminyard@mvista.com>

---
 hw/i2c/smbus_slave.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

-- 
2.17.1

Comments

Peter Maydell Nov. 20, 2018, 3:33 p.m. UTC | #1
On 15 November 2018 at 19:24,  <minyard@acm.org> wrote:
> From: Corey Minyard <cminyard@mvista.com>

>

> Avoid an overflow.

>

> Signed-off-by: Corey Minyard <cminyard@mvista.com>

> ---

>  hw/i2c/smbus_slave.c | 6 +++++-

>  1 file changed, 5 insertions(+), 1 deletion(-)

>

> diff --git a/hw/i2c/smbus_slave.c b/hw/i2c/smbus_slave.c

> index 83ca041b5d..fa988919d8 100644

> --- a/hw/i2c/smbus_slave.c

> +++ b/hw/i2c/smbus_slave.c

> @@ -182,7 +182,11 @@ static int smbus_i2c_send(I2CSlave *s, uint8_t data)

>      switch (dev->mode) {

>      case SMBUS_WRITE_DATA:

>          DPRINTF("Write data %02x\n", data);

> -        dev->data_buf[dev->data_len++] = data;

> +        if (dev->data_len >= sizeof(dev->data_buf)) {

> +            BADF("Too many bytes sent\n");

> +        } else {

> +            dev->data_buf[dev->data_len++] = data;

> +        }

>          break;


Reviewed-by: Peter Maydell <peter.maydell@linaro.org>


What happens on a real device in this situation ?

thanks
-- PMM
Corey Minyard Nov. 20, 2018, 4:58 p.m. UTC | #2
On 11/20/18 9:33 AM, Peter Maydell wrote:
> On 15 November 2018 at 19:24,  <minyard@acm.org> wrote:

>> From: Corey Minyard <cminyard@mvista.com>

>>

>> Avoid an overflow.

>>

>> Signed-off-by: Corey Minyard <cminyard@mvista.com>

>> ---

>>   hw/i2c/smbus_slave.c | 6 +++++-

>>   1 file changed, 5 insertions(+), 1 deletion(-)

>>

>> diff --git a/hw/i2c/smbus_slave.c b/hw/i2c/smbus_slave.c

>> index 83ca041b5d..fa988919d8 100644

>> --- a/hw/i2c/smbus_slave.c

>> +++ b/hw/i2c/smbus_slave.c

>> @@ -182,7 +182,11 @@ static int smbus_i2c_send(I2CSlave *s, uint8_t data)

>>       switch (dev->mode) {

>>       case SMBUS_WRITE_DATA:

>>           DPRINTF("Write data %02x\n", data);

>> -        dev->data_buf[dev->data_len++] = data;

>> +        if (dev->data_len >= sizeof(dev->data_buf)) {

>> +            BADF("Too many bytes sent\n");

>> +        } else {

>> +            dev->data_buf[dev->data_len++] = data;

>> +        }

>>           break;

> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

>

> What happens on a real device in this situation ?


It's device specific.  Some devices (most eeproms, I suspect) will just keep
taking data, wrapping around when you hit the end of the memory. Some
devices (IPMI BMCs, generally) will ignore the extra data.  Some devices
may return a NAK on a byte if it gets too much data.  The specification
says:

    The slave device detects an invalid command or invalid data. In this
    case the slave
    device must NACK the received byte. The master upon detection of
    this condition
    must generate a STOP condition and retry the transaction.

So a NAK may be appropriate here, but it's kind of fuzzy.  Since generating
a NAK is more complicated, I would guess that most devices don't.

-corey


> thanks

> -- PMM
diff mbox series

Patch

diff --git a/hw/i2c/smbus_slave.c b/hw/i2c/smbus_slave.c
index 83ca041b5d..fa988919d8 100644
--- a/hw/i2c/smbus_slave.c
+++ b/hw/i2c/smbus_slave.c
@@ -182,7 +182,11 @@  static int smbus_i2c_send(I2CSlave *s, uint8_t data)
     switch (dev->mode) {
     case SMBUS_WRITE_DATA:
         DPRINTF("Write data %02x\n", data);
-        dev->data_buf[dev->data_len++] = data;
+        if (dev->data_len >= sizeof(dev->data_buf)) {
+            BADF("Too many bytes sent\n");
+        } else {
+            dev->data_buf[dev->data_len++] = data;
+        }
         break;
 
     default: