Re: [PATCH] uprobes: mmap_region() corrupts mm->mm_rb if uprobe_mmap() fails

2012-08-03 Thread Srikar Dronamraju
* Oleg Nesterov  [2012-07-28 18:31:57]:

> https://bugzilla.redhat.com/show_bug.cgi?id=843640
> 
> If mmap_region()->uprobe_mmap() fails, unmap_and_free_vma path
> does unmap_region() but does not remove the soon-to-be-freed vma
> from rb tree (actually there are more problems).
> 
> Perhaps we could do do_munmap() + return in this case, but in fact
> it is simply wrong to abort if uprobe_mmap() fails. Until at least
> we move the !UPROBE_COPY_INSN code from install_breakpoint() to
> uprobe_register().
> 
> For example, uprobe_mmap()->install_breakpoint() can fail if the
> probed insn is not supported (remember, uprobe_register() succeeds
> if nobody mmaps inode/offset), mmap() should not fail in this case.
> 
> dup_mmap()->uprobe_mmap() is wrong too by the same reason, fork()
> can race with uprobe_register() and fail for no reason if it wins
> the race and does install_breakpoint() first.
> 
> Change mmap_region() and dup_mmap() to ignore the error code from
> uprobe_mmap().
> 
> Reported-by: William Cohen 
> Signed-off-by: Oleg Nesterov 
> Cc:  # v3.5

After discussions with Oleg, its very clear that this apt fix for now.

Acked-by: Srikar Dronamraju 

> ---
>  kernel/fork.c |4 ++--
>  mm/mmap.c |5 ++---
>  2 files changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/kernel/fork.c b/kernel/fork.c
> index ab5211b..54bb88a 100644
> --- a/kernel/fork.c
> +++ b/kernel/fork.c
> @@ -454,8 +454,8 @@ static int dup_mmap(struct mm_struct *mm, struct 
> mm_struct *oldmm)
>   if (retval)
>   goto out;
> 
> - if (file && uprobe_mmap(tmp))
> - goto out;
> + if (file)
> + uprobe_mmap(tmp);
>   }
>   /* a new mm has just been created */
>   arch_dup_mmap(oldmm, mm);
> diff --git a/mm/mmap.c b/mm/mmap.c
> index 4fe2697..f25fd3f 100644
> --- a/mm/mmap.c
> +++ b/mm/mmap.c
> @@ -1355,9 +1355,8 @@ out:
>   } else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK))
>   make_pages_present(addr, addr + len);
> 
> - if (file && uprobe_mmap(vma))
> - /* matching probes but cannot insert */
> - goto unmap_and_free_vma;
> + if (file)
> + uprobe_mmap(vma);
> 
>   return addr;
> 
> -- 
> 1.5.5.1
> 
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uprobes: mmap_region() corrupts mm-mm_rb if uprobe_mmap() fails

2012-08-03 Thread Srikar Dronamraju
* Oleg Nesterov o...@redhat.com [2012-07-28 18:31:57]:

 https://bugzilla.redhat.com/show_bug.cgi?id=843640
 
 If mmap_region()-uprobe_mmap() fails, unmap_and_free_vma path
 does unmap_region() but does not remove the soon-to-be-freed vma
 from rb tree (actually there are more problems).
 
 Perhaps we could do do_munmap() + return in this case, but in fact
 it is simply wrong to abort if uprobe_mmap() fails. Until at least
 we move the !UPROBE_COPY_INSN code from install_breakpoint() to
 uprobe_register().
 
 For example, uprobe_mmap()-install_breakpoint() can fail if the
 probed insn is not supported (remember, uprobe_register() succeeds
 if nobody mmaps inode/offset), mmap() should not fail in this case.
 
 dup_mmap()-uprobe_mmap() is wrong too by the same reason, fork()
 can race with uprobe_register() and fail for no reason if it wins
 the race and does install_breakpoint() first.
 
 Change mmap_region() and dup_mmap() to ignore the error code from
 uprobe_mmap().
 
 Reported-by: William Cohen wco...@redhat.com
 Signed-off-by: Oleg Nesterov o...@redhat.com
 Cc: sta...@vger.kernel.org # v3.5

