From: Greg Kroah-Hartman Date: Fri, 28 Sep 2012 01:02:56 +0000 (-0700) Subject: 3.0-stable patches X-Git-Tag: v3.0.44~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5e062dc52c32991a0414b538c5ecf2f15f993d8b;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: usb-fix-race-condition-when-removing-host-controllers.patch --- diff --git a/queue-3.0/series b/queue-3.0/series index 179d866bf0a..e9871dc56a4 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -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 index 00000000000..f618d1ca4a7 --- /dev/null +++ b/queue-3.0/usb-fix-race-condition-when-removing-host-controllers.patch @@ -0,0 +1,68 @@ +From 0d00dc2611abbe6ad244d50569c2ee82ce42846c Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Wed, 26 Sep 2012 13:09:53 -0400 +Subject: USB: Fix race condition when removing host controllers + +From: Alan Stern + +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 +Reported-by: Don Zickus +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + }