mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Russ Dill <russ.dill@gmail.com>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Greg KH <greg@kroah.com>, Alan Stern <stern@rowland.harvard.edu>,
	Greg KH <gregkh@suse.de>,
	Andrew Morton <akpm@linux-foundation.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	linux-usb@vger.kernel.org
Subject: Re: [GIT PATCH] USB patches for 2.6.33-git
Date: Mon, 14 Dec 2009 21:45:35 -0700	[thread overview]
Message-ID: <1260852335.1886.0.camel@russ-laptop> (raw)
In-Reply-To: <alpine.LFD.2.00.0912142031170.14385@localhost.localdomain>

[-- Attachment #1: Type: text/plain, Size: 4824 bytes --]

On Mon, 2009-12-14 at 20:36 -0800, Linus Torvalds wrote:
> 
> On Mon, 14 Dec 2009, Russ Dill wrote:
> > @@ -144,10 +144,9 @@ static int __find_interface(struct device *dev, void *data)
> >  		return 0;
> >  
> >  	intf = to_usb_interface(dev);
> > -	if (intf->minor != -1 && intf->minor == arg->minor) {
> > -		arg->interface = intf;
> > +	if (intf->minor != -1 && intf->minor == arg->minor &&
> > +		dev->driver == arg->drv)
> >  		return 1;
> > -	}
> >  	return 0;
> >  }
> 
> Btw, can we please write this somewhat more readably, and just do
> 
> 	if (dev->driver != arg->drv)
> 		return 0;
> 	intf = to_usb_interface(dev);
> 	return intf->minor == arg->minor;
> 
> because the whole "intf->minor != -1" thing is pointless (we're going to 
> test it against 'arg->minor', and if that is -1, then the caller damn well 
> gets what he deserves anyway).
> 
> This way there are no complex multi-line crud expressions, and it all 
> looks simpler. No?

Yup.

From 41e394bc38b9d5224cc5e8013f45e769910a114e Mon Sep 17 00:00:00 2001
From: Russ Dill <Russ.Dill@gmail.com>
Date: Wed, 18 Nov 2009 10:31:27 -0700
Subject: [PATCH] Close usb_find_interface race v3

USB drivers that create character devices call usb_register_dev in their
probe function. This associates the usb_interface device with that minor
number and creates the character device and announces it to the world.
However, the driver's probe function is called before the new
usb_interface is added to the driver's klist_devices.

This is a problem because userspace will respond to the character device
creation announcement by opening the character device. The driver's open
function will the call usb_find_interface to find the usb_interface
associated with that minor number. usb_find_interface will walk the
driver's list of devices and find the usb_interface with the matching
minor number.

Because the announcement happens before the usb_interface is added to the
driver's klist_devices, a race condition exists. A straightforward fix
is to walk the list of devices on usb_bus_type instead since the device
is added to that list before the announcement occurs.

bus_find_device calls get_device to bump the reference count on the found
device. It is arguable that the reference count should be dropped by the
caller of usb_find_interface instead of usb_find_interface, however,
the current users of usb_find_interface do not expect this.

The original version of this patch only matched against minor number
instead of driver and minor number. This version matches against both.

Signed-off-by: Russ Dill <Russ.Dill@gmail.com>
---
 drivers/usb/core/usb.c |   31 ++++++++++++++++---------------
 1 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index b1b85ab..52e5e31 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -132,7 +132,7 @@ EXPORT_SYMBOL_GPL(usb_altnum_to_altsetting);
 
 struct find_interface_arg {
 	int minor;
-	struct usb_interface *interface;
+	struct device_driver *drv;
 };
 
 static int __find_interface(struct device *dev, void *data)
@@ -143,12 +143,10 @@ static int __find_interface(struct device *dev, void *data)
 	if (!is_usb_interface(dev))
 		return 0;
 
+	if (dev->driver != arg->drv)
+		return 0;
 	intf = to_usb_interface(dev);
-	if (intf->minor != -1 && intf->minor == arg->minor) {
-		arg->interface = intf;
-		return 1;
-	}
-	return 0;
+	return intf->minor == arg->minor;
 }
 
 /**
@@ -156,21 +154,24 @@ static int __find_interface(struct device *dev, void *data)
  * @drv: the driver whose current configuration is considered
  * @minor: the minor number of the desired device
  *
- * This walks the driver device list and returns a pointer to the interface
- * with the matching minor.  Note, this only works for devices that share the
- * USB major number.
+ * This walks the bus device list and returns a pointer to the interface
+ * with the matching minor and driver.  Note, this only works for devices
+ * that share the USB major number.
  */
 struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
 {
 	struct find_interface_arg argb;
-	int retval;
+	struct device *dev;
 
 	argb.minor = minor;
-	argb.interface = NULL;
-	/* eat the error, it will be in argb.interface */
-	retval = driver_for_each_device(&drv->drvwrap.driver, NULL, &argb,
-					__find_interface);
-	return argb.interface;
+	argb.drv = &drv->drvwrap.driver;
+
+	dev = bus_find_device(&usb_bus_type, NULL, &argb, __find_interface);
+
+	/* Drop reference count from bus_find_device */
+	put_device(dev);
+
+	return dev ? to_usb_interface(dev) : NULL;
 }
 EXPORT_SYMBOL_GPL(usb_find_interface);
 
-- 
1.6.5





[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

  reply	other threads:[~2009-12-15  4:45 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-12-11 21:26 Greg KH
2009-12-12  6:59 ` [build failure] " Ingo Molnar
2009-12-12  7:00   ` David Miller
2009-12-12  7:15     ` [PATCH] kaweth: Replace runtime power management primitives Ingo Molnar
2009-12-15  0:39 ` [GIT PATCH] USB patches for 2.6.33-git Linus Torvalds
2009-12-15  0:52   ` Greg KH
2009-12-15  1:00     ` Linus Torvalds
2009-12-15  1:47       ` Linus Torvalds
2009-12-15  2:29         ` Linus Torvalds
2009-12-15  3:09           ` Linus Torvalds
2009-12-15  3:17             ` russ.dill
2009-12-15  4:00               ` Russ Dill
2009-12-15  4:28                 ` Linus Torvalds
2009-12-15  4:44                   ` Linus Torvalds
2009-12-15 14:31                     ` Greg KH
2009-12-15  4:36                 ` Linus Torvalds
2009-12-15  4:45                   ` Russ Dill [this message]
2009-12-15  6:02                     ` Linus Torvalds
2009-12-15  6:11                       ` Russ Dill
2009-12-15  6:20                         ` Linus Torvalds
2010-03-02 23:09 Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1260852335.1886.0.camel@russ-laptop \
    --to=russ.dill@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=greg@kroah.com \
    --cc=gregkh@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=stern@rowland.harvard.edu \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®