All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned
       [not found]   ` <20200428123914.GA27920@redhat.com>
@ 2020-05-04 16:47     ` Oleg Nesterov
  2020-05-04 18:40       ` Christian Borntraeger
                         ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Oleg Nesterov @ 2020-05-04 16:47 UTC (permalink / raw)
  To: Srikar Dronamraju, Guo Ren, Christian Borntraeger, David S. Miller
  Cc: Linus Torvalds, Steven Rostedt, Eric W. Biederman,
	Peter Zijlstra, Ingo Molnar, Jann Horn, Al Viro, Jens Axboe,
	Security Officers, Andrea Arcangeli, Ananth N Mavinakayanahalli,
	Naveen Rao, Andrew Morton, linux-kernel

uprobe_write_opcode() must not cross page boundary; prepare_uprobe()
relies on arch_uprobe_analyze_insn() which should validate "vaddr" but
some architectures (csky, s390, and sparc) don't do this.

We can remove the BUG_ON() check in prepare_uprobe() and validate the
offset early in __uprobe_register(). The new IS_ALIGNED() check matches
the alignment check in arch_prepare_kprobe() on supported architectures,
so I think that all insns must be aligned to UPROBE_SWBP_INSN_SIZE.

Another problem is __update_ref_ctr() which was wrong from the very
beginning, it can read/write outside of kmap'ed page unless "vaddr" is
aligned to sizeof(short), __uprobe_register() should check this too.

Cc: stable@vger.kernel.org
Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
 kernel/events/uprobes.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index ece7e13f6e4a..cc2095607c74 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -867,10 +867,6 @@ static int prepare_uprobe(struct uprobe *uprobe, struct file *file,
 	if (ret)
 		goto out;
 
-	/* uprobe_write_opcode() assumes we don't cross page boundary */
-	BUG_ON((uprobe->offset & ~PAGE_MASK) +
-			UPROBE_SWBP_INSN_SIZE > PAGE_SIZE);
-
 	smp_wmb(); /* pairs with the smp_rmb() in handle_swbp() */
 	set_bit(UPROBE_COPY_INSN, &uprobe->flags);
 
@@ -1166,6 +1162,15 @@ static int __uprobe_register(struct inode *inode, loff_t offset,
 	if (offset > i_size_read(inode))
 		return -EINVAL;
 
+	/*
+	 * This ensures that copy_from_page(), copy_to_page() and
+	 * __update_ref_ctr() can't cross page boundary.
+	 */
+	if (!IS_ALIGNED(offset, UPROBE_SWBP_INSN_SIZE))
+		return -EINVAL;
+	if (!IS_ALIGNED(ref_ctr_offset, sizeof(short)))
+		return -EINVAL;
+
  retry:
 	uprobe = alloc_uprobe(inode, offset, ref_ctr_offset);
 	if (!uprobe)
@@ -2014,6 +2019,9 @@ static int is_trap_at_addr(struct mm_struct *mm, unsigned long vaddr)
 	uprobe_opcode_t opcode;
 	int result;
 
+	if (WARN_ON_ONCE(!IS_ALIGNED(vaddr, UPROBE_SWBP_INSN_SIZE)))
+		return -EINVAL;
+
 	pagefault_disable();
 	result = __get_user(opcode, (uprobe_opcode_t __user *)vaddr);
 	pagefault_enable();
-- 
2.25.1.362.g51ebf55



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

* Re: [PATCH] uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned
  2020-05-04 16:47     ` [PATCH] uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned Oleg Nesterov
