]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.0-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 28 Sep 2012 01:02:56 +0000 (18:02 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 28 Sep 2012 01:02:56 +0000 (18:02 -0700)
added patches:
usb-fix-race-condition-when-removing-host-controllers.patch

queue-3.0/series
queue-3.0/usb-fix-race-condition-when-removing-host-controllers.patch [new file with mode: 0644]

index 179d866bf0a8b7070715f16edae33699892a09b7..e9871dc56a45f722813a24789ee2a71bdf6dd86a 100644 (file)
@@ -124,3 +124,4 @@ spi-mpc83xx-fix-null-pdata-dereference-bug.patch
 spi-spi-fsl-spi-reference-correct-pdata-in-fsl_spi_cs_control.patch
 sched-fix-ancient-race-in-do_exit.patch
 mce-fix-vm86-handling-for-32bit-mce-handler.patch
+usb-fix-race-condition-when-removing-host-controllers.patch
diff --git a/queue-3.0/usb-fix-race-condition-when-removing-host-controllers.patch b/queue-3.0/usb-fix-race-condition-when-removing-host-controllers.patch
new file mode 100644 (file)
index 0000000..f618d1c
--- /dev/null
@@ -0,0 +1,68 @@
+From 0d00dc2611abbe6ad244d50569c2ee82ce42846c Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Wed, 26 Sep 2012 13:09:53 -0400
+Subject: USB: Fix race condition when removing host controllers
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 0d00dc2611abbe6ad244d50569c2ee82ce42846c upstream.
+
+This patch (as1607) fixes a race that can occur if a USB host
+controller is removed while a process is reading the
+/sys/kernel/debug/usb/devices file.
+
+The usb_device_read() routine uses the bus->root_hub pointer to
+determine whether or not the root hub is registered.  The is not a
+valid test, because the pointer is set before the root hub gets
+registered and remains set even after the root hub is unregistered and
+deallocated.  As a result, usb_device_read() or usb_device_dump() can
+access freed memory, causing an oops.
+
+The patch changes the test to use the hcd->rh_registered flag, which
+does get set and cleared at the appropriate times.  It also makes sure
+to hold the usb_bus_list_lock mutex while setting the flag, so that
+usb_device_read() will become aware of new root hubs as soon as they
+are registered.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-by: Don Zickus <dzickus@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/devices.c |    2 +-
+ drivers/usb/core/hcd.c     |    6 ++----
+ 2 files changed, 3 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/core/devices.c
++++ b/drivers/usb/core/devices.c
+@@ -624,7 +624,7 @@ static ssize_t usb_device_read(struct fi
+       /* print devices for all busses */
+       list_for_each_entry(bus, &usb_bus_list, bus_list) {
+               /* recurse through all children of the root hub */
+-              if (!bus->root_hub)
++              if (!bus_to_hcd(bus)->rh_registered)
+                       continue;
+               usb_lock_device(bus->root_hub);
+               ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos,
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -977,10 +977,7 @@ static int register_root_hub(struct usb_
+       if (retval) {
+               dev_err (parent_dev, "can't register root hub for %s, %d\n",
+                               dev_name(&usb_dev->dev), retval);
+-      }
+-      mutex_unlock(&usb_bus_list_lock);
+-
+-      if (retval == 0) {
++      } else {
+               spin_lock_irq (&hcd_root_hub_lock);
+               hcd->rh_registered = 1;
+               spin_unlock_irq (&hcd_root_hub_lock);
+@@ -989,6 +986,7 @@ static int register_root_hub(struct usb_
+               if (HCD_DEAD(hcd))
+                       usb_hc_died (hcd);      /* This time clean up */
+       }
++      mutex_unlock(&usb_bus_list_lock);
+       return retval;
+ }