After discussions with Oleg, its very clear that this apt fix for now.

Acked-by: Srikar Dronamraju sri...@linux.vnet.ibm.com

 ---
  kernel/fork.c |4 ++--
  mm/mmap.c |5 ++---
  2 files changed, 4 insertions(+), 5 deletions(-)
 
 diff --git a/kernel/fork.c b/kernel/fork.c
 index ab5211b..54bb88a 100644
 --- a/kernel/fork.c
 +++ b/kernel/fork.c
 @@ -454,8 +454,8 @@ static int dup_mmap(struct mm_struct *mm, struct 
 mm_struct *oldmm)
   if (retval)
   goto out;
 
 - if (file  uprobe_mmap(tmp))
 - goto out;
 + if (file)
 + uprobe_mmap(tmp);
   }
   /* a new mm has just been created */
   arch_dup_mmap(oldmm, mm);
 diff --git a/mm/mmap.c b/mm/mmap.c
 index 4fe2697..f25fd3f 100644
 --- a/mm/mmap.c
 +++ b/mm/mmap.c
 @@ -1355,9 +1355,8 @@ out:
   } else if ((flags  MAP_POPULATE)  !(flags  MAP_NONBLOCK))
   make_pages_present(addr, addr + len);
 
 - if (file  uprobe_mmap(vma))
 - /* matching probes but cannot insert */
 - goto unmap_and_free_vma;
 + if (file)
 + uprobe_mmap(vma);
 
   return addr;
 
 -- 
 1.5.5.1
 
 

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uprobes: mmap_region() corrupts mm->mm_rb if uprobe_mmap() fails

2012-07-31 Thread Oleg Nesterov
On 07/31, Oleg Nesterov wrote:
>
> OK, so what you suggest for now?
>
> Please note that it is very trivial to crash the kernel. Just
> do something like
>
>   echo "p /bin/true:OFFSET_OF_SYSCALL_INSN" > 
> /sys/kernel/debug/tracing/uprobe_events
>   /bin/true

Forgot to mention...

And even it it didn't crash, mmap() (and thus exec) should not fail.

Oleg.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uprobes: mmap_region() corrupts mm->mm_rb if uprobe_mmap() fails

2012-07-31 Thread Oleg Nesterov
On 07/31, Srikar Dronamraju wrote:
>
> > --- a/kernel/fork.c
> > +++ b/kernel/fork.c
> > @@ -454,8 +454,8 @@ static int dup_mmap(struct mm_struct *mm, struct 
> > mm_struct *oldmm)
> > if (retval)
> > goto out;
> >
> > -   if (file && uprobe_mmap(tmp))
> > -   goto out;
> > +   if (file)
> > +   uprobe_mmap(tmp);
>
> I am not comfortable with this fix.

OK, so what you suggest for now?

Please note that it is very trivial to crash the kernel. Just
do something like

echo "p /bin/true:OFFSET_OF_SYSCALL_INSN" > 
/sys/kernel/debug/tracing/uprobe_events
/bin/true

(or any other unsupported insn)

Yes sure, I agree that in the long term this change should be
reconsidered.

> I think the long term solution is as you mentioned, move the
> instruction analysis to register.

Exactly. And we already discusssed this, we have a lot of other
reasons to do this.

> Lets say there were 10 probes that were to be installed in that vma.
> we were able to install five probes and the 6th one happened to fail
> because of invalid instruction; we dont continue with the registering
> probes for the remaining 4 probes.

Yes. And I already have the patch. I didn't send it because, unlike
this fix, it depends on other changes (already in -tip).

