Hi Greg,

On Monday 02 August 2004 21:59, Greg KH wrote:
> On Thu, Jul 29, 2004 at 06:35:26PM +0200, Duncan Sands wrote:
> > +static int start_wait_urb(struct usb_device *dev, struct urb *urb, int timeout, 
> > int* actual_length)
> 
> Hm, with the exception of these two lines:
> 
> > +           up(&dev->serialize);
> > +           wait_for_completion(&done);
> > +           down(&dev->serialize);
> 
> I don't see how this is any different from usb_start_wait_urb().  You
> say it's interruptable, but if it is, then why isn't
> usb_start_wait_urb()?  Why can't you just use it (or really the
> functions that call it), by dropping the semaphore before calling it?

it isn't interruptible... yet.  Anyway, making it interruptible is a side issue.
The real question is: why is using usb_start_wait_urb racy, and how do
the above lines fix the problem?  It is all a question of whether dev->serialize
is released before calling usb_submit_urb, or after.  If you use usb_start_wait_urb,
then dev->serialize is dropped before the call to usb_submit_urb.  With my
patch, it is dropped after the call.  Here is an example race if you use
usb_start_wait_urb:

(A) you call proc_bulk to send an urb (to an endpoint E, say)
(A) dev->serialize is dropped in proc_bulk
(B) someone changes the current configuration.  This causes usbfs's
disconnect method to be called (which, incidentally, causes it to "unclaim"
any interfaces it claimed).  Since we have a reference to the struct usb_device,
there is no need to worry about things going "boom".  Suppose the new
configuration has an endpoint with the same pipe as E.
(C) usb_submit_urb is now called in usb_start_wait_urb.  This sends the urb to
the new endpoint, which is the wrong endpoint...

There seems to be general agreement that this race exists.  Submitting
the urb before dropping the lock avoids the race.  Probably there are other
similar races, for example when you change the altsetting.

I wrote the patch the way I did in order to avoid these races.  However,
(1) the race still exists in another form, and (2) who cares about this race,
anyway?

(1) Still racy: since proc_bulk takes the endpoint number as an argument,
if the configuration changes just before you call proc_bulk, the urb will
happily be sent to the wrong endpoint.  Let me say more on this point:
before submitting an urb, you are supposed to claim the interface.  If
the configuration changes, then the interface is "unclaimed".  If you
send the urb after the configuration changes, then you are sending it
to an interface you haven't claimed.  Therefore the submission should fail
and the race is avoided... except that it isn't: if you haven't claimed the
interface, then usbfs automatically claims it for you, and your urb is
happily sent to the wrong place.

Summary: to avoid the race, not only do you need my patch the way
it is, you also need to stop usbfs from autoclaiming interfaces.

In my opinion, it is a mistake to have usbfs automatically claim interfaces.
It would be easy to change, but it would also break many programs.  We
could mark autoclaiming as deprecated, and remove it in a years time.
That means that you get no benefit from not using usb_start_wait_urb for
at least one year.

(2) Who cares?  It seems rather unlikely that anyone will hit this (*).  Also,
any driver which sometimes submits urbs after disconnect has been called
presumably suffers from the same problem.  Should usbfs do better?  Since
everyone knows that usbfs is a piece of crud, soon to be replaced by usbfs2,
why should we bother with these unlikely cases?  Of course, let us pity the poor
person who ends up sending an urb to the wrong endpoint, and then wonders
why his task is stuck in the (uninterruptible) D state because his urb is not
completing (this is possible).

Here is what I suggest.  I send you a patch that fixes up proc_bulk and
proc_control as my current patch does, but doesn't push taking dev->serialize
down into the individual ioctl methods.

All the best,

Duncan.

(*) This argument cuts no ice with me, I'm just playing the devil's advocate here.


-------------------------------------------------------
This SF.Net email is sponsored by OSTG. Have you noticed the changes on
Linux.com, ITManagersJournal and NewsForge in the past few weeks? Now,
one more big change to announce. We are now OSTG- Open Source Technology
Group. Come see the changes on the new OSTG site. www.ostg.com
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to