USB: cdc-wdm: remove from device list on disconnect
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>
This commit is contained in:
parent
6b0b79d388
commit
6286d85e8e
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue