From 03f36e885fc26cb0ea299fb6df5171a51e814548 Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oliver@neukum.org>
Date: Thu, 25 Oct 2007 15:46:30 +0200
Subject: USB: open disconnect race in iowarrior

the driver sets intfdata to NULL without lock. Data structures can be
freed and accessed.

Signed-off-by: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/usb/misc/iowarrior.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

(limited to 'drivers/usb/misc')

diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index c86c132d8aae..764696ff1e8e 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -66,6 +66,7 @@ module_param(debug, bool, 0644);
 MODULE_PARM_DESC(debug, "debug=1 enables debugging messages");
 
 static struct usb_driver iowarrior_driver;
+static DEFINE_MUTEX(iowarrior_open_disc_lock);
 
 /*--------------*/
 /*     data     */
@@ -608,11 +609,15 @@ static int iowarrior_open(struct inode *inode, struct file *file)
 		return -ENODEV;
 	}
 
+	mutex_lock(&iowarrior_open_disc_lock);
 	dev = usb_get_intfdata(interface);
-	if (!dev)
+	if (!dev) {
+		mutex_unlock(&iowarrior_open_disc_lock);
 		return -ENODEV;
+	}
 
 	mutex_lock(&dev->mutex);
+	mutex_unlock(&iowarrior_open_disc_lock);
 
 	/* Only one process can open each device, no sharing. */
 	if (dev->opened) {
@@ -866,6 +871,7 @@ static void iowarrior_disconnect(struct usb_interface *interface)
 	int minor;
 
 	dev = usb_get_intfdata(interface);
+	mutex_lock(&iowarrior_open_disc_lock);
 	usb_set_intfdata(interface, NULL);
 
 	minor = dev->minor;
@@ -879,6 +885,7 @@ static void iowarrior_disconnect(struct usb_interface *interface)
 	dev->present = 0;
 
 	mutex_unlock(&dev->mutex);
+	mutex_unlock(&iowarrior_open_disc_lock);
 
 	if (dev->opened) {
 		/* There is a process that holds a filedescriptor to the device ,
-- 
cgit v1.2.3