@ 2020-05-04 18:40       ` Christian Borntraeger
  2020-05-05  6:49         ` Sven Schnelle
  2020-06-10  2:53         ` Guo Ren
  2020-05-06  5:29       ` Srikar Dronamraju
                         ` (2 subsequent siblings)
  3 siblings, 2 replies; 11+ messages in thread
From: Christian Borntraeger @ 2020-05-04 18:40 UTC (permalink / raw)
  To: Oleg Nesterov, Srikar Dronamraju, Guo Ren, David S. Miller
  Cc: Linus Torvalds, Steven Rostedt, Eric W. Biederman,
	Peter Zijlstra, Ingo Molnar, Jann Horn, Al Viro, Jens Axboe,
	Security Officers, Andrea Arcangeli, Ananth N Mavinakayanahalli,
	Naveen Rao, Andrew Morton, linux-kernel, Vasily Gorbik,
	Sven Schnelle



On 04.05.20 18:47, Oleg Nesterov wrote:
> uprobe_write_opcode() must not cross page boundary; prepare_uprobe()
> relies on arch_uprobe_analyze_insn() which should validate "vaddr" but
> some architectures (csky, s390, and sparc) don't do this.

I think the idea was that the uprobe instruction is 2 bytes and instructions
are always aligned to 2 bytes on s390.  (we can have 2,4 or 6 bytes).

> 
> We can remove the BUG_ON() check in prepare_uprobe() and validate the
> offset early in __uprobe_register(). The new IS_ALIGNED() check matches
> the alignment check in arch_prepare_kprobe() on supported architectures,
> so I think that all insns must be aligned to UPROBE_SWBP_INSN_SIZE.

Not sure if it would have been possible to try to create a uprobe on an 
odd address. If yes, then the new IS_ALIGNED check certainly makes this
better for s390, so the patch looks sane. Adding Vasily and Sven to double
check.


> 
> Another problem is __update_ref_ctr() which was wrong from the very
> beginning, it can read/write outside of kmap'ed page unless "vaddr" is
> aligned to sizeof(short), __uprobe_register() should check this too.
> 
> Cc: stable@vger.kernel.org
> Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
> Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
> Signed-off-by: Oleg Nesterov <oleg@redhat.com>
> ---
>  kernel/events/uprobes.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
> index ece7e13f6e4a..cc2095607c74 100644
> --- a/kernel/events/uprobes.c
> +++ b/kernel/events/uprobes.c
> @@ -867,10 +867,6 @@ static int prepare_uprobe(struct uprobe *uprobe, struct file *file,
>  	if (ret)
>  		goto out;
>  
> -	/* uprobe_write_opcode() assumes we don't cross page boundary */
> -	BUG_ON((uprobe->offset & ~PAGE_MASK) +
> -			UPROBE_SWBP_INSN_SIZE > PAGE_SIZE);
> -
>  	smp_wmb(); /* pairs with the smp_rmb() in handle_swbp() */
>  	set_bit(UPROBE_COPY_INSN, &uprobe->flags);
>  
> @@ -1166,6 +1162,15 @@ static int __uprobe_register(struct inode *inode, loff_t offset,
>  	if (offset > i_size_read(inode))
>  		return -EINVAL;
>  
> +	/*
> +	 * This ensures that copy_from_page(), copy_to_page() and
> +	 * __update_ref_ctr() can't cross page boundary.
> +	 */
> +	if (!IS_ALIGNED(offset, UPROBE_SWBP_INSN_SIZE))
> +		return -EINVAL;
> +	if (!IS_ALIGNED(ref_ctr_offset, sizeof(short)))
> +		return -EINVAL;
> +
>   retry:
>  	uprobe = alloc_uprobe(inode, offset, ref_ctr_offset);
>  	if (!uprobe)
> @@ -2014,6 +2019,9 @@ static int is_trap_at_addr(struct mm_struct *mm, unsigned long vaddr)
>  	uprobe_opcode_t opcode;
>  	int result;
>  
> +	if (WARN_ON_ONCE(!IS_ALIGNED(vaddr, UPROBE_SWBP_INSN_SIZE)))
> +		return -EINVAL;
> +
>  	pagefault_disable();
>  	result = __get_user(opcode, (uprobe_opcode_t __user *)vaddr);
>  	pagefault_enable();
> 

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

* Re: [PATCH] uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned
  2020-05-04 18:40       ` Christian Borntraeger
@ 2020-05-05  6:49         ` Sven Schnelle
  2020-06-10  2:53         ` Guo Ren
  1 sibling, 0 replies; 11+ messages in thread
