Skip to content

Commit

Permalink
USB: disconnect open race in legousbtower
Browse files Browse the repository at this point in the history
again, possible use after free due to touching intfdata without lock.

Signed-off-by: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Oliver Neukum authored and Greg Kroah-Hartman committed Oct 25, 2007
1 parent 03f36e8 commit 78663ec
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion drivers/usb/misc/legousbtower.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ static struct usb_device_id tower_table [] = {
};

MODULE_DEVICE_TABLE (usb, tower_table);
static DEFINE_MUTEX(open_disc_mutex);

#define LEGO_USB_TOWER_MINOR_BASE 160

Expand Down Expand Up @@ -350,25 +351,31 @@ static int tower_open (struct inode *inode, struct file *file)
goto exit;
}

mutex_lock(&open_disc_mutex);
dev = usb_get_intfdata(interface);

if (!dev) {
mutex_unlock(&open_disc_mutex);
retval = -ENODEV;
goto exit;
}

/* lock this device */
if (down_interruptible (&dev->sem)) {
mutex_unlock(&open_disc_mutex);
retval = -ERESTARTSYS;
goto exit;
}


/* allow opening only once */
if (dev->open_count) {
mutex_unlock(&open_disc_mutex);
retval = -EBUSY;
goto unlock_exit;
}
dev->open_count = 1;
mutex_unlock(&open_disc_mutex);

/* reset the tower */
result = usb_control_msg (dev->udev,
Expand Down Expand Up @@ -437,9 +444,10 @@ static int tower_release (struct inode *inode, struct file *file)
if (dev == NULL) {
dbg(1, "%s: object is NULL", __FUNCTION__);
retval = -ENODEV;
goto exit;
goto exit_nolock;
}

mutex_lock(&open_disc_mutex);
if (down_interruptible (&dev->sem)) {
retval = -ERESTARTSYS;
goto exit;
Expand Down Expand Up @@ -468,6 +476,8 @@ static int tower_release (struct inode *inode, struct file *file)
up (&dev->sem);

exit:
mutex_unlock(&open_disc_mutex);
exit_nolock:
dbg(2, "%s: leave, return value %d", __FUNCTION__, retval);
return retval;
}
Expand Down Expand Up @@ -989,6 +999,7 @@ static void tower_disconnect (struct usb_interface *interface)
dbg(2, "%s: enter", __FUNCTION__);

dev = usb_get_intfdata (interface);
mutex_lock(&open_disc_mutex);
usb_set_intfdata (interface, NULL);

minor = dev->minor;
Expand All @@ -997,6 +1008,7 @@ static void tower_disconnect (struct usb_interface *interface)
usb_deregister_dev (interface, &tower_class);

down (&dev->sem);
mutex_unlock(&open_disc_mutex);

/* if the device is not opened, then we clean up right now */
if (!dev->open_count) {
Expand Down

0 comments on commit 78663ec

Please sign in to comment.