ChangeSet 1.1673.8.17, 2004/03/25 16:53:25-08:00, oliver@neukum.org [PATCH] USB: race condition in open of w9968cf there's a race in how open handles multiple openers. You implement exclusive opening and wait for close in case of further openers. However if there are more than one waiter, only one of them must be allowed to proceed. drivers/usb/media/w9968cf.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) diff -Nru a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c --- a/drivers/usb/media/w9968cf.c Wed Apr 14 14:38:58 2004 +++ b/drivers/usb/media/w9968cf.c Wed Apr 14 14:38:58 2004 @@ -905,8 +905,7 @@ spin_unlock(&cam->urb_lock); /* Wake up the user process */ - if (waitqueue_active(&cam->wait_queue)) - wake_up_interruptible(&cam->wait_queue); + wake_up_interruptible(&cam->wait_queue); } @@ -2690,6 +2689,7 @@ up(&cam->dev_sem); return -EWOULDBLOCK; } +retry: up(&cam->dev_sem); err = wait_event_interruptible(cam->open, cam->disconnected || (cam->users == 0)); @@ -2698,6 +2698,9 @@ if (cam->disconnected) return -ENODEV; down(&cam->dev_sem); + /*recheck - there may be several waiters */ + if (cam->users) + goto retry; } DBG(5, "Opening '%s', /dev/video%d ...", @@ -2758,8 +2761,7 @@ cam->users--; w9968cf_deallocate_memory(cam); - if (waitqueue_active(&cam->open)) - wake_up_interruptible(&cam->open); + wake_up_interruptible(&cam->open); DBG(5, "Video device closed.") up(&cam->dev_sem);