From: Sven Schnelle @ 2020-05-05  6:49 UTC (permalink / raw)
  To: Christian Borntraeger
  Cc: Oleg Nesterov, Srikar Dronamraju, Guo Ren, David S. Miller,
	Linus Torvalds, Steven Rostedt, Eric W. Biederman,
	Peter Zijlstra, Ingo Molnar, Jann Horn, Al Viro, Jens Axboe,
	Security Officers, Andrea Arcangeli, Ananth N Mavinakayanahalli,
	Naveen Rao, Andrew Morton, linux-kernel, Vasily Gorbik

Hi,

On Mon, May 04, 2020 at 08:40:44PM +0200, Christian Borntraeger wrote:
> 
> 
> On 04.05.20 18:47, Oleg Nesterov wrote:
> > uprobe_write_opcode() must not cross page boundary; prepare_uprobe()
> > relies on arch_uprobe_analyze_insn() which should validate "vaddr" but
> > some architectures (csky, s390, and sparc) don't do this.
> 
> I think the idea was that the uprobe instruction is 2 bytes and instructions
> are always aligned to 2 bytes on s390.  (we can have 2,4 or 6 bytes).
> 
> > 
> > We can remove the BUG_ON() check in prepare_uprobe() and validate the
> > offset early in __uprobe_register(). The new IS_ALIGNED() check matches
> > the alignment check in arch_prepare_kprobe() on supported architectures,
> > so I think that all insns must be aligned to UPROBE_SWBP_INSN_SIZE.
> 
> Not sure if it would have been possible to try to create a uprobe on an 
> odd address. If yes, then the new IS_ALIGNED check certainly makes this
> better for s390, so the patch looks sane. Adding Vasily and Sven to double
> check.

I did a quick test, and without this patch it is possible to place a uprobe
at an odd address. With the patch it fails with EINVAL, which is more
reasonable.

Regards
Sven

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

* Re: [PATCH] uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned
  2020-05-04 16:47     ` [PATCH] uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned Oleg Nesterov
  2020-05-04 18:40       ` Christian Borntraeger
@ 2020-05-06  5:29       ` Srikar Dronamraju
  2020-05-06 12:51         ` Steven Rostedt
  2020-06-09 15:30       ` Oleg Nesterov
  2020-06-10  2:54       ` Guo Ren
  3 siblings, 1 reply; 11+ messages in thread
From: Srikar Dronamraju @ 2020-05-06  5:29 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Guo Ren, Christian Borntraeger, David S. Miller, Linus Torvalds,
	Steven Rostedt, Eric W. Biederman, Peter Zijlstra, Ingo Molnar,
	Jann Horn, Al Viro, Jens Axboe, Security Officers,
	Andrea Arcangeli, Ananth N Mavinakayanahalli, Naveen Rao,
	Andrew Morton, linux-kernel

* Oleg Nesterov <oleg@redhat.com> [2020-05-04 18:47:25]:

> uprobe_write_opcode() must not cross page boundary; prepare_uprobe()
> relies on arch_uprobe_analyze_insn() which should validate "vaddr" but
> some architectures (csky, s390, and sparc) don't do this.
> 
> We can remove the BUG_ON() check in prepare_uprobe() and validate the
> offset early in __uprobe_register(). The new IS_ALIGNED() check matches
> the alignment check in arch_prepare_kprobe() on supported architectures,
> so I think that all insns must be aligned to UPROBE_SWBP_INSN_SIZE.
> 
> Another problem is __update_ref_ctr() which was wrong from the very
> beginning, it can read/write outside of kmap'ed page unless "vaddr" is
> aligned to sizeof(short), __uprobe_register() should check this too.
> 
> Cc: stable@vger.kernel.org
> Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
> Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
> Signed-off-by: Oleg Nesterov <oleg@redhat.com>

Thanks Oleg.

Looks good to me.

Reviewed-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
> ---


-- 
Thanks and Regards
Srikar Dronamraju

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

