uvc_v4l2_open() acquires the uvc device mutex. After doing so, it does not check if the video device is still registered. This may result in race conditions and can result in an attempt to submit an urb to a disconnected USB interface (from uvc_v4l2_open). The problem was observed after adding a call to msleep() just before acquiring the mutex and disconnecting the camera during the sleep. Check if the video device is still registered after acquiring the mutex to avoid the problem. In the release function, only call uvc_status_stop() if the video device is still registered. If the video device has been unregistered, the urb associated with uvc status has already been killed in uvc_status_unregister(). Trying to kill it again won't do any good and might have unexpected side effects. Cc: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx> Cc: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> Cc: Hans Verkuil <hverkuil-cisco@xxxxxxxxx> Signed-off-by: Guenter Roeck <linux@xxxxxxxxxxxx> --- drivers/media/usb/uvc/uvc_v4l2.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 7e5e583dae5e..1f7d454557b9 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -548,6 +548,10 @@ static int uvc_v4l2_open(struct file *file) } mutex_lock(&stream->dev->lock); + if (!video_is_registered(&stream->vdev)) { + mutex_unlock(&stream->dev->lock); + return -ENODEV; + } if (stream->dev->users == 0) { ret = uvc_status_start(stream->dev, GFP_KERNEL); if (ret < 0) { @@ -590,7 +594,7 @@ static int uvc_v4l2_release(struct file *file) file->private_data = NULL; mutex_lock(&stream->dev->lock); - if (--stream->dev->users == 0) + if (--stream->dev->users == 0 && video_is_registered(&stream->vdev)) uvc_status_stop(stream->dev); mutex_unlock(&stream->dev->lock); -- 2.17.1