Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Deepak Sharma and committed by
Jiri Kosina
362f2153 50f1f782

+24 -3
+24 -3
drivers/hid/hid-cp2112.c
··· 689 689 count = cp2112_write_read_req(buf, addr, read_length, 690 690 command, NULL, 0); 691 691 } else { 692 - count = cp2112_write_req(buf, addr, command, 692 + /* Copy starts from data->block[1] so the length can 693 + * be at max I2C_SMBUS_CLOCK_MAX + 1 694 + */ 695 + 696 + if (data->block[0] > I2C_SMBUS_BLOCK_MAX + 1) 697 + count = -EINVAL; 698 + else 699 + count = cp2112_write_req(buf, addr, command, 693 700 data->block + 1, 694 701 data->block[0]); 695 702 } ··· 707 700 I2C_SMBUS_BLOCK_MAX, 708 701 command, NULL, 0); 709 702 } else { 710 - count = cp2112_write_req(buf, addr, command, 703 + /* data_length here is data->block[0] + 1 704 + * so make sure that the data->block[0] is 705 + * less than or equals I2C_SMBUS_BLOCK_MAX + 1 706 + */ 707 + if (data->block[0] > I2C_SMBUS_BLOCK_MAX + 1) 708 + count = -EINVAL; 709 + else 710 + count = cp2112_write_req(buf, addr, command, 711 711 data->block, 712 712 data->block[0] + 1); 713 713 } ··· 723 709 size = I2C_SMBUS_BLOCK_DATA; 724 710 read_write = I2C_SMBUS_READ; 725 711 726 - count = cp2112_write_read_req(buf, addr, I2C_SMBUS_BLOCK_MAX, 712 + /* data_length is data->block[0] + 1, so 713 + * so data->block[0] should be less than or 714 + * equal to the I2C_SMBUS_BLOCK_MAX + 1 715 + */ 716 + if (data->block[0] > I2C_SMBUS_BLOCK_MAX + 1) 717 + count = -EINVAL; 718 + else 719 + count = cp2112_write_read_req(buf, addr, I2C_SMBUS_BLOCK_MAX, 727 720 command, data->block, 728 721 data->block[0] + 1); 729 722 break;