mirror of https://gitee.com/openkylin/linux.git
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)
|
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->sbuf);
|
||||||
kfree(desc->inbuf);
|
kfree(desc->inbuf);
|
||||||
kfree(desc->orq);
|
kfree(desc->orq);
|
||||||
|
@ -782,6 +779,9 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor
|
||||||
out:
|
out:
|
||||||
return rv;
|
return rv;
|
||||||
err:
|
err:
|
||||||
|
spin_lock(&wdm_device_list_lock);
|
||||||
|
list_del(&desc->device_list);
|
||||||
|
spin_unlock(&wdm_device_list_lock);
|
||||||
cleanup(desc);
|
cleanup(desc);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -907,6 +907,12 @@ static void wdm_disconnect(struct usb_interface *intf)
|
||||||
cancel_work_sync(&desc->rxwork);
|
cancel_work_sync(&desc->rxwork);
|
||||||
mutex_unlock(&desc->wlock);
|
mutex_unlock(&desc->wlock);
|
||||||
mutex_unlock(&desc->rlock);
|
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)
|
if (!desc->count)
|
||||||
cleanup(desc);
|
cleanup(desc);
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue