Commit 03f36e88 authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman

USB: open disconnect race in iowarrior

the driver sets intfdata to NULL without lock. Data structures can be
freed and accessed.
Signed-off-by: default avatarOliver Neukum <oneukum@suse.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 5919a43b
...@@ -66,6 +66,7 @@ module_param(debug, bool, 0644); ...@@ -66,6 +66,7 @@ module_param(debug, bool, 0644);
MODULE_PARM_DESC(debug, "debug=1 enables debugging messages"); MODULE_PARM_DESC(debug, "debug=1 enables debugging messages");
static struct usb_driver iowarrior_driver; static struct usb_driver iowarrior_driver;
static DEFINE_MUTEX(iowarrior_open_disc_lock);
/*--------------*/ /*--------------*/
/* data */ /* data */
...@@ -608,11 +609,15 @@ static int iowarrior_open(struct inode *inode, struct file *file) ...@@ -608,11 +609,15 @@ static int iowarrior_open(struct inode *inode, struct file *file)
return -ENODEV; return -ENODEV;
} }
mutex_lock(&iowarrior_open_disc_lock);
dev = usb_get_intfdata(interface); dev = usb_get_intfdata(interface);
if (!dev) if (!dev) {
mutex_unlock(&iowarrior_open_disc_lock);
return -ENODEV; return -ENODEV;
}
mutex_lock(&dev->mutex); mutex_lock(&dev->mutex);
mutex_unlock(&iowarrior_open_disc_lock);
/* Only one process can open each device, no sharing. */ /* Only one process can open each device, no sharing. */
if (dev->opened) { if (dev->opened) {
...@@ -866,6 +871,7 @@ static void iowarrior_disconnect(struct usb_interface *interface) ...@@ -866,6 +871,7 @@ static void iowarrior_disconnect(struct usb_interface *interface)
int minor; int minor;
dev = usb_get_intfdata(interface); dev = usb_get_intfdata(interface);
mutex_lock(&iowarrior_open_disc_lock);
usb_set_intfdata(interface, NULL); usb_set_intfdata(interface, NULL);
minor = dev->minor; minor = dev->minor;
...@@ -879,6 +885,7 @@ static void iowarrior_disconnect(struct usb_interface *interface) ...@@ -879,6 +885,7 @@ static void iowarrior_disconnect(struct usb_interface *interface)
dev->present = 0; dev->present = 0;
mutex_unlock(&dev->mutex); mutex_unlock(&dev->mutex);
mutex_unlock(&iowarrior_open_disc_lock);
if (dev->opened) { if (dev->opened) {
/* There is a process that holds a filedescriptor to the device , /* There is a process that holds a filedescriptor to the device ,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment