On Fri Jul 17 15:42:45 2026 +0200, Hans Verkuil wrote:
> This reverts commit 2a934fdb01db6458288fc9386d3d8ceba6dd551a.
>
> The intentions of that patch were good, but it doesn't work.
>
> The idea is that if device_register fails, you have to do a put_device
> to let the ref counter release resources.
>
> However, the V4L2 API says that if video_register_device() fails, then
> you have to call video_device_release(), which kfree()s the video_device
> struct.
>
> But the put_device() will already have freed the struct, so you end
> up in a double-free scenario.
>
> There is not really a good way of fixing this without breaking
> video_register_device() into two parts, one that initializes everything,
> and one that does the actual device_register, and then converting all
> V4L2 drivers to this new model.
>
> That is a massive job, and it is very unlikely that device_register
> will fail.
>
> So rather than ending up in a double-free scenario, just revert this
> patch, and in that case we'll have a small memory leak. Which is a lot
> more robust.
>
> Reviewed-by: Laurent Pinchart <[email protected]>
> Fixes: 2a934fdb01db ("media: v4l2-dev: fix error handling in
> __video_register_device()")
> Cc: [email protected]
> Link:
> https://lore.kernel.org/linux-media/[email protected]/
> Link: https://lore.kernel.org/all/2026042058-charm-storable-4ad8@gregkh/
> Signed-off-by: Hans Verkuil <[email protected]>
Patch committed.
Thanks,
Hans Verkuil
drivers/media/v4l2-core/v4l2-dev.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
---
diff --git a/drivers/media/v4l2-core/v4l2-dev.c
b/drivers/media/v4l2-core/v4l2-dev.c
index 5516b2bbb08f..d750bf10febe 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -1071,25 +1071,25 @@ int __video_register_device(struct video_device *vdev,
vdev->dev.class = &video_class;
vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);
vdev->dev.parent = vdev->dev_parent;
- vdev->dev.release = v4l2_device_release;
dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);
-
- /* Increase v4l2_device refcount */
- v4l2_device_get(vdev->v4l2_dev);
-
mutex_lock(&videodev_lock);
ret = device_register(&vdev->dev);
if (ret < 0) {
mutex_unlock(&videodev_lock);
pr_err("%s: device_register failed\n", __func__);
- put_device(&vdev->dev);
- return ret;
+ goto cleanup;
}
+ /* Register the release callback that will be called when the last
+ reference to the device goes away. */
+ vdev->dev.release = v4l2_device_release;
if (nr != -1 && nr != vdev->num && warn_if_nr_in_use)
pr_warn("%s: requested %s%d, got %s\n", __func__,
name_base, nr, video_device_node_name(vdev));
+ /* Increase v4l2_device refcount */
+ v4l2_device_get(vdev->v4l2_dev);
+
/* Part 5: Register the entity. */
ret = video_register_media_controller(vdev);
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]