Until we move analysis to register, until we teach the callers of
uprobe_mmap() to bailout (and please note that vma_adjust() ignores
the result too), uprobe_mmap() should not give up if install fails,
it should continue.

> The intention behind failing mmap()/fork() if uprobe_mmap failed,
> was to make sure that we always report the correct number of events.

Sure, I understand and agree.

But what we can do right now?

Oleg.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uprobes: mmap_region() corrupts mm->mm_rb if uprobe_mmap() fails

2012-07-31 Thread Srikar Dronamraju
> 
> If mmap_region()->uprobe_mmap() fails, unmap_and_free_vma path
> does unmap_region() but does not remove the soon-to-be-freed vma
> from rb tree (actually there are more problems).
> 
> Perhaps we could do do_munmap() + return in this case, but in fact
> it is simply wrong to abort if uprobe_mmap() fails. Until at least
> we move the !UPROBE_COPY_INSN code from install_breakpoint() to
> uprobe_register().
> 
> For example, uprobe_mmap()->install_breakpoint() can fail if the
> probed insn is not supported (remember, uprobe_register() succeeds
> if nobody mmaps inode/offset), mmap() should not fail in this case.
> 
> dup_mmap()->uprobe_mmap() is wrong too by the same reason, fork()
> can race with uprobe_register() and fail for no reason if it wins
> the race and does install_breakpoint() first.
> 
> Change mmap_region() and dup_mmap() to ignore the error code from
> uprobe_mmap().
> 
> Reported-by: William Cohen 
> Signed-off-by: Oleg Nesterov 
> Cc:  # v3.5
> ---
>  kernel/fork.c |4 ++--
>  mm/mmap.c |5 ++---
>  2 files changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/kernel/fork.c b/kernel/fork.c
> index ab5211b..54bb88a 100644
> --- a/kernel/fork.c
> +++ b/kernel/fork.c
> @@ -454,8 +454,8 @@ static int dup_mmap(struct mm_struct *mm, struct 
> mm_struct *oldmm)
>   if (retval)
>   goto out;
> 
> - if (file && uprobe_mmap(tmp))
> - goto out;
> + if (file)
> + uprobe_mmap(tmp);

I am not comfortable with this fix.

Lets say there were 10 probes that were to be installed in that vma.
we were able to install five probes and the 6th one happened to fail
because of invalid instruction; we dont continue with the registering
probes for the remaining 4 probes.

Your fix allows probe hits for 5 registered probes that can lead to
misleading analysis. For example if one of the first five probes was a
malloc and the probe at free() was one of the last probes which wasnt
registered, then a person doing an analysis based on probes can say
there was a memory leak.

The intention behind failing mmap()/fork() if uprobe_mmap failed,
was to make sure that we always report the correct number of events.

Infact this was something that Peter advocated very strongly
http://article.gmane.org/gmane.linux.kernel.mm/59956

I think the long term solution is as you mentioned, move the
instruction analysis to register.

Till then should we just ignore invalid instruction probes similar to 
existing probes. i.e we return -ESRCH or some such which is ignored in
uprobe_mmap(), but is taken care of in the uprobe_register path.

The above may not be an elegant solution but.. 

-- 
thanks and regards
Srikar

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uprobes: mmap_region() corrupts mm-mm_rb if uprobe_mmap() fails

