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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox