commit: 6286d85e8efdb59252d1ceb99a56fa6b0b11526c
From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <[email protected]>
Date: Wed, 9 May 2012 13:53:23 +0200
Subject: USB: cdc-wdm: remove from device list on disconnect
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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 <[email protected]>
Cc: stable <[email protected]>
Signed-off-by: Bjørn Mork <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
 drivers/usb/class/cdc-wdm.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 90bc916..631bb95 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -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
-- 
1.7.3.4
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to