From: Duncan Sands <baldrick@free.fr>
To: Greg KH <greg@kroah.com>
Cc: linux-usb-devel@lists.sf.net, linux-kernel@vger.kernel.org,
Frederic Detienne <fd@cisco.com>
Subject: Re: [linux-usb-devel] [PATCH 1/9] USB usbfs: take a reference to the usb device
Date: Sat, 17 Apr 2004 22:17:10 +0200 [thread overview]
Message-ID: <200404172217.10994.baldrick@free.fr> (raw)
In-Reply-To: <200404141229.26677.baldrick@free.fr>
On Wednesday 14 April 2004 12:29, Duncan Sands wrote:
> Hi Greg, this is the first of a series of patches that replace the
> per-file semaphore ps->devsem with the per-device semaphore
> ps->dev->serialize. The role of devsem was to protect against
> device disconnection. This can be done equally well using
> ps->dev->serialize. On the other hand, ps->dev->serialize
> protects against configuration and other changes, and has
> already been introduced into usbfs in several places. Using
> just one semaphore simplifies the code and removes some
> remaining race conditions. It should also fix the oopses some
> people have been seeing. In this first patch, a reference is
> taken to the usb device as long as the usbfs file is open. That
> way we can use ps->dev->serialize for as long as ps exists.
Perhaps I should explain why something like this is needed.
Take a random subroutine in devio.c. I just made a random
choice (yes, really) and got proc_submiturb. It starts like
this:
if (copy_from_user(&uurb, arg, sizeof(uurb)))
return -EFAULT;
if (uurb.flags & ~(USBDEVFS_URB_ISO_ASAP|USBDEVFS_URB_SHORT_NOT_OK|
URB_NO_FSBR|URB_ZERO_PACKET))
return -EINVAL;
if (!uurb.buffer)
return -EINVAL;
if (uurb.signr != 0 && (uurb.signr < SIGRTMIN || uurb.signr > SIGRTMAX))
return -EINVAL;
if (!(uurb.type == USBDEVFS_URB_TYPE_CONTROL && (uurb.endpoint & ~USB_EN
DPOINT_DIR_MASK) == 0)) {
if ((intf = findintfep(ps->dev, uurb.endpoint)) < 0)
return intf;
if ((ret = checkintf(ps, intf)))
return ret;
}
Notice the calls to findintfep and to checkintf? The first scans through interfaces to
find which one we want, the second looks up the interface and claims it. What is to
stop the interfaces changing while we are doing that (due to a configuration change
for example)? Answer: nothing. Almost all subroutines in devio.c have calls like
these. The ps->dev->serialize semaphore needs to be taken to protect against
changes, but this simply isn't down right now. Normal USB drivers don't suffer from
this problem: they claim interfaces via their probe method (during which dev->serialize
is held for them by the core), and get disconnected by the core before any configuration
changes are performed. But usbfs is different: it goes around claiming interfaces all
over the place. For example, proc_submiturb like most other routines can be called
on an interface that hasn't been claimed - it will "helpfully" claim it (checkintf does it).
This means mapping an interface number to struct usb_interface - so we need to take
dev->serialize. If we removed this autoclaiming of interfaces (which would be a good
thing to do IMHO) then things would already be a lot better - but that would break
at least one user space program I know of, so surely others too. Anyway, checkintf
isn't the only problem here - devio.c is riddled with races of this kind. The simplest
solution is to systematically take ps->dev->serialize when entering the usbfs
routines, which is what my patches do. This should be regarded as a first step: it
gives correctness, but at the cost of a probable performance hit. In later steps we can
(1) turn dev->serialize into a rwsem
(2) push the acquisition of dev->serialize down to the lower levels as they are fixed up.
All the best,
Duncan.
next prev parent reply other threads:[~2004-04-17 20:17 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-04-14 10:29 Duncan Sands
2004-04-17 20:17 ` Duncan Sands [this message]
2004-04-17 20:33 ` [linux-usb-devel] " Oliver Neukum
2004-04-18 9:35 ` Duncan Sands
2004-04-18 13:57 ` Oliver Neukum
2004-04-18 14:08 ` Duncan Sands
2004-04-18 14:40 ` Alan Stern
2004-04-19 17:25 ` David Brownell
2004-04-23 23:18 ` Greg KH
2004-04-26 14:05 ` Duncan Sands
2004-04-26 22:14 ` Greg KH
2004-04-27 8:58 ` [linux-usb-devel] " Oliver Neukum
2004-04-30 9:04 ` Duncan Sands
2004-05-01 23:01 ` 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=200404172217.10994.baldrick@free.fr \
--to=baldrick@free.fr \
--cc=fd@cisco.com \
--cc=greg@kroah.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb-devel@lists.sf.net \
/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®