[kernel] r16364 - in dists/trunk/linux-2.6/debian: . patches/bugfix/all patches/series

Ben Hutchings benh at alioth.debian.org
Tue Sep 28 01:21:40 UTC 2010


Author: benh
Date: Tue Sep 28 01:21:38 2010
New Revision: 16364

Log:
USB: fix bug in initialization of interface minor numbers (Closes: #598207)

Added:
   dists/trunk/linux-2.6/debian/patches/bugfix/all/USB-fix-bug-in-initialization-of-interface-minor-num.patch
Modified:
   dists/trunk/linux-2.6/debian/changelog
   dists/trunk/linux-2.6/debian/patches/series/1~experimental.2

Modified: dists/trunk/linux-2.6/debian/changelog
==============================================================================
--- dists/trunk/linux-2.6/debian/changelog	Tue Sep 28 01:13:05 2010	(r16363)
+++ dists/trunk/linux-2.6/debian/changelog	Tue Sep 28 01:21:38 2010	(r16364)
@@ -4,6 +4,7 @@
   * linux-base: Remove dependency on libapt-pkg-perl (Closes: #589996, really)
   * drm/i915: Ensure that the crtcinfo is populated during mode_fixup()
     (Closes: #592415)
+  * USB: fix bug in initialization of interface minor numbers (Closes: #598207)
 
  -- Ben Hutchings <ben at decadent.org.uk>  Sun, 26 Sep 2010 15:34:10 +0100
 

Added: dists/trunk/linux-2.6/debian/patches/bugfix/all/USB-fix-bug-in-initialization-of-interface-minor-num.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/USB-fix-bug-in-initialization-of-interface-minor-num.patch	Tue Sep 28 01:21:38 2010	(r16364)
@@ -0,0 +1,122 @@
+From: Alan Stern <stern at rowland.harvard.edu>
+Date: Tue, 21 Sep 2010 15:01:53 -0400
+Subject: [PATCH] USB: fix bug in initialization of interface minor numbers
+
+commit 0026e00523a85b90a92a93ddf6660939ecef3e54 upstream.
+
+Recent changes in the usbhid layer exposed a bug in usbcore.  If
+CONFIG_USB_DYNAMIC_MINORS is enabled then an interface may be assigned
+a minor number of 0.  However interfaces that aren't registered as USB
+class devices also have their minor number set to 0, during
+initialization.  As a result usb_find_interface() may return the
+wrong interface, leading to a crash.
+
+This patch (as1418) fixes the problem by initializing every
+interface's minor number to -1.  It also cleans up the
+usb_register_dev() function, which besides being somewhat awkwardly
+written, does not unwind completely on all its error paths.
+
+Signed-off-by: Alan Stern <stern at rowland.harvard.edu>
+Tested-by: Philip J. Turmel <philip at turmel.org>
+Tested-by: Gabriel Craciunescu <nix.or.die at googlemail.com>
+Tested-by: Alex Riesen <raa.lkml at gmail.com>
+Tested-by: Matthias Bayer <jackdachef at gmail.com>
+CC: Jiri Kosina <jkosina at suse.cz>
+Cc: stable <stable at kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+---
+ drivers/usb/core/file.c    |   35 ++++++++++++++++-------------------
+ drivers/usb/core/message.c |    1 +
+ 2 files changed, 17 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
+index f06f5db..1e6ccef 100644
+--- a/drivers/usb/core/file.c
++++ b/drivers/usb/core/file.c
+@@ -159,9 +159,9 @@ void usb_major_cleanup(void)
+ int usb_register_dev(struct usb_interface *intf,
+ 		     struct usb_class_driver *class_driver)
+ {
+-	int retval = -EINVAL;
++	int retval;
+ 	int minor_base = class_driver->minor_base;
+-	int minor = 0;
++	int minor;
+ 	char name[20];
+ 	char *temp;
+ 
+@@ -173,12 +173,17 @@ int usb_register_dev(struct usb_interface *intf,
+ 	 */
+ 	minor_base = 0;
+ #endif
+-	intf->minor = -1;
+-
+-	dbg ("looking for a minor, starting at %d", minor_base);
+ 
+ 	if (class_driver->fops == NULL)
+-		goto exit;
++		return -EINVAL;
++	if (intf->minor >= 0)
++		return -EADDRINUSE;
++
++	retval = init_usb_class();
++	if (retval)
++		return retval;
++
++	dev_dbg(&intf->dev, "looking for a minor, starting at %d", minor_base);
+ 
+ 	down_write(&minor_rwsem);
+ 	for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) {
+@@ -186,20 +191,12 @@ int usb_register_dev(struct usb_interface *intf,
+ 			continue;
+ 
+ 		usb_minors[minor] = class_driver->fops;
+-
+-		retval = 0;
++		intf->minor = minor;
+ 		break;
+ 	}
+ 	up_write(&minor_rwsem);
+-
+-	if (retval)
+-		goto exit;
+-
+-	retval = init_usb_class();
+-	if (retval)
+-		goto exit;
+-
+-	intf->minor = minor;
++	if (intf->minor < 0)
++		return -EXFULL;
+ 
+ 	/* create a usb class device for this usb interface */
+ 	snprintf(name, sizeof(name), class_driver->name, minor - minor_base);
+@@ -213,11 +210,11 @@ int usb_register_dev(struct usb_interface *intf,
+ 				      "%s", temp);
+ 	if (IS_ERR(intf->usb_dev)) {
+ 		down_write(&minor_rwsem);
+-		usb_minors[intf->minor] = NULL;
++		usb_minors[minor] = NULL;
++		intf->minor = -1;
+ 		up_write(&minor_rwsem);
+ 		retval = PTR_ERR(intf->usb_dev);
+ 	}
+-exit:
+ 	return retval;
+ }
+ EXPORT_SYMBOL_GPL(usb_register_dev);
+diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
+index 844683e..9f0ce7d 100644
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -1802,6 +1802,7 @@ free_interfaces:
+ 		intf->dev.groups = usb_interface_groups;
+ 		intf->dev.dma_mask = dev->dev.dma_mask;
+ 		INIT_WORK(&intf->reset_ws, __usb_queue_reset_device);
++		intf->minor = -1;
+ 		device_initialize(&intf->dev);
+ 		dev_set_name(&intf->dev, "%d-%s:%d.%d",
+ 			dev->bus->busnum, dev->devpath,
+-- 
+1.7.1
+

Modified: dists/trunk/linux-2.6/debian/patches/series/1~experimental.2
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/1~experimental.2	Tue Sep 28 01:13:05 2010	(r16363)
+++ dists/trunk/linux-2.6/debian/patches/series/1~experimental.2	Tue Sep 28 01:21:38 2010	(r16364)
@@ -1 +1,2 @@
 + bugfix/x86/drm-i915-Ensure-that-the-crtcinfo-is-populated-during-mode_fixup.patch
++ bugfix/all/USB-fix-bug-in-initialization-of-interface-minor-num.patch



More information about the Kernel-svn-changes mailing list