[lvc-project] [PATCH] media: dw2102: Fix null-ptr-deref in su3000_i2c_transfer()

Denis Arefev arefev at swemel.ru
Fri Feb 27 15:25:33 MSK 2026


general protection fault, probably for non-canonical address
KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
...
Call Trace:
 <TASK>
 __i2c_transfer+0x868/0x2080 drivers/i2c/i2c-core-base.c:-1
 i2c_transfer+0x250/0x390 drivers/i2c/i2c-core-base.c:2328
 i2cdev_ioctl_rdwr+0x3b0/0x690 drivers/i2c/i2c-dev.c:297
 i2cdev_ioctl+0x646/0x7e0 drivers/i2c/i2c-dev.c:458
 vfs_ioctl fs/ioctl.c:51 [inline]
 __do_sys_ioctl fs/ioctl.c:871 [inline]
 __se_sys_ioctl+0xfd/0x170 fs/ioctl.c:857
 do_syscall_x64 arch/x86/entry/common.c:51 [inline]
 do_syscall_64+0x55/0xb0 arch/x86/entry/common.c:81
 entry_SYSCALL_64_after_hwframe+0x68/0xd2
RIP: 0033:0x7f1bc3f8ebe9

The user transmits messages of invalid length via ioctl, some of which may
be zero length. This causes the i2cdev_ioctl_rdwr() function to allocate 
zero-length memory for msgs[i].buf when executing memdup_user(), resulting
in a ZERO_SIZE_PTR error. The i2cdev_ioctl_rdwr() function does not handle
this situation for this adapter, resulting in a null-ptr-deref error when
accessing msgs[i].buf in su3000_i2c_transfer().

Adding the necessary checks to su3000_i2c_transfer() resolves the
ZERO_SIZE_PTR error.

Fixes: d2ffc447cabb ("[media] dw2102: add support for Geniatech SU3000 USB DVB-S2 card")
Reported-by: syzbot+d99f3a288cc7d8ef60fb at syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=d99f3a288cc7d8ef60fb
Cc: stable at vger.kernel.org
Signed-off-by: Denis Arefev <arefev at swemel.ru>
---
 drivers/media/usb/dvb-usb/dw2102.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
index 4fecf2f965e9..ad9c0374b4cb 100644
--- a/drivers/media/usb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -737,6 +737,10 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 	while (j < num) {
 		switch (msg[j].addr) {
 		case SU3000_STREAM_CTRL:
+			if (msg[j].len < 1) {
+				num = -EOPNOTSUPP;
+				break;
+			}
 			state->data[0] = msg[j].buf[0] + 0x36;
 			state->data[1] = 3;
 			state->data[2] = 0;
@@ -745,6 +749,10 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 				err("i2c transfer failed.");
 			break;
 		case DW2102_RC_QUERY:
+			if (msg[j].len < 2) {
+				num = -EOPNOTSUPP;
+				break;
+			}
 			state->data[0] = 0x10;
 			if (dvb_usb_generic_rw(d, state->data, 1,
 					       state->data, 2, 0) < 0)
-- 
2.43.0




More information about the lvc-project mailing list