HID: cp2112: Add parameter validation to data length

Syzkaller reported a stack OOB access in cp2112_write_req caused by lack
of parameter validation for the user input in I2C SMBUS ioctl in cp2112
driver

Add the parameter validation for the data->block[0] to be bounded by
I2C_SMBUS_BLOCK_MAX + the additional compatibility padding

[jkosina@suse.com: fix whitespace damage]
Reported-by: syzbot+7617e19c8a59edfbd879@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=7617e19c8a59edfbd879
Tested-by: syzbot+7617e19c8a59edfbd879@syzkaller.appspotmail.com
Signed-off-by: Deepak Sharma <deepak.sharma.472935@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
This commit is contained in:
Deepak Sharma 2025-09-26 20:28:11 +05:30 committed by Jiri Kosina
parent 50f1f782f8
commit 362f215369
1 changed files with 24 additions and 3 deletions

View File

@ -689,6 +689,13 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr,
count = cp2112_write_read_req(buf, addr, read_length,
command, NULL, 0);
} else {
/* Copy starts from data->block[1] so the length can
* be at max I2C_SMBUS_CLOCK_MAX + 1
*/
if (data->block[0] > I2C_SMBUS_BLOCK_MAX + 1)
count = -EINVAL;
else
count = cp2112_write_req(buf, addr, command,
data->block + 1,
data->block[0]);
@ -700,6 +707,13 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr,
I2C_SMBUS_BLOCK_MAX,
command, NULL, 0);
} else {
/* data_length here is data->block[0] + 1
* so make sure that the data->block[0] is
* less than or equals I2C_SMBUS_BLOCK_MAX + 1
*/
if (data->block[0] > I2C_SMBUS_BLOCK_MAX + 1)
count = -EINVAL;
else
count = cp2112_write_req(buf, addr, command,
data->block,
data->block[0] + 1);
@ -709,6 +723,13 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr,
size = I2C_SMBUS_BLOCK_DATA;
read_write = I2C_SMBUS_READ;
/* data_length is data->block[0] + 1, so
* so data->block[0] should be less than or
* equal to the I2C_SMBUS_BLOCK_MAX + 1
*/
if (data->block[0] > I2C_SMBUS_BLOCK_MAX + 1)
count = -EINVAL;
else
count = cp2112_write_read_req(buf, addr, I2C_SMBUS_BLOCK_MAX,
command, data->block,
data->block[0] + 1);