* Re: [PATCH] uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned
  2020-05-06  5:29       ` Srikar Dronamraju
@ 2020-05-06 12:51         ` Steven Rostedt
  2020-05-06 17:16           ` Oleg Nesterov
  0 siblings, 1 reply; 11+ messages in thread
From: Steven Rostedt @ 2020-05-06 12:51 UTC (permalink / raw)
  To: Srikar Dronamraju
  Cc: Oleg Nesterov, Guo Ren, Christian Borntraeger, David S. Miller,
	Linus Torvalds, Eric W. Biederman, Peter Zijlstra, Ingo Molnar,
	Jann Horn, Al Viro, Jens Axboe, Security Officers,
	Andrea Arcangeli, Ananth N Mavinakayanahalli, Naveen Rao,
	Andrew Morton, linux-kernel

On Wed, 6 May 2020 10:59:55 +0530
Srikar Dronamraju <srikar@linux.vnet.ibm.com> wrote:

> * Oleg Nesterov <oleg@redhat.com> [2020-05-04 18:47:25]:
> 
> > uprobe_write_opcode() must not cross page boundary; prepare_uprobe()
> > relies on arch_uprobe_analyze_insn() which should validate "vaddr" but
> > some architectures (csky, s390, and sparc) don't do this.
> > 
> > We can remove the BUG_ON() check in prepare_uprobe() and validate the
> > offset early in __uprobe_register(). The new IS_ALIGNED() check matches
> > the alignment check in arch_prepare_kprobe() on supported architectures,
> > so I think that all insns must be aligned to UPROBE_SWBP_INSN_SIZE.
> > 
> > Another problem is __update_ref_ctr() which was wrong from the very
> > beginning, it can read/write outside of kmap'ed page unless "vaddr" is
> > aligned to sizeof(short), __uprobe_register() should check this too.
> > 
> > Cc: stable@vger.kernel.org
> > Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
> > Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
> > Signed-off-by: Oleg Nesterov <oleg@redhat.com>  
> 
> Thanks Oleg.
> 
> Looks good to me.
> 
> Reviewed-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
> > ---  
> 

Thanks Oleg, Srikar and Sven.

As this is in the kernel/events/ directory, I'm guessing it should be taken
through the tip tree?

-- Steve

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

* Re: [PATCH] uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned
  2020-05-06 12:51         ` Steven Rostedt
@ 2020-05-06 17:16           ` Oleg Nesterov
  0 siblings, 0 replies; 11+ messages in thread
From: Oleg Nesterov @ 2020-05-06 17:16 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Srikar Dronamraju, Guo Ren, Christian Borntraeger,
	David S. Miller, Linus Torvalds, Eric W. Biederman,
	Peter Zijlstra, Ingo Molnar, Jann Horn, Al Viro, Jens Axboe,
	Security Officers, Andrea Arcangeli, Ananth N Mavinakayanahalli,
	Naveen Rao, Andrew Morton, linux-kernel

On 05/06, Steven Rostedt wrote:
>
> As this is in the kernel/events/ directory, I'm guessing it should be taken
> through the tip tree?

this would be great, thanks Steven.

Oleg.


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

* Re: [PATCH] uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned
  2020-05-04 16:47     ` [PATCH] uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned Oleg Nesterov
  2020-05-04 18:40       ` Christian Borntraeger
  2020-05-06  5:29       ` Srikar Dronamraju