2012-07-31 Thread Srikar Dronamraju
 
 If mmap_region()-uprobe_mmap() fails, unmap_and_free_vma path
 does unmap_region() but does not remove the soon-to-be-freed vma
 from rb tree (actually there are more problems).
 
 Perhaps we could do do_munmap() + return in this case, but in fact
 it is simply wrong to abort if uprobe_mmap() fails. Until at least
 we move the !UPROBE_COPY_INSN code from install_breakpoint() to
 uprobe_register().
 
 For example, uprobe_mmap()-install_breakpoint() can fail if the
 probed insn is not supported (remember, uprobe_register() succeeds
 if nobody mmaps inode/offset), mmap() should not fail in this case.
 
 dup_mmap()-uprobe_mmap() is wrong too by the same reason, fork()
 can race with uprobe_register() and fail for no reason if it wins
 the race and does install_breakpoint() first.
 
 Change mmap_region() and dup_mmap() to ignore the error code from
 uprobe_mmap().
 
 Reported-by: William Cohen wco...@redhat.com
 Signed-off-by: Oleg Nesterov o...@redhat.com
 Cc: sta...@vger.kernel.org # v3.5
 ---
  kernel/fork.c |4 ++--
  mm/mmap.c |5 ++---
  2 files changed, 4 insertions(+), 5 deletions(-)
 
 diff --git a/kernel/fork.c b/kernel/fork.c
 index ab5211b..54bb88a 100644
 --- a/kernel/fork.c
 +++ b/kernel/fork.c
 @@ -454,8 +454,8 @@ static int dup_mmap(struct mm_struct *mm, struct 
 mm_struct *oldmm)
   if (retval)
   goto out;
 
 - if (file  uprobe_mmap(tmp))
 - goto out;
 + if (file)
 + uprobe_mmap(tmp);

I am not comfortable with this fix.

Lets say there were 10 probes that were to be installed in that vma.
we were able to install five probes and the 6th one happened to fail
because of invalid instruction; we dont continue with the registering
probes for the remaining 4 probes.

Your fix allows probe hits for 5 registered probes that can lead to
misleading analysis. For example if one of the first five probes was a
malloc and the probe at free() was one of the last probes which wasnt
registered, then a person doing an analysis based on probes can say
there was a memory leak.

The intention behind failing mmap()/fork() if uprobe_mmap failed,
was to make sure that we always report the correct number of events.

Infact this was something that Peter advocated very strongly
http://article.gmane.org/gmane.linux.kernel.mm/59956

I think the long term solution is as you mentioned, move the
instruction analysis to register.

Till then should we just ignore invalid instruction probes similar to 
existing probes. i.e we return -ESRCH or some such which is ignored in
uprobe_mmap(), but is taken care of in the uprobe_register path.

The above may not be an elegant solution but.. 

-- 
thanks and regards
Srikar

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uprobes: mmap_region() corrupts mm-mm_rb if uprobe_mmap() fails

2012-07-31 Thread Oleg Nesterov
On 07/31, Srikar Dronamraju wrote:

  --- a/kernel/fork.c
  +++ b/kernel/fork.c
  @@ -454,8 +454,8 @@ static int dup_mmap(struct mm_struct *mm, struct 
  mm_struct *oldmm)
  if (retval)
  goto out;
 
  -   if (file  uprobe_mmap(tmp))
  -   goto out;
  +   if (file)
  +   uprobe_mmap(tmp);

 I am not comfortable with this fix.

OK, so what you suggest for now?

Please note that it is very trivial to crash the kernel. Just
do something like

echo p /bin/true:OFFSET_OF_SYSCALL_INSN  
/sys/kernel/debug/tracing/uprobe_events
/bin/true

(or any other unsupported insn)

Yes sure, I agree that in the long term this change should be
reconsidered.

 I think the long term solution is as you mentioned, move the
 instruction analysis to register.

Exactly. And we already discusssed this, we have a lot of other
reasons to do this.

 Lets say there were 10 probes that were to be installed in that vma.
 we were able to install five probes and the 6th one happened to fail
 because of invalid instruction; we dont continue with the registering
 probes for the remaining 4 probes.

Yes. And I already have the patch. I didn't send it because, unlike
this fix, it depends on other changes (already in -tip).

Until we move analysis to register, until we teach the callers of
uprobe_mmap() to bailout (and please note that vma_adjust() ignores
the result too), uprobe_mmap() should not give up if install fails,
it should continue.

 The intention behind failing mmap()/fork() if uprobe_mmap failed,
 was to make sure that we always report the correct number of events.

