diff options
author | Oliver Neukum <oliver@neukum.org> | 2007-10-25 09:46:30 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-10-25 15:18:46 -0400 |
commit | 03f36e885fc26cb0ea299fb6df5171a51e814548 (patch) | |
tree | dbc189fa0af4f172c57b97c98cf68718ac0028fd | |
parent | 5919a43bbc649f4770b8b5db33f43136c7ff3153 (diff) |
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>
-rw-r--r-- | drivers/usb/misc/iowarrior.c | 9 |
1 files changed, 8 insertions, 1 deletions
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); | |||
66 | MODULE_PARM_DESC(debug, "debug=1 enables debugging messages"); | 66 | MODULE_PARM_DESC(debug, "debug=1 enables debugging messages"); |
67 | 67 | ||
68 | static struct usb_driver iowarrior_driver; | 68 | static struct usb_driver iowarrior_driver; |
69 | static DEFINE_MUTEX(iowarrior_open_disc_lock); | ||
69 | 70 | ||
70 | /*--------------*/ | 71 | /*--------------*/ |
71 | /* data */ | 72 | /* data */ |
@@ -608,11 +609,15 @@ static int iowarrior_open(struct inode *inode, struct file *file) | |||
608 | return -ENODEV; | 609 | return -ENODEV; |
609 | } | 610 | } |
610 | 611 | ||
612 | mutex_lock(&iowarrior_open_disc_lock); | ||
611 | dev = usb_get_intfdata(interface); | 613 | dev = usb_get_intfdata(interface); |
612 | if (!dev) | 614 | if (!dev) { |
615 | mutex_unlock(&iowarrior_open_disc_lock); | ||
613 | return -ENODEV; | 616 | return -ENODEV; |
617 | } | ||
614 | 618 | ||
615 | mutex_lock(&dev->mutex); | 619 | mutex_lock(&dev->mutex); |
620 | mutex_unlock(&iowarrior_open_disc_lock); | ||
616 | 621 | ||
617 | /* Only one process can open each device, no sharing. */ | 622 | /* Only one process can open each device, no sharing. */ |
618 | if (dev->opened) { | 623 | if (dev->opened) { |
@@ -866,6 +871,7 @@ static void iowarrior_disconnect(struct usb_interface *interface) | |||
866 | int minor; | 871 | int minor; |
867 | 872 | ||
868 | dev = usb_get_intfdata(interface); | 873 | dev = usb_get_intfdata(interface); |
874 | mutex_lock(&iowarrior_open_disc_lock); | ||
869 | usb_set_intfdata(interface, NULL); | 875 | usb_set_intfdata(interface, NULL); |
870 | 876 | ||
871 | minor = dev->minor; | 877 | minor = dev->minor; |
@@ -879,6 +885,7 @@ static void iowarrior_disconnect(struct usb_interface *interface) | |||
879 | dev->present = 0; | 885 | dev->present = 0; |
880 | 886 | ||
881 | mutex_unlock(&dev->mutex); | 887 | mutex_unlock(&dev->mutex); |
888 | mutex_unlock(&iowarrior_open_disc_lock); | ||
882 | 889 | ||
883 | if (dev->opened) { | 890 | if (dev->opened) { |
884 | /* There is a process that holds a filedescriptor to the device , | 891 | /* There is a process that holds a filedescriptor to the device , |