@ 2020-06-09 15:30       ` Oleg Nesterov
  2020-06-09 16:48         ` Linus Torvalds
  2020-06-10  2:54       ` Guo Ren
  3 siblings, 1 reply; 11+ messages in thread
From: Oleg Nesterov @ 2020-06-09 15:30 UTC (permalink / raw)
  To: Linus Torvalds, Srikar Dronamraju, Guo Ren,
	Christian Borntraeger, David S. Miller
  Cc: Steven Rostedt, Eric W. Biederman, Peter Zijlstra, Ingo Molnar,
	Jann Horn, Al Viro, Jens Axboe, Security Officers,
	Andrea Arcangeli, Ananth N Mavinakayanahalli, Naveen Rao,
	Andrew Morton, linux-kernel

Looks like this patch was forgotten...

Should I resend it?

On 05/04, Oleg Nesterov wrote:
>
> uprobe_write_opcode() must not cross page boundary; prepare_uprobe()
> relies on arch_uprobe_analyze_insn() which should validate "vaddr" but
> some architectures (csky, s390, and sparc) don't do this.
> 
> We can remove the BUG_ON() check in prepare_uprobe() and validate the
> offset early in __uprobe_register(). The new IS_ALIGNED() check matches
> the alignment check in arch_prepare_kprobe() on supported architectures,
> so I think that all insns must be aligned to UPROBE_SWBP_INSN_SIZE.
> 
> Another problem is __update_ref_ctr() which was wrong from the very
> beginning, it can read/write outside of kmap'ed page unless "vaddr" is
> aligned to sizeof(short), __uprobe_register() should check this too.
> 
> Cc: stable@vger.kernel.org
> Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
> Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
> Signed-off-by: Oleg Nesterov <oleg@redhat.com>
> ---
>  kernel/events/uprobes.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
> index ece7e13f6e4a..cc2095607c74 100644
> --- a/kernel/events/uprobes.c
> +++ b/kernel/events/uprobes.c
> @@ -867,10 +867,6 @@ static int prepare_uprobe(struct uprobe *uprobe, struct file *file,
>  	if (ret)
>  		goto out;
>  
> -	/* uprobe_write_opcode() assumes we don't cross page boundary */
> -	BUG_ON((uprobe->offset & ~PAGE_MASK) +
> -			UPROBE_SWBP_INSN_SIZE > PAGE_SIZE);
> -
>  	smp_wmb(); /* pairs with the smp_rmb() in handle_swbp() */
>  	set_bit(UPROBE_COPY_INSN, &uprobe->flags);
>  
> @@ -1166,6 +1162,15 @@ static int __uprobe_register(struct inode *inode, loff_t offset,
>  	if (offset > i_size_read(inode))
>  		return -EINVAL;
>  
> +	/*
> +	 * This ensures that copy_from_page(), copy_to_page() and
> +	 * __update_ref_ctr() can't cross page boundary.
> +	 */
> +	if (!IS_ALIGNED(offset, UPROBE_SWBP_INSN_SIZE))
> +		return -EINVAL;
> +	if (!IS_ALIGNED(ref_ctr_offset, sizeof(short)))
> +		return -EINVAL;
> +
>   retry:
>  	uprobe = alloc_uprobe(inode, offset, ref_ctr_offset);
>  	if (!uprobe)
> @@ -2014,6 +2019,9 @@ static int is_trap_at_addr(struct mm_struct *mm, unsigned long vaddr)
>  	uprobe_opcode_t opcode;
>  	int result;
>  
> +	if (WARN_ON_ONCE(!IS_ALIGNED(vaddr, UPROBE_SWBP_INSN_SIZE)))
> +		return -EINVAL;
> +
>  	pagefault_disable();
>  	result = __get_user(opcode, (uprobe_opcode_t __user *)vaddr);
>  	pagefault_enable();
> -- 
> 2.25.1.362.g51ebf55
> 


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

* Re: [PATCH] uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned
  2020-06-09 15:30       ` Oleg Nesterov
@ 2020-06-09 16:48         ` Linus Torvalds
  2020-06-09 17:43           ` Steven Rostedt
  0 siblings, 1 reply; 11+ messages in thread
From: Linus Torvalds @ 2020-06-09 16:48 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Srikar Dronamraju, Guo Ren, Christian Borntraeger,
	David S. Miller, Steven Rostedt, Eric W. Biederman,
	Peter Zijlstra, Ingo Molnar, Jann Horn, Al Viro, Jens Axboe,
	Security Officers, Andrea Arcangeli, Ananth N Mavinakayanahalli,
	Naveen Rao, Andrew Morton, Linux Kernel Mailing List

On Tue, Jun 9, 2020 at 8:30 AM Oleg Nesterov <oleg@redhat.com> wrote:
>
> Looks like this patch was forgotten...
>
> Should I resend it?

I guess I'll just take it directly, since it was triggered by me
complaining anyway.

I had hoped it would go through the usual channels.

                Linus

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

* Re: [PATCH] uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned
  2020-06-09 16:48         ` Linus Torvalds
@ 2020-06-09 17:43           ` Steven Rostedt
  0 siblings, 0 replies; 11+ messages in thread