Sure, I understand and agree.

But what we can do right now?

Oleg.

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uprobes: mmap_region() corrupts mm-mm_rb if uprobe_mmap() fails

2012-07-31 Thread Oleg Nesterov
On 07/31, Oleg Nesterov wrote:

 OK, so what you suggest for now?

 Please note that it is very trivial to crash the kernel. Just
 do something like

   echo p /bin/true:OFFSET_OF_SYSCALL_INSN  
 /sys/kernel/debug/tracing/uprobe_events
   /bin/true

Forgot to mention...

And even it it didn't crash, mmap() (and thus exec) should not fail.

Oleg.

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uprobes: mmap_region() corrupts mm->mm_rb if uprobe_mmap() fails

2012-07-30 Thread William Cohen
On 07/28/2012 12:31 PM, Oleg Nesterov wrote:
> https://bugzilla.redhat.com/show_bug.cgi?id=843640

Hi Oleg,

I checked the following patch and it does fix the problem on the 3.5.0+ kernel.

-Will

> 
> If mmap_region()->uprobe_mmap() fails, unmap_and_free_vma path
> does unmap_region() but does not remove the soon-to-be-freed vma
> from rb tree (actually there are more problems).
> 
> Perhaps we could do do_munmap() + return in this case, but in fact
> it is simply wrong to abort if uprobe_mmap() fails. Until at least
> we move the !UPROBE_COPY_INSN code from install_breakpoint() to
> uprobe_register().
> 
> For example, uprobe_mmap()->install_breakpoint() can fail if the
> probed insn is not supported (remember, uprobe_register() succeeds
> if nobody mmaps inode/offset), mmap() should not fail in this case.
> 
> dup_mmap()->uprobe_mmap() is wrong too by the same reason, fork()
> can race with uprobe_register() and fail for no reason if it wins
> the race and does install_breakpoint() first.
> 
> Change mmap_region() and dup_mmap() to ignore the error code from
> uprobe_mmap().
> 
> Reported-by: William Cohen 
> Signed-off-by: Oleg Nesterov 
> Cc:  # v3.5
> ---
>  kernel/fork.c |4 ++--
>  mm/mmap.c |5 ++---
>  2 files changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/kernel/fork.c b/kernel/fork.c
> index ab5211b..54bb88a 100644
> --- a/kernel/fork.c
> +++ b/kernel/fork.c
> @@ -454,8 +454,8 @@ static int dup_mmap(struct mm_struct *mm, struct 
> mm_struct *oldmm)
>   if (retval)
>   goto out;
>  
> - if (file && uprobe_mmap(tmp))
> - goto out;
> + if (file)
> + uprobe_mmap(tmp);
>   }
>   /* a new mm has just been created */
>   arch_dup_mmap(oldmm, mm);
> diff --git a/mm/mmap.c b/mm/mmap.c
> index 4fe2697..f25fd3f 100644
> --- a/mm/mmap.c
> +++ b/mm/mmap.c
> @@ -1355,9 +1355,8 @@ out:
>   } else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK))
>   make_pages_present(addr, addr + len);
>  
> - if (file && uprobe_mmap(vma))
> - /* matching probes but cannot insert */
> - goto unmap_and_free_vma;
> + if (file)
> + uprobe_mmap(vma);
>  
>   return addr;
>  

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uprobes: mmap_region() corrupts mm-mm_rb if uprobe_mmap() fails

2012-07-30 Thread William Cohen
On 07/28/2012 12:31 PM, Oleg Nesterov wrote:
 https://bugzilla.redhat.com/show_bug.cgi?id=843640

Hi Oleg,

I checked the following patch and it does fix the problem on the 3.5.0+ kernel.

