Skip to content

Commit

Permalink
USB: cdc-wdm: remove from device list on disconnect
Browse files Browse the repository at this point in the history
Prevents dereferencing an invalid struct usb_interface
pointer.

Always delete entry from device list whether or not the
rest of the device state cleanup is postponed. The device
list uses desc->intf as key, and wdm_open will dereference
this key while searching for a matching device.  A device
should not appear in the list unless probe() has succeeded
and disconnect() has not finished.

Cc: Oliver Neukum <oliver@neukum.org>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Bjørn Mork authored and Greg Kroah-Hartman committed May 11, 2012
1 parent 6b0b79d commit 6286d85
Showing 1 changed file with 9 additions and 3 deletions.
12 changes: 9 additions & 3 deletions drivers/usb/class/cdc-wdm.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,9 +309,6 @@ static void free_urbs(struct wdm_device *desc)

static void cleanup(struct wdm_device *desc)
{
spin_lock(&wdm_device_list_lock);
list_del(&desc->device_list);
spin_unlock(&wdm_device_list_lock);
kfree(desc->sbuf);
kfree(desc->inbuf);
kfree(desc->orq);
Expand Down Expand Up @@ -782,6 +779,9 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor
out:
return rv;
err:
spin_lock(&wdm_device_list_lock);
list_del(&desc->device_list);
spin_unlock(&wdm_device_list_lock);
cleanup(desc);
return rv;
}
Expand Down Expand Up @@ -907,6 +907,12 @@ static void wdm_disconnect(struct usb_interface *intf)
cancel_work_sync(&desc->rxwork);
mutex_unlock(&desc->wlock);
mutex_unlock(&desc->rlock);

/* the desc->intf pointer used as list key is now invalid */
spin_lock(&wdm_device_list_lock);
list_del(&desc->device_list);
spin_unlock(&wdm_device_list_lock);

if (!desc->count)
cleanup(desc);
else
Expand Down

0 comments on commit 6286d85

Please sign in to comment.