From: Steven Rostedt @ 2020-06-09 17:43 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Oleg Nesterov, Srikar Dronamraju, Guo Ren, Christian Borntraeger,
	David S. Miller, Eric W. Biederman, Peter Zijlstra, Ingo Molnar,
	Jann Horn, Al Viro, Jens Axboe, Security Officers,
	Andrea Arcangeli, Ananth N Mavinakayanahalli, Naveen Rao,
	Andrew Morton, Linux Kernel Mailing List

On Tue, 9 Jun 2020 09:48:45 -0700
Linus Torvalds <torvalds@linux-foundation.org> wrote:

> On Tue, Jun 9, 2020 at 8:30 AM Oleg Nesterov <oleg@redhat.com> wrote:
> >
> > Looks like this patch was forgotten...
> >
> > Should I resend it?  
> 
> I guess I'll just take it directly, since it was triggered by me
> complaining anyway.
> 
> I had hoped it would go through the usual channels.

Perhaps there was confusion about which tree it was suppose to go
through :-/

-- Steve


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

* Re: [PATCH] uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned
  2020-05-04 18:40       ` Christian Borntraeger
  2020-05-05  6:49         ` Sven Schnelle
@ 2020-06-10  2:53         ` Guo Ren
  1 sibling, 0 replies; 11+ messages in thread
From: Guo Ren @ 2020-06-10  2:53 UTC (permalink / raw)
  To: Christian Borntraeger
  Cc: Oleg Nesterov, Srikar Dronamraju, David S. Miller,
	Linus Torvalds, Steven Rostedt, Eric W. Biederman,
	Peter Zijlstra, Ingo Molnar, Jann Horn, Al Viro, Jens Axboe,
	Security Officers, Andrea Arcangeli, Ananth N Mavinakayanahalli,
	Naveen Rao, Andrew Morton, Linux Kernel Mailing List,
	Vasily Gorbik, Sven Schnelle

On Tue, May 5, 2020 at 2:41 AM Christian Borntraeger
<borntraeger@de.ibm.com> wrote:
>
>
>
> On 04.05.20 18:47, Oleg Nesterov wrote:
> > uprobe_write_opcode() must not cross page boundary; prepare_uprobe()
> > relies on arch_uprobe_analyze_insn() which should validate "vaddr" but
> > some architectures (csky, s390, and sparc) don't do this.
>
> I think the idea was that the uprobe instruction is 2 bytes and instructions
> are always aligned to 2 bytes on s390.  (we can have 2,4 or 6 bytes).
Agree, csky has two length-types of instructions (2,4 bytes).

>
> >
> > We can remove the BUG_ON() check in prepare_uprobe() and validate the
> > offset early in __uprobe_register(). The new IS_ALIGNED() check matches
> > the alignment check in arch_prepare_kprobe() on supported architectures,
> > so I think that all insns must be aligned to UPROBE_SWBP_INSN_SIZE.
>
> Not sure if it would have been possible to try to create a uprobe on an
> odd address. If yes, then the new IS_ALIGNED check certainly makes this
> better for s390, so the patch looks sane. Adding Vasily and Sven to double
> check.
Also good to csky.

-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/

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

* Re: [PATCH] uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned
  2020-05-04 16:47     ` [PATCH] uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned Oleg Nesterov
                         ` (2 preceding siblings ...)
  2020-06-09 15:30       ` Oleg Nesterov
