[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <lsq.1544392233.201600056@decadent.org.uk>
Date: Sun, 09 Dec 2018 21:50:33 +0000
From: Ben Hutchings <ben@...adent.org.uk>
To: linux-kernel@...r.kernel.org, stable@...r.kernel.org
CC: akpm@...ux-foundation.org,
"Greg Kroah-Hartman" <gregkh@...uxfoundation.org>,
"Alan Stern" <stern@...land.harvard.edu>,
syzbot+f84aa7209ccec829536f@...kaller.appspotmail.com
Subject: [PATCH 3.16 255/328] USB: fix error handling in usb_driver_claim_interface()
3.16.62-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Alan Stern <stern@...land.harvard.edu>
commit bd729f9d67aa9a303d8925bb8c4f06af25f407d1 upstream.
The syzbot fuzzing project found a use-after-free bug in the USB
core. The bug was caused by usbfs not unbinding from an interface
when the USB device file was closed, which led another process to
attempt the unbind later on, after the private data structure had been
deallocated.
The reason usbfs did not unbind the interface at the appropriate time
was because it thought the interface had never been claimed in the
first place. This was caused by the fact that
usb_driver_claim_interface() does not clean up properly when
device_bind_driver() returns an error. Although the error code gets
passed back to the caller, the iface->dev.driver pointer remains set
and iface->condition remains equal to USB_INTERFACE_BOUND.
This patch adds proper error handling to usb_driver_claim_interface().
Signed-off-by: Alan Stern <stern@...land.harvard.edu>
Reported-by: syzbot+f84aa7209ccec829536f@...kaller.appspotmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Signed-off-by: Ben Hutchings <ben@...adent.org.uk>
---
drivers/usb/core/driver.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -556,6 +556,21 @@ int usb_driver_claim_interface(struct us
if (device_is_registered(dev))
retval = device_bind_driver(dev);
+ if (retval) {
+ dev->driver = NULL;
+ usb_set_intfdata(iface, NULL);
+ iface->needs_remote_wakeup = 0;
+ iface->condition = USB_INTERFACE_UNBOUND;
+
+ /*
+ * Unbound interfaces are always runtime-PM-disabled
+ * and runtime-PM-suspended
+ */
+ if (driver->supports_autosuspend)
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ }
+
return retval;
}
EXPORT_SYMBOL_GPL(usb_driver_claim_interface);
Powered by blists - more mailing lists