[PATCH RFC] media: radio-usb-si4713: fix use-after-free on disconnect
"syzbot" <[email protected]>
| Newsgroups | dev.linux.lists.syzbot |
|---|---|
| Message-ID | <[email protected]> |
A use-after-free bug occurs in i2c_adapter_depth() when the USB device is
disconnected while a user-space process holds a file descriptor open for
the video device. The radio-usb-si4713 driver defers i2c_del_adapter() to
the v4l2_device release callback. If the release is delayed, the I2C
adapter remains registered after the USB device is deleted. When the I2C
core is accessed later, it traverses the device tree using the dangling
parent pointer, leading to a use-after-free.
BUG: KASAN: slab-use-after-free in i2c_adapter_depth
drivers/i2c/i2c-core-base.c:1243 [inline]
BUG: KASAN: slab-use-after-free in i2c_adapter_lock_bus+0x5e/0xf0
drivers/i2c/i2c-core-base.c:849
Read of size 8 at addr ffff88818f703108 by task syz-executor235/5896
Call Trace:
<TASK>
i2c_adapter_depth drivers/i2c/i2c-core-base.c:1243 [inline]
i2c_adapter_lock_bus+0x5e/0xf0 drivers/i2c/i2c-core-base.c:849
i2c_lock_bus include/linux/i2c.h:809 [inline]
__i2c_lock_bus_helper drivers/i2c/i2c-core.h:47 [inline]
i2c_transfer+0xc8/0x2d0 drivers/i2c/i2c-core-base.c:2339
i2cdev_ioctl_rdwr+0x460/0x740 drivers/i2c/i2c-dev.c:306
i2cdev_ioctl+0x6a5/0x880 drivers/i2c/i2c-dev.c:467
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x174/0x580 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
</TASK>
To fix this, unregister the I2C adapter and V4L2 device synchronously in
the disconnect callback. Additionally, call v4l2_device_unregister() before
i2c_del_adapter() to prevent a double-free of the I2C client device, which
would occur if the I2C adapter unregisters its clients before V4L2 does.
The same ordering is applied to the error path in usb_si4713_probe().
Finally, i2c_del_adapter() is called outside of radio->lock to avoid
deadlocks with concurrent ioctl calls.
Fixes: b874b39fcd2f ("[media] si4713: Added the USB driver for Si4713")
Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot
Reported-by: [email protected]
Closes: https://syzkaller.appspot.com/bug?extid=450abcfc7906fe1a1e16
Link: https://syzkaller.appspot.com/ai_job?id=4960f118-574d-47b1-a640-160d51f8ec71
To: "Hans Verkuil" <[email protected]>
To: <[email protected]>
To: "Mauro Carvalho Chehab" <[email protected]>
To: "Dinesh Ram" <[email protected]>
Cc: <[email protected]>
---
diff --git a/drivers/media/radio/si4713/radio-usb-si4713.c b/drivers/media/radio/si4713/radio-usb-si4713.c
index 6e6764143..d5d97e336 100644
--- a/drivers/media/radio/si4713/radio-usb-si4713.c
+++ b/drivers/media/radio/si4713/radio-usb-si4713.c
@@ -128,10 +128,7 @@ static const struct v4l2_file_operations usb_si4713_fops = {
static void usb_si4713_video_device_release(struct v4l2_device *v4l2_dev)
{
struct si4713_usb_device *radio = to_si4713_dev(v4l2_dev);
- struct i2c_adapter *adapter = &radio->i2c_adapter;
- i2c_del_adapter(adapter);
- v4l2_device_unregister(&radio->v4l2_dev);
kfree(radio->buffer);
kfree(radio);
}
@@ -488,7 +485,9 @@ static int usb_si4713_probe(struct usb_interface *intf,
return 0;
del_adapter:
+ v4l2_device_unregister(&radio->v4l2_dev);
i2c_del_adapter(adapter);
+ goto err_v4l2;
err_i2cdev:
v4l2_device_unregister(&radio->v4l2_dev);
err_v4l2:
@@ -506,8 +505,11 @@ static void usb_si4713_disconnect(struct usb_interface *intf)
mutex_lock(&radio->lock);
usb_set_intfdata(intf, NULL);
video_unregister_device(&radio->vdev);
- v4l2_device_disconnect(&radio->v4l2_dev);
mutex_unlock(&radio->lock);
+
+ v4l2_device_unregister(&radio->v4l2_dev);
+ i2c_del_adapter(&radio->i2c_adapter);
+
v4l2_device_put(&radio->v4l2_dev);
}
base-commit: 075b74841bd0065a3bda3440873c747938e69b68
--
This is an AI-generated patch subject to moderation.
Reply with '#syz upstream' to Sign-off the patch as a human author
and send it to the upstream kernel mailing lists.
Reply with '#syz reject' to reject it ('#syz unreject' to undo).
See https://goo.gle/syzbot-ai-patches for information about AI-generated patches.
The person who has signed off on the patch is responsible for
addressing comments.
syzbot engineers can be reached at [email protected].