[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