public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: David Fries <David@fries.net>
Cc: linux-kernel@vger.kernel.org,
	Guennadi Liakhovetski <g.liakhovetski@gmx.de>,
	Mauro Carvalho Chehab <mchehab@s-opensource.com>,
	stable@vger.kernel.org
Subject: Re: [PATCH 1/1] media: uvc_driver: fix USB Camera ref leak denial of service
Date: Sat, 26 May 2018 19:47:12 +0300	[thread overview]
Message-ID: <7755956.sgLFZZjbUQ@avalon> (raw)
In-Reply-To: <20180526163718.GE28969@spacedout.fries.net>

Hi David,

On Saturday, 26 May 2018 19:37:18 EEST David Fries wrote:
> Laurent and Mauro,
> 
> I've reviewed Philipp Zabel's 49770 patch, it looks like they
> equivalent, but take a different path.  My version does the unref in
> uvc_unregister_video, Zabel's does the unref in each caller of
> uvc_unregister_video.  I think I would prefer it to be in fewer
> places.

While I agree that avoiding code duplication is a good idea, we also need to 
ensure that the unref call is the very last operation we perform, otherwise 
we'll risk a use-after-free. The uvc_unregister_video() function is called 
last so that's guaranteed with your patch. However, by hiding the unref there 
from the callers, I wonder whether it couldn't result in issues in the future 
if someone decides to add code after the uvc_unregister_video() calls without 
noticing the unref issue.

> Any ideas on the sysfs group 'power' not found bug on removal while on
> use?

I haven't had time to investigate them yet, please feel free to give it a go 
without waiting for me :-)

> Thanks, it will be great to get this fixed.
> 
> On Sat, May 26, 2018 at 07:21:11PM +0300, Laurent Pinchart wrote:
> > Hi David,
> > 
> > Thank you for the patch.
> > 
> > On Saturday, 26 May 2018 18:50:46 EEST David Fries wrote:
> > > Commit 9d15cd958c17 ("media: uvcvideo: Convert from using an atomic
> > > variable to a reference count")
> > > didn't take into account that while the old counter was initialized to
> > > 0 (no stream open), kref_init starts with a reference of 1.  The
> > > reference count on unplug no longer reaches 0, uvc_delete isn't
> > > called, and evdev doesn't release /dev/input/event*.  Plug and unplug
> > > enough times and it runs out of device minors preventing any new input
> > > device and the use of newly plugged in USB video cameras until the
> > > system is rebooted.
> > > 
> > > Signed-off-by: David Fries <David@Fries.net>
> > > Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > > Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > > Cc: Mauro Carvalho Chehab <mchehab@s-opensource.com>
> > > Cc: stable@vger.kernel.org
> > 
> > Philipp Zabel has already posted a similar patch, see https://
> > patchwork.linuxtv.org/patch/49770/
> > 
> > Mauro,
> > 
> > This is a serious issue so I'd like to get the patch merged in v4.18, but
> > it could be argued that it's getting late for that, especially given that
> > the bug has been there since v4.14. Would you be OK merging this in v4.18
> > ? If so could you pick https://patchwork.linuxtv.org/patch/49770/ up, or
> > would you like me to send a pull request ?
> > 
> > > ---
> > > 
> > >  drivers/media/usb/uvc/uvc_driver.c | 11 ++++-------
> > >  1 file changed, 4 insertions(+), 7 deletions(-)
> > > 
> > > diff --git a/drivers/media/usb/uvc/uvc_driver.c
> > > b/drivers/media/usb/uvc/uvc_driver.c index 2469b49..3cbdc87 100644
> > > --- a/drivers/media/usb/uvc/uvc_driver.c
> > > +++ b/drivers/media/usb/uvc/uvc_driver.c
> > > @@ -1871,13 +1871,6 @@ static void uvc_unregister_video(struct
> > > uvc_device
> > > *dev) {
> > > 
> > >  	struct uvc_streaming *stream;
> > > 
> > > -	/* Unregistering all video devices might result in uvc_delete() 
being
> > > -	 * called from inside the loop if there's no open file handle. To
> > > avoid
> > > -	 * that, increment the refcount before iterating over the streams 
and
> > > -	 * decrement it when done.
> > > -	 */
> > > -	kref_get(&dev->ref);
> > > -
> > > 
> > >  	list_for_each_entry(stream, &dev->streams, list) {
> > >  	
> > >  		if (!video_is_registered(&stream->vdev))
> > >  		
> > >  			continue;
> > > 
> > > @@ -1888,6 +1881,10 @@ static void uvc_unregister_video(struct
> > > uvc_device
> > > *dev) uvc_debugfs_cleanup_stream(stream);
> > > 
> > >  	}
> > > 
> > > +	/* Release the reference implicit in kref_init from uvc_probe,
> > > +	 * the UVC device won't be deleted until the last file descriptor
> > > +	 * is also closed.
> > > +	 */
> > > 
> > >  	kref_put(&dev->ref, uvc_delete);
> > >  
> > >  }


-- 
Regards,

Laurent Pinchart

      reply	other threads:[~2018-05-26 16:47 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-26 15:50 [PATCH 1/1] media: uvc_driver: fix USB Camera ref leak denial of service David Fries
2018-05-26 16:21 ` Laurent Pinchart
2018-05-26 16:37   ` David Fries
2018-05-26 16:47     ` Laurent Pinchart [this message]

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=7755956.sgLFZZjbUQ@avalon \
    --to=laurent.pinchart@ideasonboard.com \
    --cc=David@fries.net \
    --cc=g.liakhovetski@gmx.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mchehab@s-opensource.com \
    --cc=stable@vger.kernel.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