[linux] 01/03: USB: fix invalid memory access in hub_activate() (CVE-2015-8816)

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Mon Feb 29 00:42:39 UTC 2016


This is an automated email from the git hooks/post-receive script.

benh pushed a commit to branch jessie-security
in repository linux.

commit 226cfb8d990cfde03f908f6a724375d4e8a76f2d
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Sun Feb 28 23:00:08 2016 +0000

    USB: fix invalid memory access in hub_activate() (CVE-2015-8816)
---
 debian/changelog                                   |  1 +
 ...fix-invalid-memory-access-in-hub_activate.patch | 88 ++++++++++++++++++++++
 debian/patches/series                              |  1 +
 3 files changed, 90 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 26acea6..454ca6e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -17,6 +17,7 @@ linux (3.16.7-ckt20-1+deb8u4) UNRELEASED; urgency=medium
   * ALSA: usb-audio: avoid freeing umidi object twice (CVE-2016-2384)
   * unix: correctly track in-flight fds in sending process user_struct
     (regression in 3.16.7-ckt20-1+deb8u3) (CVE-2016-2550)
+  * USB: fix invalid memory access in hub_activate() (CVE-2015-8816)
 
  -- Ben Hutchings <ben at decadent.org.uk>  Sat, 23 Jan 2016 22:53:58 +0000
 
diff --git a/debian/patches/bugfix/all/usb-fix-invalid-memory-access-in-hub_activate.patch b/debian/patches/bugfix/all/usb-fix-invalid-memory-access-in-hub_activate.patch
new file mode 100644
index 0000000..2ee0a07
--- /dev/null
+++ b/debian/patches/bugfix/all/usb-fix-invalid-memory-access-in-hub_activate.patch
@@ -0,0 +1,88 @@
+From: Alan Stern <stern at rowland.harvard.edu>
+Date: Wed, 16 Dec 2015 13:32:38 -0500
+Subject: USB: fix invalid memory access in hub_activate()
+Origin: https://git.kernel.org/linus/e50293ef9775c5f1cf3fcc093037dd6a8c5684ea
+
+Commit 8520f38099cc ("USB: change hub initialization sleeps to
+delayed_work") changed the hub_activate() routine to make part of it
+run in a workqueue.  However, the commit failed to take a reference to
+the usb_hub structure or to lock the hub interface while doing so.  As
+a result, if a hub is plugged in and quickly unplugged before the work
+routine can run, the routine will try to access memory that has been
+deallocated.  Or, if the hub is unplugged while the routine is
+running, the memory may be deallocated while it is in active use.
+
+This patch fixes the problem by taking a reference to the usb_hub at
+the start of hub_activate() and releasing it at the end (when the work
+is finished), and by locking the hub interface while the work routine
+is running.  It also adds a check at the start of the routine to see
+if the hub has already been disconnected, in which nothing should be
+done.
+
+Signed-off-by: Alan Stern <stern at rowland.harvard.edu>
+Reported-by: Alexandru Cornea <alexandru.cornea at intel.com>
+Tested-by: Alexandru Cornea <alexandru.cornea at intel.com>
+Fixes: 8520f38099cc ("USB: change hub initialization sleeps to delayed_work")
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+[ luis: backported to 3.16:
+  - Added forward declaration of hub_release() which mainline had with commit
+    32a6958998c5 ("usb: hub: convert khubd into workqueue") ]
+Signed-off-by: Luis Henriques <luis.henriques at canonical.com>
+---
+ drivers/usb/core/hub.c | 23 ++++++++++++++++++++---
+ 1 file changed, 20 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -104,6 +104,7 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rws
+ #define HUB_DEBOUNCE_STEP	  25
+ #define HUB_DEBOUNCE_STABLE	 100
+ 
++static void hub_release(struct kref *kref);
+ static int usb_reset_and_verify_device(struct usb_device *udev);
+ 
+ static inline char *portspeed(struct usb_hub *hub, int portstatus)
+@@ -1023,10 +1024,20 @@ static void hub_activate(struct usb_hub
+ 	unsigned delay;
+ 
+ 	/* Continue a partial initialization */
+-	if (type == HUB_INIT2)
+-		goto init2;
+-	if (type == HUB_INIT3)
++	if (type == HUB_INIT2 || type == HUB_INIT3) {
++		device_lock(hub->intfdev);
++
++		/* Was the hub disconnected while we were waiting? */
++		if (hub->disconnected) {
++			device_unlock(hub->intfdev);
++			kref_put(&hub->kref, hub_release);
++			return;
++		}
++		if (type == HUB_INIT2)
++			goto init2;
+ 		goto init3;
++	}
++	kref_get(&hub->kref);
+ 
+ 	/* The superspeed hub except for root hub has to use Hub Depth
+ 	 * value as an offset into the route string to locate the bits
+@@ -1224,6 +1235,7 @@ static void hub_activate(struct usb_hub
+ 			queue_delayed_work(system_power_efficient_wq,
+ 					&hub->init_work,
+ 					msecs_to_jiffies(delay));
++			device_unlock(hub->intfdev);
+ 			return;		/* Continues at init3: below */
+ 		} else {
+ 			msleep(delay);
+@@ -1245,6 +1257,11 @@ static void hub_activate(struct usb_hub
+ 	/* Allow autosuspend if it was suppressed */
+ 	if (type <= HUB_INIT3)
+ 		usb_autopm_put_interface_async(to_usb_interface(hub->intfdev));
++
++	if (type == HUB_INIT2 || type == HUB_INIT3)
++		device_unlock(hub->intfdev);
++
++	kref_put(&hub->kref, hub_release);
+ }
+ 
+ /* Implement the continuations for the delays above */
diff --git a/debian/patches/series b/debian/patches/series
index f30457b..bc50c5d 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -687,3 +687,4 @@ bugfix/all/af_unix-guard-against-other-sk-in-unix_dgram_sendmsg.patch
 bugfix/all/revert-workqueue-make-sure-delayed-work-run-in-local-cpu.patch
 bugfix/all/alsa-usb-audio-avoid-freeing-umidi-object-twice.patch
 bugfix/all/unix-correctly-track-in-flight-fds-in-sending-process-user_struct.patch
+bugfix/all/usb-fix-invalid-memory-access-in-hub_activate.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git



More information about the Kernel-svn-changes mailing list