aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2006-11-11 00:13:32 +0100
committerAdrian Bunk <bunk@stusta.de>2006-11-11 00:13:32 +0100
commitc04f8dca8e1e3b055355bf5fa94d773b17f6f683 (patch)
tree4bc384b7274fb29355d1e94f3b877c41686cb49d
parentb88acf65abec97a9b44c42d921c930c4d62d7b5e (diff)
scx200_acb: Fix the block transactions
The scx200_acb i2c bus driver pretends to support SMBus block transactions, but in fact it implements the more simple I2C block transactions. Additionally, it lacks sanity checks on the length of the block transactions, which could lead to a buffer overrun. This fixes an oops reported by Alexander Atanasov: http://marc.theaimsgroup.com/?l=linux-kernel&m=114970382125094 Thanks to Ben Gardner for fixing my bugs :) Signed-off-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: Adrian Bunk <bunk@stusta.de>
-rw-r--r--drivers/i2c/busses/scx200_acb.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
index e28fb6973e5..49f8a50205e 100644
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -316,8 +316,12 @@ static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
cur_word = cpu_to_le16(data->word);
buffer = (u8 *)&cur_word;
break;
- case I2C_SMBUS_BLOCK_DATA:
+ case I2C_SMBUS_I2C_BLOCK_DATA:
+ if (rw == I2C_SMBUS_READ)
+ data->block[0] = I2C_SMBUS_BLOCK_MAX; /* For now */
len = data->block[0];
+ if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
+ return -EINVAL;
buffer = &data->block[1];
break;
default:
@@ -390,7 +394,7 @@ static u32 scx200_acb_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_BLOCK_DATA;
+ I2C_FUNC_SMBUS_I2C_BLOCK;
}
/* For now, we only handle combined mode (smbus) */