From: Hans Verkuil Date: Fri, 26 Nov 2010 09:54:53 +0000 (-0300) Subject: [media] v4l2-dev: fix race condition X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=ca9afe6f87b569cdf8e797395381f18ae23a2905;p=linux-beck.git [media] v4l2-dev: fix race condition The unregister function had a race condition with the v4l2_open function. Ensure that both functions test and clear the REGISTER flag from within a critical section. Thanks to Laurent Pinchart for finding this race. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 6b64fd607b20..359e23290a7e 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -309,7 +309,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) mutex_lock(&videodev_lock); vdev = video_devdata(filp); /* return ENODEV if the video device has already been removed. */ - if (vdev == NULL) { + if (vdev == NULL || !video_is_registered(vdev)) { mutex_unlock(&videodev_lock); return -ENODEV; } @@ -624,7 +624,12 @@ void video_unregister_device(struct video_device *vdev) if (!vdev || !video_is_registered(vdev)) return; + 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. + */ clear_bit(V4L2_FL_REGISTERED, &vdev->flags); + mutex_unlock(&videodev_lock); device_unregister(&vdev->dev); } EXPORT_SYMBOL(video_unregister_device);