Re: [syzbot] [media?] [usb?] KASAN: slab-use-after-free Read in v4l2_open

From: Edward Adam Davis

Date: Thu Mar 19 2026 - 08:20:54 EST


#syz test

diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 6ce623a1245a..cf9279a2d990 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -423,14 +423,18 @@ static int v4l2_open(struct inode *inode, struct file *filp)
}
/* and increase the device refcount */
video_get(vdev);
- mutex_unlock(&videodev_lock);

if (!video_is_registered(vdev)) {
ret = -ENODEV;
goto done;
}

+ set_bit(V4L2_FL_BUSY, &vdev->flags);
+ mutex_unlock(&videodev_lock);
+
ret = vdev->fops->open(filp);
+
+ mutex_lock(&videodev_lock);
if (ret)
goto done;

@@ -448,6 +452,8 @@ static int v4l2_open(struct inode *inode, struct file *filp)
/* decrease the refcount in case of an error */
if (ret)
video_put(vdev);
+ clear_bit(V4L2_FL_BUSY, &vdev->flags);
+ mutex_unlock(&videodev_lock);
return ret;
}

@@ -1121,6 +1127,11 @@ void video_unregister_device(struct video_device *vdev)
return;

mutex_lock(&videodev_lock);
+ while (test_bit(V4L2_FL_BUSY, &vdev->flags)) {
+ mutex_unlock(&videodev_lock);
+ cond_resched();
+ mutex_lock(&videodev_lock);
+ }
/* This must be in a critical section to prevent a race with v4l2_open.
* Once this bit has been cleared video_get may never be called again.
*/
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 2e0f6d2e6a78..83feb0a4f4d3 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -95,6 +95,7 @@ enum v4l2_video_device_flags {
V4L2_FL_USES_V4L2_FH = 1,
V4L2_FL_QUIRK_INVERTED_CROP = 2,
V4L2_FL_SUBDEV_RO_DEVNODE = 3,
+ V4L2_FL_BUSY = 4,
};

/* Priority helper functions */