Commit 362f2153 authored by Deepak Sharma's avatar Deepak Sharma Committed by Jiri Kosina
Browse files

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: default avatar <syzbot+7617e19c8a59edfbd879@syzkaller.appspotmail.com>
Closes: https://syzkaller.appspot.com/bug?extid=7617e19c8a59edfbd879


Tested-by: default avatar <syzbot+7617e19c8a59edfbd879@syzkaller.appspotmail.com>
Signed-off-by: default avatarDeepak Sharma <deepak.sharma.472935@gmail.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.com>
parent 50f1f782
Loading
Loading
Loading
Loading
+24 −3
Original line number Diff line number Diff line
@@ -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);