linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] media: omap_vout: potential buffer overflow in vidioc_dqbuf()
@ 2019-04-09 11:29 Dan Carpenter
  2019-04-10 10:50 ` Hans Verkuil
  0 siblings, 1 reply; 5+ messages in thread
From: Dan Carpenter @ 2019-04-09 11:29 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Amber Jain
  Cc: Hans Verkuil, Niklas Söderlund, Philipp Zabel,
	Benoit Parrot, linux-media, kernel-janitors, Andrzej Hajda

The "b->index" is a u32 the comes from the user in the ioctl.  It hasn't
been checked.  We aren't supposed to use it but we're instead supposed
to use the value that gets written to it when we call videobuf_dqbuf().

The videobuf_dqbuf() first memsets it to zero and then re-initializes it
inside the videobuf_status() function.  It's this final value which we
want.

Fixes: 72915e851da9 ("[media] V4L2: OMAP: VOUT: dma map and unmap v4l2 buffers in qbuf and dqbuf")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
---
UNTESTED!  I think I understand this code now, but I have struggled to
read it correctly in the past.  Please review carefully.


 drivers/media/platform/omap/omap_vout.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
index 37f0d7146dfa..15e38990e85a 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -1527,8 +1527,6 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
 	unsigned long size;
 	struct videobuf_buffer *vb;
 
-	vb = q->bufs[b->index];
-
 	if (!vout->streaming)
 		return -EINVAL;
 
@@ -1539,6 +1537,8 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
 		/* Call videobuf_dqbuf for  blocking mode */
 		ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0);
 
+	vb = q->bufs[b->index];
+
 	addr = (unsigned long) vout->buf_phy_addr[vb->i];
 	size = (unsigned long) vb->size;
 	dma_unmap_single(vout->vid_dev->v4l2_dev.dev,  addr,
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] media: omap_vout: potential buffer overflow in vidioc_dqbuf()
  2019-04-09 11:29 [PATCH] media: omap_vout: potential buffer overflow in vidioc_dqbuf() Dan Carpenter
@ 2019-04-10 10:50 ` Hans Verkuil
  2019-04-10 11:14   ` Dan Carpenter
  2019-04-11  9:01   ` [PATCH v2] " Dan Carpenter
  0 siblings, 2 replies; 5+ messages in thread
From: Hans Verkuil @ 2019-04-10 10:50 UTC (permalink / raw)
  To: Dan Carpenter, Mauro Carvalho Chehab, Amber Jain
  Cc: Niklas Söderlund, Philipp Zabel, Benoit Parrot, linux-media,
	kernel-janitors, Andrzej Hajda

On 4/9/19 1:29 PM, Dan Carpenter wrote:
> The "b->index" is a u32 the comes from the user in the ioctl.  It hasn't
> been checked.  We aren't supposed to use it but we're instead supposed
> to use the value that gets written to it when we call videobuf_dqbuf().
> 
> The videobuf_dqbuf() first memsets it to zero and then re-initializes it
> inside the videobuf_status() function.  It's this final value which we
> want.
> 
> Fixes: 72915e851da9 ("[media] V4L2: OMAP: VOUT: dma map and unmap v4l2 buffers in qbuf and dqbuf")
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> ---
> UNTESTED!  I think I understand this code now, but I have struggled to
> read it correctly in the past.  Please review carefully.
> 
> 
>  drivers/media/platform/omap/omap_vout.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
> index 37f0d7146dfa..15e38990e85a 100644
> --- a/drivers/media/platform/omap/omap_vout.c
> +++ b/drivers/media/platform/omap/omap_vout.c
> @@ -1527,8 +1527,6 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
>  	unsigned long size;
>  	struct videobuf_buffer *vb;
>  
> -	vb = q->bufs[b->index];
> -
>  	if (!vout->streaming)
>  		return -EINVAL;
>  
> @@ -1539,6 +1537,8 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
>  		/* Call videobuf_dqbuf for  blocking mode */
>  		ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0);

We need a:

	if (ret)
		return ret;

here. Or alternatively, add 'if (!ret)' around the next five lines.

b->index is only valid if the videobuf_dqbuf call returned 0.

Regards,

	Hans

>  
> +	vb = q->bufs[b->index];
> +
>  	addr = (unsigned long) vout->buf_phy_addr[vb->i];
>  	size = (unsigned long) vb->size;
>  	dma_unmap_single(vout->vid_dev->v4l2_dev.dev,  addr,
> 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] media: omap_vout: potential buffer overflow in vidioc_dqbuf()
  2019-04-10 10:50 ` Hans Verkuil
@ 2019-04-10 11:14   ` Dan Carpenter
  2019-04-10 14:05     ` [EXTERNAL] " Scheurer, Amber
  2019-04-11  9:01   ` [PATCH v2] " Dan Carpenter
  1 sibling, 1 reply; 5+ messages in thread
From: Dan Carpenter @ 2019-04-10 11:14 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Mauro Carvalho Chehab, Amber Jain, Niklas Söderlund,
	Philipp Zabel, Benoit Parrot, linux-media, kernel-janitors,
	Andrzej Hajda