@ 2020-06-10  2:54       ` Guo Ren
  3 siblings, 0 replies; 11+ messages in thread
From: Guo Ren @ 2020-06-10  2:54 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Srikar Dronamraju, Christian Borntraeger, David S. Miller,
	Linus Torvalds, Steven Rostedt, Eric W. Biederman,
	Peter Zijlstra, Ingo Molnar, Jann Horn, Al Viro, Jens Axboe,
	Security Officers, Andrea Arcangeli, Ananth N Mavinakayanahalli,
	Naveen Rao, Andrew Morton, Linux Kernel Mailing List

Hi Oleg,

On Tue, May 5, 2020 at 12:47 AM Oleg Nesterov <oleg@redhat.com> wrote:
>
> uprobe_write_opcode() must not cross page boundary; prepare_uprobe()
> relies on arch_uprobe_analyze_insn() which should validate "vaddr" but
> some architectures (csky, s390, and sparc) don't do this.
>
> We can remove the BUG_ON() check in prepare_uprobe() and validate the
> offset early in __uprobe_register(). The new IS_ALIGNED() check matches
> the alignment check in arch_prepare_kprobe() on supported architectures,
> so I think that all insns must be aligned to UPROBE_SWBP_INSN_SIZE.
>
> Another problem is __update_ref_ctr() which was wrong from the very
> beginning, it can read/write outside of kmap'ed page unless "vaddr" is
> aligned to sizeof(short), __uprobe_register() should check this too.
>
> Cc: stable@vger.kernel.org
> Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
> Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
> Signed-off-by: Oleg Nesterov <oleg@redhat.com>
> ---
>  kernel/events/uprobes.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
> index ece7e13f6e4a..cc2095607c74 100644
> --- a/kernel/events/uprobes.c
> +++ b/kernel/events/uprobes.c
> @@ -867,10 +867,6 @@ static int prepare_uprobe(struct uprobe *uprobe, struct file *file,
>         if (ret)
>                 goto out;
>
> -       /* uprobe_write_opcode() assumes we don't cross page boundary */
> -       BUG_ON((uprobe->offset & ~PAGE_MASK) +
> -                       UPROBE_SWBP_INSN_SIZE > PAGE_SIZE);
> -
>         smp_wmb(); /* pairs with the smp_rmb() in handle_swbp() */
>         set_bit(UPROBE_COPY_INSN, &uprobe->flags);
>
> @@ -1166,6 +1162,15 @@ static int __uprobe_register(struct inode *inode, loff_t offset,
>         if (offset > i_size_read(inode))
>                 return -EINVAL;
>
> +       /*
> +        * This ensures that copy_from_page(), copy_to_page() and
> +        * __update_ref_ctr() can't cross page boundary.
> +        */
> +       if (!IS_ALIGNED(offset, UPROBE_SWBP_INSN_SIZE))
> +               return -EINVAL;
> +       if (!IS_ALIGNED(ref_ctr_offset, sizeof(short)))
> +               return -EINVAL;
> +
>   retry:
>         uprobe = alloc_uprobe(inode, offset, ref_ctr_offset);
>         if (!uprobe)
> @@ -2014,6 +2019,9 @@ static int is_trap_at_addr(struct mm_struct *mm, unsigned long vaddr)
>         uprobe_opcode_t opcode;
>         int result;
>
> +       if (WARN_ON_ONCE(!IS_ALIGNED(vaddr, UPROBE_SWBP_INSN_SIZE)))
> +               return -EINVAL;
> +
>         pagefault_disable();
>         result = __get_user(opcode, (uprobe_opcode_t __user *)vaddr);
>         pagefault_enable();
> --
> 2.25.1.362.g51ebf55
>
>
Looks good to me, thx.

Reviewed-by: Guo Ren <guoren@kernel.org>

-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/

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

end of thread, other threads:[~2020-06-10  2:54 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CAHk-=whQt69ApMkZF8b2Q2idMDgPpPETZeeOuZg59CrOO4025w@mail.gmail.com>
     [not found] ` <20200428091149.GB19958@linux.vnet.ibm.com>
     [not found]   ` <20200428123914.GA27920@redhat.com>
2020-05-04 16:47     ` [PATCH] uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned Oleg Nesterov
2020-05-04 18:40       ` Christian Borntraeger
2020-05-05  6:49         ` Sven Schnelle
2020-06-10  2:53         ` Guo Ren
2020-05-06  5:29       ` Srikar Dronamraju
2020-05-06 12:51         ` Steven Rostedt
2020-05-06 17:16           ` Oleg Nesterov
2020-06-09 15:30       ` Oleg Nesterov
2020-06-09 16:48         ` Linus Torvalds
2020-06-09 17:43           ` Steven Rostedt
2020-06-10  2:54       ` Guo Ren

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.