-Will

 
 If mmap_region()-uprobe_mmap() fails, unmap_and_free_vma path
 does unmap_region() but does not remove the soon-to-be-freed vma
 from rb tree (actually there are more problems).
 
 Perhaps we could do do_munmap() + return in this case, but in fact
 it is simply wrong to abort if uprobe_mmap() fails. Until at least
 we move the !UPROBE_COPY_INSN code from install_breakpoint() to
 uprobe_register().
 
 For example, uprobe_mmap()-install_breakpoint() can fail if the
 probed insn is not supported (remember, uprobe_register() succeeds
 if nobody mmaps inode/offset), mmap() should not fail in this case.
 
 dup_mmap()-uprobe_mmap() is wrong too by the same reason, fork()
 can race with uprobe_register() and fail for no reason if it wins
 the race and does install_breakpoint() first.
 
 Change mmap_region() and dup_mmap() to ignore the error code from
 uprobe_mmap().
 
 Reported-by: William Cohen wco...@redhat.com
 Signed-off-by: Oleg Nesterov o...@redhat.com
 Cc: sta...@vger.kernel.org # v3.5
 ---
  kernel/fork.c |4 ++--
  mm/mmap.c |5 ++---
  2 files changed, 4 insertions(+), 5 deletions(-)
 
 diff --git a/kernel/fork.c b/kernel/fork.c
 index ab5211b..54bb88a 100644
 --- a/kernel/fork.c
 +++ b/kernel/fork.c
 @@ -454,8 +454,8 @@ static int dup_mmap(struct mm_struct *mm, struct 
 mm_struct *oldmm)
   if (retval)
   goto out;
  
 - if (file  uprobe_mmap(tmp))
 - goto out;
 + if (file)
 + uprobe_mmap(tmp);
   }
   /* a new mm has just been created */
   arch_dup_mmap(oldmm, mm);
 diff --git a/mm/mmap.c b/mm/mmap.c
 index 4fe2697..f25fd3f 100644
 --- a/mm/mmap.c
 +++ b/mm/mmap.c
 @@ -1355,9 +1355,8 @@ out:
   } else if ((flags  MAP_POPULATE)  !(flags  MAP_NONBLOCK))
   make_pages_present(addr, addr + len);
  
 - if (file  uprobe_mmap(vma))
 - /* matching probes but cannot insert */
 - goto unmap_and_free_vma;
 + if (file)
 + uprobe_mmap(vma);
  
   return addr;
  

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uprobes: mmap_region() corrupts mm->mm_rb if uprobe_mmap() fails

2012-07-28 Thread Oleg Nesterov
On 07/28, Oleg Nesterov wrote:
>
> https://bugzilla.redhat.com/show_bug.cgi?id=843640
>
> If mmap_region()->uprobe_mmap() fails, unmap_and_free_vma path
> does unmap_region() but does not remove the soon-to-be-freed vma
> from rb tree (actually there are more problems).

Just in case...

Ingo, this is orthogonal to other pending changes I sent. I think
3.6 (and 3.5-stable) needs this fix.

Oleg.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] uprobes: mmap_region() corrupts mm->mm_rb if uprobe_mmap() fails

2012-07-28 Thread Oleg Nesterov
https://bugzilla.redhat.com/show_bug.cgi?id=843640

If mmap_region()->uprobe_mmap() fails, unmap_and_free_vma path
does unmap_region() but does not remove the soon-to-be-freed vma
from rb tree (actually there are more problems).

Perhaps we could do do_munmap() + return in this case, but in fact
it is simply wrong to abort if uprobe_mmap() fails. Until at least
we move the !UPROBE_COPY_INSN code from install_breakpoint() to
uprobe_register().

For example, uprobe_mmap()->install_breakpoint() can fail if the
probed insn is not supported (remember, uprobe_register() succeeds
if nobody mmaps inode/offset), mmap() should not fail in this case.

dup_mmap()->uprobe_mmap() is wrong too by the same reason, fork()
can race with uprobe_register() and fail for no reason if it wins
the race and does install_breakpoint() first.

Change mmap_region() and dup_mmap() to ignore the error code from
uprobe_mmap().

