From: Stefani Seibold <stefani@seibold.net>
To: Oliver Neukum <oliver@neukum.org>
Cc: linux-kernel@vger.kernel.org, gregkh@linuxfoundation.org,
alan@lxorguk.ukuu.org.uk,
thomas.braunstorfinger@rohde-schwarz.com
Subject: Re: [PATCH] add new NRP power meter USB device driver
Date: Sun, 03 Jun 2012 07:15:22 +0200 [thread overview]
Message-ID: <1338700522.4801.8.camel@wall-e> (raw)
In-Reply-To: <201206022224.21443.oliver@neukum.org>
Am Samstag, den 02.06.2012, 22:24 +0200 schrieb Oliver Neukum:
> Am Samstag, 2. Juni 2012, 18:18:59 schrieb stefani@seibold.net:
> > +static int bulks_in_submit(struct usb_nrpz *dev)
> > +{
> > + int ret;
> > + unsigned i;
> > +
> > + for (i = 0; i != ARRAY_SIZE(dev->in_urbs); ++i) {
> > + usb_anchor_urb(&dev->in_urbs[i], &dev->in_running);
> > +
> > + ret = usb_submit_urb(&dev->in_urbs[i], GFP_KERNEL);
> > + if (ret) {
> > + usb_kill_anchored_urbs(&dev->in_running);
> > + return ret;
> > + }
> > + }
> > + return 0;
> > +}
>
> This is used in the resume code path. During resume you
> cannot swap, as the swap device may still be asleep.
> Therefore GFP_NOIO should be used. It's considered
> best practice to pass the gfp parameter to such methods.
>
Good point. Fixed.
> > +static ssize_t nrpz_read(struct file *file, char __user *buffer, size_t count,
> > + loff_t *ppos)
> > +{
> > + struct usb_nrpz *dev = file->private_data;
> > + int ret;
> > + struct urb *urb;
> > + size_t n;
> > +
> > + /* verify that we actually have some data to read */
> > + if (!count)
> > + return 0;
> > +
> > + /* lock the read data */
> > + if (file->f_flags & O_NONBLOCK) {
> > + if (!mutex_trylock(&dev->read_mutex))
> > + return -EAGAIN;
>
> Congratulations. I overlooked this. Does skeleton do it right?
>
This issue was reported by Alan Cox. Skeleton must be also fixed.
> > + } else {
> > + ret = mutex_lock_interruptible(&dev->read_mutex);
> > + if (ret)
> > + return ret;
> > + }
> > +
> > + for (;;) {
> > + urb = urb_list_get(&dev->read_lock, &dev->in_avail);
> > + if (urb)
> > + break;
> > +
> > + /* verify that the device wasn't unplugged */
> > + if (!dev->connected) {
> > + ret = -ENODEV;
> > + goto exit;
> > + }
> > +
> > + if (file->f_flags & O_NONBLOCK) {
> > + ret = -EAGAIN;
> > + goto exit;
> > + }
> > +
> > + ret = wait_event_interruptible(dev->wq,
> > + !list_empty(&dev->in_avail) || !dev->connected);
> > + if (ret) {
> > + ret = -ERESTARTSYS;
> > + goto exit;
> > + }
> > + }
> > +
> > + if (!urb->status) {
> > + n = min(count, urb->actual_length);
> > +
> > + if (copy_to_user(buffer, urb->transfer_buffer, n)) {
> > + urb_list_add(&dev->read_lock, urb, &dev->in_avail);
> > + ret = -EFAULT;
> > + goto exit;
> > + }
> > + } else {
> > + n = -EPIPE;
> > + }
> > +
> > + usb_anchor_urb(urb, &dev->in_running);
> > +
> > + ret = usb_submit_urb(urb, GFP_KERNEL);
> > + if (ret) {
> > + usb_unanchor_urb(urb);
> > + urb_list_add_tail(&dev->read_lock, urb, &dev->in_avail);
> > + urb->status = ret;
>
> That is a bug. You will report that error the next time the URB comes up.
> That's wrong. I think you need a special error code that will cause you
> to just resubmit the URB and go for the next URB.
>
I think it is okay to push it back to the tail of the list and the next
time i will get this URB i will report this error to the userspace. This
keeps the order of the errors. But i will do more investigation on this.
> > + case NRPZ_GETSENSORINFO:
> > + {
Kick away in the next release :-(
> > +static int nrpz_release(struct inode *inode, struct file *file)
> > +{
> > + struct usb_nrpz *dev = file->private_data;
> > +
> > + if (dev == NULL)
> > + return -ENODEV;
> > +
> > + usb_kill_anchored_urbs(&dev->in_running);
> > + usb_kill_anchored_urbs(&dev->out_running);
>
> Isn't this a noop as you've implemented flush() ?
>
No, it is not a noop. flush() can be interrupted and will only handle
the out_running urbs.
> > +
> > + bulks_release(dev->out_urbs, ARRAY_SIZE(dev->out_urbs), dev->out_size);
> > + bulks_release(dev->in_urbs, ARRAY_SIZE(dev->in_urbs), dev->in_size);
> > +
> > + /* decrement the count on our device */
> > + kref_put(&dev->kref, nrpz_delete);
> > +
> > + spin_lock_irq(&dev->read_lock);
> > + dev->in_use = false;
> > + spin_unlock_irq(&dev->read_lock);
>
> Looks like a use after free. You should drop the reference as the very
> last thing.
>
Thanks. One of this nasty little tiny race conditions...
Greetings,
Stefani
next prev parent reply other threads:[~2012-06-03 5:15 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-06-02 16:18 [PATCH] add new NRP power meter USB device driver stefani
2012-06-02 20:24 ` Oliver Neukum
2012-06-03 5:15 ` Stefani Seibold [this message]
-- strict thread matches above, loose matches on Subject: below --
2012-06-03 8:46 stefani
2012-06-03 11:48 ` Joe Perches
2012-06-13 0:58 ` Greg KH
2012-05-29 19:14 stefani
2012-05-29 23:15 ` Greg KH
2012-05-31 8:47 ` Stefani Seibold
2012-05-31 9:41 ` Greg KH
2012-06-02 7:10 ` Stefani Seibold
2012-06-02 12:10 ` Greg KH
2012-06-02 15:43 ` Stefani Seibold
2012-05-31 9:53 ` Greg KH
2012-05-31 10:17 ` Oliver Neukum
2012-05-31 12:04 ` Greg KH
2012-05-31 12:32 ` Oliver Neukum
2012-05-31 12:48 ` Greg KH
2012-05-31 14:22 ` Oliver Neukum
2012-05-31 14:32 ` Greg KH
2012-06-01 13:38 ` Oliver Neukum
2012-05-30 8:10 ` Oliver Neukum
2012-05-31 7:43 ` Stefani Seibold
2012-05-31 8:20 ` Oliver Neukum
2012-05-31 9:21 ` Stefani Seibold
2012-06-01 14:16 ` Oliver Neukum
2012-06-01 14:34 ` Alan Cox
2012-06-02 5:57 ` Stefani Seibold
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=1338700522.4801.8.camel@wall-e \
--to=stefani@seibold.net \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=oliver@neukum.org \
--cc=thomas.braunstorfinger@rohde-schwarz.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.