summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil-cisco@xs4all.nl>2024-02-23 09:45:36 +0100
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2024-04-24 13:49:55 +0200
commit1ed4477f2ea4743e7c5e1f9f3722152d14e6eeb1 (patch)
treec182d3df80fc09f733495ab60150518d5bce9ca8
parente42a204f0519a2540f1507ac2798be2aeaa76bee (diff)
downloadlinux-stable-1ed4477f2ea4743e7c5e1f9f3722152d14e6eeb1.tar.gz
linux-stable-1ed4477f2ea4743e7c5e1f9f3722152d14e6eeb1.tar.bz2
linux-stable-1ed4477f2ea4743e7c5e1f9f3722152d14e6eeb1.zip
media: v4l2-core: hold videodev_lock until dev reg, finishes
After the new V4L2 device node was registered, some additional initialization was done before the device node was marked as 'registered'. During the time between creating the device node and marking it as 'registered' it was possible to open the device node, which would return -ENODEV since the 'registered' flag was not yet set. Hold the videodev_lock mutex from just before the device node is registered until the 'registered' flag is set. Since v4l2_open will take the same lock, it will wait until this registration process is finished. This resolves this race condition. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com> Cc: <stable@vger.kernel.org> # for vi4.18 and up
-rw-r--r--drivers/media/v4l2-core/v4l2-dev.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index e39e9742fdb5..be2ba7ca5de2 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -1039,8 +1039,10 @@ int __video_register_device(struct video_device *vdev,
vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);
vdev->dev.parent = vdev->dev_parent;
dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);
+ mutex_lock(&videodev_lock);
ret = device_register(&vdev->dev);
if (ret < 0) {
+ mutex_unlock(&videodev_lock);
pr_err("%s: device_register failed\n", __func__);
goto cleanup;
}
@@ -1060,6 +1062,7 @@ int __video_register_device(struct video_device *vdev,
/* Part 6: Activate this minor. The char device can now be used. */
set_bit(V4L2_FL_REGISTERED, &vdev->flags);
+ mutex_unlock(&videodev_lock);
return 0;