linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] omap_vout: find_vma() needs ->mmap_sem held
@ 2012-12-15 20:12 Al Viro
  2012-12-15 20:38 ` Al Viro
  2012-12-16 20:01 ` Paul Bolle
  0 siblings, 2 replies; 8+ messages in thread
From: Al Viro @ 2012-12-15 20:12 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: linux-kernel, linux-media

	Walking rbtree while it's modified is a Bad Idea(tm); besides,
the result of find_vma() can be freed just as it's getting returned
to caller.  Fortunately, it's easy to fix - just take ->mmap_sem a bit
earlier (and don't bother with find_vma() at all if virtp >= PAGE_OFFSET -
in that case we don't even look at its result).

Cc: stable@vger.kernel.org [2.6.35]
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
index 9935040..984512f 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -207,19 +207,21 @@ static u32 omap_vout_uservirt_to_phys(u32 virtp)
 	struct vm_area_struct *vma;
 	struct mm_struct *mm = current->mm;
 
-	vma = find_vma(mm, virtp);
 	/* For kernel direct-mapped memory, take the easy way */
-	if (virtp >= PAGE_OFFSET) {
-		physp = virt_to_phys((void *) virtp);
+	if (virtp >= PAGE_OFFSET)
+		return virt_to_phys((void *) virtp);
+
+	down_read(&current->mm->mmap_sem);
+	vma = find_vma(mm, virtp);
 	} else if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
 		/* this will catch, kernel-allocated, mmaped-to-usermode
 		   addresses */
 		physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
+		up_read(&current->mm->mmap_sem);
 	} else {
 		/* otherwise, use get_user_pages() for general userland pages */
 		int res, nr_pages = 1;
 		struct page *pages;
-		down_read(&current->mm->mmap_sem);
 
 		res = get_user_pages(current, current->mm, virtp, nr_pages, 1,
 				0, &pages, NULL);

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

* Re: [PATCH] omap_vout: find_vma() needs ->mmap_sem held
  2012-12-15 20:12 [PATCH] omap_vout: find_vma() needs ->mmap_sem held Al Viro
@ 2012-12-15 20:38 ` Al Viro
  2013-01-06 13:02   ` Mauro Carvalho Chehab
  2012-12-16 20:01 ` Paul Bolle
  1 sibling, 1 reply; 8+ messages in thread
From: Al Viro @ 2012-12-15 20:38 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: linux-kernel, linux-media

On Sat, Dec 15, 2012 at 08:12:37PM +0000, Al Viro wrote:
> 	Walking rbtree while it's modified is a Bad Idea(tm); besides,
> the result of find_vma() can be freed just as it's getting returned
> to caller.  Fortunately, it's easy to fix - just take ->mmap_sem a bit
> earlier (and don't bother with find_vma() at all if virtp >= PAGE_OFFSET -
> in that case we don't even look at its result).

	While we are at it, what prevents VIDIOC_PREPARE_BUF calling
v4l_prepare_buf() -> (e.g) vb2_ioctl_prepare_buf() -> vb2_prepare_buf() ->
__buf_prepare() -> __qbuf_userptr() -> vb2_vmalloc_get_userptr() -> find_vma(),
AFAICS without having taken ->mmap_sem anywhere in process?  The code flow
is bloody convoluted and depends on a bunch of things done by initialization,
so I certainly might've missed something...

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

* Re: [PATCH] omap_vout: find_vma() needs ->mmap_sem held
  2012-12-15 20:12 [PATCH] omap_vout: find_vma() needs ->mmap_sem held Al Viro
  2012-12-15 20:38 ` Al Viro
@ 2012-12-16 20:01 ` Paul Bolle
  2012-12-16 20:04   ` Al Viro
  1 sibling, 1 reply; 8+ messages in thread
From: Paul Bolle @ 2012-12-16 20:01 UTC (permalink / raw)
  To: Al Viro; +Cc: Mauro Carvalho Chehab, linux-kernel, linux-media

On Sat, 2012-12-15 at 20:12 +0000, Al Viro wrote:
> 	Walking rbtree while it's modified is a Bad Idea(tm); besides,
> the result of find_vma() can be freed just as it's getting returned
> to caller.  Fortunately, it's easy to fix - just take ->mmap_sem a bit
> earlier (and don't bother with find_vma() at all if virtp >= PAGE_OFFSET -
> in that case we don't even look at its result).
> 
> Cc: stable@vger.kernel.org [2.6.35]
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
> ---
> diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
> index 9935040..984512f 100644
> --- a/drivers/media/platform/omap/omap_vout.c
> +++ b/drivers/media/platform/omap/omap_vout.c
> @@ -207,19 +207,21 @@ static u32 omap_vout_uservirt_to_phys(u32 virtp)
>  	struct vm_area_struct *vma;
>  	struct mm_struct *mm = current->mm;
>  
> -	vma = find_vma(mm, virtp);
>  	/* For kernel direct-mapped memory, take the easy way */
> -	if (virtp >= PAGE_OFFSET) {
> -		physp = virt_to_phys((void *) virtp);
> +	if (virtp >= PAGE_OFFSET)
> +		return virt_to_phys((void *) virtp);
> +
> +	down_read(&current->mm->mmap_sem);
> +	vma = find_vma(mm, virtp);
>  	} else if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {

Shouldn't that line become 
    if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {

so that this actually compiles?

>  		/* this will catch, kernel-allocated, mmaped-to-usermode
>  		   addresses */
>  		physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
> +		up_read(&current->mm->mmap_sem);
>  	} else {
>  		/* otherwise, use get_user_pages() for general userland pages */
>  		int res, nr_pages = 1;
>  		struct page *pages;
> -		down_read(&current->mm->mmap_sem);
>  
>  		res = get_user_pages(current, current->mm, virtp, nr_pages, 1,
>  				0, &pages, NULL);


Paul Bolle


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

* Re: [PATCH] omap_vout: find_vma() needs ->mmap_sem held
  2012-12-16 20:01 ` Paul Bolle
@ 2012-12-16 20:04   ` Al Viro
  2013-01-07 14:15     ` Laurent Pinchart
  0 siblings, 1 reply; 8+ messages in thread
From: Al Viro @ 2012-12-16 20:04 UTC (permalink / raw)
  To: Paul Bolle; +Cc: Mauro Carvalho Chehab, linux-kernel, linux-media

On Sun, Dec 16, 2012 at 09:01:10PM +0100, Paul Bolle wrote:
> > +	vma = find_vma(mm, virtp);
> >  	} else if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
> 
> Shouldn't that line become 
>     if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
> 
> so that this actually compiles?

*Do'h*

Yes, it should.  Mea culpa...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
index 9935040..cb564d0 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -207,19 +207,21 @@ static u32 omap_vout_uservirt_to_phys(u32 virtp)
 	struct vm_area_struct *vma;
 	struct mm_struct *mm = current->mm;
 
-	vma = find_vma(mm, virtp);
 	/* For kernel direct-mapped memory, take the easy way */
-	if (virtp >= PAGE_OFFSET) {
-		physp = virt_to_phys((void *) virtp);
-	} else if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
+	if (virtp >= PAGE_OFFSET)
+		return virt_to_phys((void *) virtp);
+
+	down_read(&current->mm->mmap_sem);
+	vma = find_vma(mm, virtp);
+	if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
 		/* this will catch, kernel-allocated, mmaped-to-usermode
 		   addresses */
 		physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
+		up_read(&current->mm->mmap_sem);
 	} else {
 		/* otherwise, use get_user_pages() for general userland pages */
 		int res, nr_pages = 1;
 		struct page *pages;
-		down_read(&current->mm->mmap_sem);
 
 		res = get_user_pages(current, current->mm, virtp, nr_pages, 1,
 				0, &pages, NULL);

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

* Re: [PATCH] omap_vout: find_vma() needs ->mmap_sem held
  2012-12-15 20:38 ` Al Viro
@ 2013-01-06 13:02   ` Mauro Carvalho Chehab
  2013-01-07 14:03     ` Laurent Pinchart
  2013-01-07 14:06     ` Laurent Pinchart
  0 siblings, 2 replies; 8+ messages in thread
From: Mauro Carvalho Chehab @ 2013-01-06 13:02 UTC (permalink / raw)
  To: Al Viro
  Cc: linux-kernel, linux-media, Laurent Pinchart, Archit Taneja,
	Prabhakar Lad, Sakari Ailus

Hi Viro,

Em Sat, 15 Dec 2012 20:38:29 +0000
Al Viro <viro@ZenIV.linux.org.uk> escreveu:

> On Sat, Dec 15, 2012 at 08:12:37PM +0000, Al Viro wrote:
> > 	Walking rbtree while it's modified is a Bad Idea(tm); besides,
> > the result of find_vma() can be freed just as it's getting returned
> > to caller.  Fortunately, it's easy to fix - just take ->mmap_sem a bit
> > earlier (and don't bother with find_vma() at all if virtp >= PAGE_OFFSET -
> > in that case we don't even look at its result).
> 
> 	While we are at it, what prevents VIDIOC_PREPARE_BUF calling
> v4l_prepare_buf() -> (e.g) vb2_ioctl_prepare_buf() -> vb2_prepare_buf() ->
> __buf_prepare() -> __qbuf_userptr() -> vb2_vmalloc_get_userptr() -> find_vma(),
> AFAICS without having taken ->mmap_sem anywhere in process?  The code flow
> is bloody convoluted and depends on a bunch of things done by initialization,
> so I certainly might've missed something...

This driver is currently missing an active maintainer, as it is for an old
hardware (AFAIK, omap is now at version 4, and this is for the first one),
but I'm c/c a few developers that might help to test and analyze it.

In any case, /me is assuming that your patch is right (as nobody complained),
and I'm applying it right now on my tree. This will hopefully allow some
people to test.

Cheers,
Mauro

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

* Re: [PATCH] omap_vout: find_vma() needs ->mmap_sem held
  2013-01-06 13:02   ` Mauro Carvalho Chehab
@ 2013-01-07 14:03     ` Laurent Pinchart
  2013-01-07 14:06     ` Laurent Pinchart
  1 sibling, 0 replies; 8+ messages in thread
From: Laurent Pinchart @ 2013-01-07 14:03 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Al Viro, linux-kernel, linux-media, Laurent Pinchart,
	Archit Taneja, Prabhakar Lad, Sakari Ailus

Hi Mauro,

On Sunday 06 January 2013 11:02:25 Mauro Carvalho Chehab wrote:
> Em Sat, 15 Dec 2012 20:38:29 +0000 Al Viro escreveu:
> > On Sat, Dec 15, 2012 at 08:12:37PM +0000, Al Viro wrote:
> > > 	Walking rbtree while it's modified is a Bad Idea(tm); besides,
> > > 
> > > the result of find_vma() can be freed just as it's getting returned
> > > to caller.  Fortunately, it's easy to fix - just take ->mmap_sem a bit
> > > earlier (and don't bother with find_vma() at all if virtp >= PAGE_OFFSET
> > > -
> > > in that case we don't even look at its result).
> > 	
> > 	While we are at it, what prevents VIDIOC_PREPARE_BUF calling
> > 
> > v4l_prepare_buf() -> (e.g) vb2_ioctl_prepare_buf() -> vb2_prepare_buf() ->
> > __buf_prepare() -> __qbuf_userptr() -> vb2_vmalloc_get_userptr() ->
> > find_vma(), AFAICS without having taken ->mmap_sem anywhere in process? 
> > The code flow is bloody convoluted and depends on a bunch of things done
> > by initialization, so I certainly might've missed something...
> 
> This driver is currently missing an active maintainer, as it is for an old
> hardware (AFAIK, omap is now at version 4, and this is for the first one),

The omap_vout driver is for OMAP2+ if I'm not mistaken. I use it with the 
OMAP3.

> but I'm c/c a few developers that might help to test and analyze it.
> 
> In any case, /me is assuming that your patch is right (as nobody
> complained), and I'm applying it right now on my tree. This will hopefully
> allow some people to test.

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH] omap_vout: find_vma() needs ->mmap_sem held
  2013-01-06 13:02   ` Mauro Carvalho Chehab
  2013-01-07 14:03     ` Laurent Pinchart
@ 2013-01-07 14:06     ` Laurent Pinchart
  1 sibling, 0 replies; 8+ messages in thread
From: Laurent Pinchart @ 2013-01-07 14:06 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Archit Taneja
  Cc: Al Viro, linux-kernel, linux-media, Prabhakar Lad, Sakari Ailus

Hi Mauro,

On Sunday 06 January 2013 11:02:25 Mauro Carvalho Chehab wrote:
> Em Sat, 15 Dec 2012 20:38:29 +0000 Al Viro escreveu:
> > On Sat, Dec 15, 2012 at 08:12:37PM +0000, Al Viro wrote:
> > > 	Walking rbtree while it's modified is a Bad Idea(tm); besides,
> > > 
> > > the result of find_vma() can be freed just as it's getting returned
> > > to caller.  Fortunately, it's easy to fix - just take ->mmap_sem a bit
> > > earlier (and don't bother with find_vma() at all if virtp >= PAGE_OFFSET
> > > -
> > > in that case we don't even look at its result).
> > 	
> > 	While we are at it, what prevents VIDIOC_PREPARE_BUF calling
> > 
> > v4l_prepare_buf() -> (e.g) vb2_ioctl_prepare_buf() -> vb2_prepare_buf() ->
> > __buf_prepare() -> __qbuf_userptr() -> vb2_vmalloc_get_userptr() ->
> > find_vma(), AFAICS without having taken ->mmap_sem anywhere in process? 
> > The code flow is bloody convoluted and depends on a bunch of things done
> > by initialization, so I certainly might've missed something...
> 
> This driver is currently missing an active maintainer, as it is for an old
> hardware (AFAIK, omap is now at version 4, and this is for the first one),
> but I'm c/c a few developers that might help to test and analyze it.
> 
> In any case, /me is assuming that your patch is right (as nobody
> complained), and I'm applying it right now on my tree. This will hopefully
> allow some people to test.

Please make sure you apply v2 (posted as "Re: [PATCH] omap_vout: find_vma() 
needs ->mmap_sem held").

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH] omap_vout: find_vma() needs ->mmap_sem held
  2012-12-16 20:04   ` Al Viro
@ 2013-01-07 14:15     ` Laurent Pinchart
  0 siblings, 0 replies; 8+ messages in thread
From: Laurent Pinchart @ 2013-01-07 14:15 UTC (permalink / raw)
  To: Al Viro; +Cc: Paul Bolle, Mauro Carvalho Chehab, linux-kernel, linux-media

On Sunday 16 December 2012 20:04:46 Al Viro wrote:
> On Sun, Dec 16, 2012 at 09:01:10PM +0100, Paul Bolle wrote:
> > > +	vma = find_vma(mm, virtp);
> > > 
> > >  	} else if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
> > 
> > Shouldn't that line become
> > 
> >     if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
> > 
> > so that this actually compiles?
> 
> *Do'h*
> 
> Yes, it should.  Mea culpa...
> 
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
> diff --git a/drivers/media/platform/omap/omap_vout.c
> b/drivers/media/platform/omap/omap_vout.c index 9935040..cb564d0 100644
> --- a/drivers/media/platform/omap/omap_vout.c
> +++ b/drivers/media/platform/omap/omap_vout.c
> @@ -207,19 +207,21 @@ static u32 omap_vout_uservirt_to_phys(u32 virtp)
>  	struct vm_area_struct *vma;
>  	struct mm_struct *mm = current->mm;
> 
> -	vma = find_vma(mm, virtp);
>  	/* For kernel direct-mapped memory, take the easy way */
> -	if (virtp >= PAGE_OFFSET) {
> -		physp = virt_to_phys((void *) virtp);
> -	} else if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
> +	if (virtp >= PAGE_OFFSET)
> +		return virt_to_phys((void *) virtp);
> +
> +	down_read(&current->mm->mmap_sem);
> +	vma = find_vma(mm, virtp);
> +	if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
>  		/* this will catch, kernel-allocated, mmaped-to-usermode
>  		   addresses */
>  		physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
> +		up_read(&current->mm->mmap_sem);
>  	} else {
>  		/* otherwise, use get_user_pages() for general userland pages */
>  		int res, nr_pages = 1;
>  		struct page *pages;
> -		down_read(&current->mm->mmap_sem);
> 
>  		res = get_user_pages(current, current->mm, virtp, nr_pages, 1,
>  				0, &pages, NULL);

-- 
Regards,

Laurent Pinchart


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

end of thread, other threads:[~2013-01-07 14:13 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-15 20:12 [PATCH] omap_vout: find_vma() needs ->mmap_sem held Al Viro
2012-12-15 20:38 ` Al Viro
2013-01-06 13:02   ` Mauro Carvalho Chehab
2013-01-07 14:03     ` Laurent Pinchart
2013-01-07 14:06     ` Laurent Pinchart
2012-12-16 20:01 ` Paul Bolle
2012-12-16 20:04   ` Al Viro
2013-01-07 14:15     ` Laurent Pinchart

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).