Reported-by: William Cohen 
Signed-off-by: Oleg Nesterov 
Cc:  # v3.5
---
 kernel/fork.c |4 ++--
 mm/mmap.c |5 ++---
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/kernel/fork.c b/kernel/fork.c
index ab5211b..54bb88a 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -454,8 +454,8 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct 
*oldmm)
if (retval)
goto out;
 
-   if (file && uprobe_mmap(tmp))
-   goto out;
+   if (file)
+   uprobe_mmap(tmp);
}
/* a new mm has just been created */
arch_dup_mmap(oldmm, mm);
diff --git a/mm/mmap.c b/mm/mmap.c
index 4fe2697..f25fd3f 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1355,9 +1355,8 @@ out:
} else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK))
make_pages_present(addr, addr + len);
 
-   if (file && uprobe_mmap(vma))
-   /* matching probes but cannot insert */
-   goto unmap_and_free_vma;
+   if (file)
+   uprobe_mmap(vma);
 
return addr;
 
-- 
1.5.5.1


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] uprobes: mmap_region() corrupts mm-mm_rb if uprobe_mmap() fails

2012-07-28 Thread Oleg Nesterov
https://bugzilla.redhat.com/show_bug.cgi?id=843640

If mmap_region()-uprobe_mmap() fails, unmap_and_free_vma path
does unmap_region() but does not remove the soon-to-be-freed vma
from rb tree (actually there are more problems).

Perhaps we could do do_munmap() + return in this case, but in fact
it is simply wrong to abort if uprobe_mmap() fails. Until at least
we move the !UPROBE_COPY_INSN code from install_breakpoint() to
uprobe_register().

For example, uprobe_mmap()-install_breakpoint() can fail if the
probed insn is not supported (remember, uprobe_register() succeeds
if nobody mmaps inode/offset), mmap() should not fail in this case.

dup_mmap()-uprobe_mmap() is wrong too by the same reason, fork()
can race with uprobe_register() and fail for no reason if it wins
the race and does install_breakpoint() first.

Change mmap_region() and dup_mmap() to ignore the error code from
uprobe_mmap().

Reported-by: William Cohen wco...@redhat.com
Signed-off-by: Oleg Nesterov o...@redhat.com
Cc: sta...@vger.kernel.org # v3.5
---
 kernel/fork.c |4 ++--
 mm/mmap.c |5 ++---
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/kernel/fork.c b/kernel/fork.c
index ab5211b..54bb88a 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -454,8 +454,8 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct 
*oldmm)
if (retval)
goto out;
 
-   if (file  uprobe_mmap(tmp))
-   goto out;
+   if (file)
+   uprobe_mmap(tmp);
}
/* a new mm has just been created */
arch_dup_mmap(oldmm, mm);
diff --git a/mm/mmap.c b/mm/mmap.c
index 4fe2697..f25fd3f 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1355,9 +1355,8 @@ out:
} else if ((flags  MAP_POPULATE)  !(flags  MAP_NONBLOCK))
make_pages_present(addr, addr + len);
 
-   if (file  uprobe_mmap(vma))
-   /* matching probes but cannot insert */
-   goto unmap_and_free_vma;
+   if (file)
+   uprobe_mmap(vma);
 
return addr;
 
-- 
1.5.5.1


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uprobes: mmap_region() corrupts mm-mm_rb if uprobe_mmap() fails

2012-07-28 Thread Oleg Nesterov
On 07/28, Oleg Nesterov wrote:

 https://bugzilla.redhat.com/show_bug.cgi?id=843640

 If mmap_region()-uprobe_mmap() fails, unmap_and_free_vma path
 does unmap_region() but does not remove the soon-to-be-freed vma
 from rb tree (actually there are more problems).

Just in case...

Ingo, this is orthogonal to other pending changes I sent. I think
3.6 (and 3.5-stable) needs this fix.

Oleg.

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/