On Wed, Apr 10, 2019 at 12:50:31PM +0200, Hans Verkuil wrote:
> On 4/9/19 1:29 PM, Dan Carpenter wrote:
> > diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
> > index 37f0d7146dfa..15e38990e85a 100644
> > --- a/drivers/media/platform/omap/omap_vout.c
> > +++ b/drivers/media/platform/omap/omap_vout.c
> > @@ -1527,8 +1527,6 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
> >  	unsigned long size;
> >  	struct videobuf_buffer *vb;
> >  
> > -	vb = q->bufs[b->index];
> > -
> >  	if (!vout->streaming)
> >  		return -EINVAL;
> >  
> > @@ -1539,6 +1537,8 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
> >  		/* Call videobuf_dqbuf for  blocking mode */
> >  		ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0);
> 
> We need a:
> 
> 	if (ret)
> 		return ret;
> 
> here. Or alternatively, add 'if (!ret)' around the next five lines.
> 
> b->index is only valid if the videobuf_dqbuf call returned 0.
> 

Doh.  Thanks.

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [EXTERNAL] Re: [PATCH] media: omap_vout: potential buffer overflow in vidioc_dqbuf()
  2019-04-10 11:14   ` Dan Carpenter
@ 2019-04-10 14:05     ` Scheurer, Amber
  0 siblings, 0 replies; 5+ messages in thread
From: Scheurer, Amber @ 2019-04-10 14:05 UTC (permalink / raw)
  To: Dan Carpenter, Hans Verkuil
  Cc: Mauro Carvalho Chehab, Niklas Söderlund, Philipp Zabel,
	Parrot, Benoit, linux-media, kernel-janitors, Andrzej Hajda

I think you might have the wrong Amber copied on this email. 

Amber

-----Original Message-----
From: Dan Carpenter [mailto:dan.carpenter@oracle.com] 
Sent: Wednesday, April 10, 2019 6:14 AM
To: Hans Verkuil
Cc: Mauro Carvalho Chehab; Scheurer, Amber; Niklas Söderlund; Philipp Zabel; Parrot, Benoit; linux-media@vger.kernel.org; kernel-janitors@vger.kernel.org; Andrzej Hajda
Subject: [EXTERNAL] Re: [PATCH] media: omap_vout: potential buffer overflow in vidioc_dqbuf()

On Wed, Apr 10, 2019 at 12:50:31PM +0200, Hans Verkuil wrote:
> On 4/9/19 1:29 PM, Dan Carpenter wrote:
> > diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
> > index 37f0d7146dfa..15e38990e85a 100644
> > --- a/drivers/media/platform/omap/omap_vout.c
> > +++ b/drivers/media/platform/omap/omap_vout.c
> > @@ -1527,8 +1527,6 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
> >  	unsigned long size;
> >  	struct videobuf_buffer *vb;
> >  
> > -	vb = q->bufs[b->index];
> > -
> >  	if (!vout->streaming)
> >  		return -EINVAL;
> >  
> > @@ -1539,6 +1537,8 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
> >  		/* Call videobuf_dqbuf for  blocking mode */
> >  		ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0);
> 
> We need a:
> 
> 	if (ret)
> 		return ret;
> 
> here. Or alternatively, add 'if (!ret)' around the next five lines.
> 
> b->index is only valid if the videobuf_dqbuf call returned 0.
> 

Doh.  Thanks.

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2] media: omap_vout: potential buffer overflow in vidioc_dqbuf()
  2019-04-10 10:50 ` Hans Verkuil
  2019-04-10 11:14   ` Dan Carpenter
@ 2019-04-11  9:01   ` Dan Carpenter
  1 sibling, 0 replies; 5+ messages in thread
From: Dan Carpenter @ 2019-04-11  9:01 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Hans Verkuil, Niklas Söderlund, Lad, Prabhakar, linux-media,
	kernel-janitors

The "b->index" is a u32 the comes from the user in the ioctl.  It hasn't
been checked.  We aren't supposed to use it but we're instead supposed
to use the value that gets written to it when we call videobuf_dqbuf().

The videobuf_dqbuf() first memsets it to zero and then re-initializes it
inside the videobuf_status() function.  It's this final value which we
want.

Hans Verkuil pointed out that we need to check the return from
videobuf_dqbuf().  I ended up doing a little cleanup related to that as
well.

Fixes: 72915e851da9 ("[media] V4L2: OMAP: VOUT: dma map and unmap v4l2 buffers in qbuf and dqbuf")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
---
v2: check videobuf_dqbuf() return

 drivers/media/platform/omap/omap_vout.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
index 37f0d7146dfa..cb6a9e3946b6 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -1527,23 +1527,20 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
 	unsigned long size;
 	struct videobuf_buffer *vb;
 
-	vb = q->bufs[b->index];
-
 	if (!vout->streaming)
 		return -EINVAL;
 
-	if (file->f_flags & O_NONBLOCK)
-		/* Call videobuf_dqbuf for non blocking mode */
-		ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 1);
-	else
-		/* Call videobuf_dqbuf for  blocking mode */
-		ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0);
+	ret = videobuf_dqbuf(q, b, !!(file->f_flags & O_NONBLOCK));
+	if (ret)
+		return ret;
+
+	vb = q->bufs[b->index];
 
 	addr = (unsigned long) vout->buf_phy_addr[vb->i];
 	size = (unsigned long) vb->size;
 	dma_unmap_single(vout->vid_dev->v4l2_dev.dev,  addr,
 				size, DMA_TO_DEVICE);
-	return ret;
+	return 0;
 }
 
 static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-04-11  9:02 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-09 11:29 [PATCH] media: omap_vout: potential buffer overflow in vidioc_dqbuf() Dan Carpenter
2019-04-10 10:50 ` Hans Verkuil
2019-04-10 11:14   ` Dan Carpenter
2019-04-10 14:05     ` [EXTERNAL] " Scheurer, Amber
2019-04-11  9:01   ` [PATCH v2] " Dan Carpenter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).