All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] powerpc: Don't print kernel instructions in show_user_instructions()
@ 2018-10-05 13:21 Michael Ellerman
  2018-10-05 13:52 ` Christophe LEROY
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Michael Ellerman @ 2018-10-05 13:21 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: muriloo, jannh

Recently we implemented show_user_instructions() which dumps the code
around the NIP when a user space process dies with an unhandled
signal. This was modelled on the x86 code, and we even went so far as
to implement the exact same bug, namely that if the user process
crashed with its NIP pointing into the kernel we will dump kernel text
to dmesg. eg:

  bad-bctr[2996]: segfault (11) at c000000000010000 nip c000000000010000 lr 12d0b0894 code 1
  bad-bctr[2996]: code: fbe10068 7cbe2b78 7c7f1b78 fb610048 38a10028 38810020 fb810050 7f8802a6
  bad-bctr[2996]: code: 3860001c f8010080 48242371 60000000 <7c7b1b79> 4082002c e8010080 eb610048

This was discovered on x86 by Jann Horn and fixed in commit
342db04ae712 ("x86/dumpstack: Don't dump kernel memory based on usermode RIP").

Fix it by checking the adjusted NIP value (pc) and number of
instructions against USER_DS, and bail if we fail the check, eg:

  bad-bctr[2969]: segfault (11) at c000000000010000 nip c000000000010000 lr 107930894 code 1
  bad-bctr[2969]: Bad NIP, not dumping instructions.

Fixes: 88b0fe175735 ("powerpc: Add show_user_instructions()")
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/kernel/process.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 913c5725cdb2..bb6ac471a784 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1306,6 +1306,16 @@ void show_user_instructions(struct pt_regs *regs)
 
 	pc = regs->nip - (instructions_to_print * 3 / 4 * sizeof(int));
 
+	/*
+	 * Make sure the NIP points at userspace, not kernel text/data or
+	 * elsewhere.
+	 */
+	if (!__access_ok(pc, instructions_to_print * sizeof(int), USER_DS)) {
+		pr_info("%s[%d]: Bad NIP, not dumping instructions.\n",
+			current->comm, current->pid);
+		return;
+	}
+
 	pr_info("%s[%d]: code: ", current->comm, current->pid);
 
 	for (i = 0; i < instructions_to_print; i++) {
-- 
2.17.1


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

* Re: [PATCH] powerpc: Don't print kernel instructions in show_user_instructions()
  2018-10-05 13:21 [PATCH] powerpc: Don't print kernel instructions in show_user_instructions() Michael Ellerman
@ 2018-10-05 13:52 ` Christophe LEROY
  2018-10-08  8:12   ` Michael Ellerman
  2018-10-05 14:02 ` Jann Horn
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Christophe LEROY @ 2018-10-05 13:52 UTC (permalink / raw)
  To: Michael Ellerman, linuxppc-dev; +Cc: jannh, muriloo



Le 05/10/2018 à 15:21, Michael Ellerman a écrit :
> Recently we implemented show_user_instructions() which dumps the code
> around the NIP when a user space process dies with an unhandled
> signal. This was modelled on the x86 code, and we even went so far as
> to implement the exact same bug, namely that if the user process
> crashed with its NIP pointing into the kernel we will dump kernel text
> to dmesg. eg:
> 
>    bad-bctr[2996]: segfault (11) at c000000000010000 nip c000000000010000 lr 12d0b0894 code 1
>    bad-bctr[2996]: code: fbe10068 7cbe2b78 7c7f1b78 fb610048 38a10028 38810020 fb810050 7f8802a6
>    bad-bctr[2996]: code: 3860001c f8010080 48242371 60000000 <7c7b1b79> 4082002c e8010080 eb610048
> 
> This was discovered on x86 by Jann Horn and fixed in commit
> 342db04ae712 ("x86/dumpstack: Don't dump kernel memory based on usermode RIP").
> 
> Fix it by checking the adjusted NIP value (pc) and number of
> instructions against USER_DS, and bail if we fail the check, eg:
> 
>    bad-bctr[2969]: segfault (11) at c000000000010000 nip c000000000010000 lr 107930894 code 1
>    bad-bctr[2969]: Bad NIP, not dumping instructions.
> 
> Fixes: 88b0fe175735 ("powerpc: Add show_user_instructions()")
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> ---
>   arch/powerpc/kernel/process.c | 10 ++++++++++
>   1 file changed, 10 insertions(+)
> 
> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
> index 913c5725cdb2..bb6ac471a784 100644
> --- a/arch/powerpc/kernel/process.c
> +++ b/arch/powerpc/kernel/process.c
> @@ -1306,6 +1306,16 @@ void show_user_instructions(struct pt_regs *regs)
>   
>   	pc = regs->nip - (instructions_to_print * 3 / 4 * sizeof(int));
>   
> +	/*
> +	 * Make sure the NIP points at userspace, not kernel text/data or
> +	 * elsewhere.
> +	 */
> +	if (!__access_ok(pc, instructions_to_print * sizeof(int), USER_DS)) {
> +		pr_info("%s[%d]: Bad NIP, not dumping instructions.\n",
> +			current->comm, current->pid);
> +		return;
> +	}
> +

This will conflict with my serie 
https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=64611 
which changes instructions_to_print to a constant. Will you merge it or 
do you expect me to rebase my serie ?

Reviewed-by: Christophe Leroy <christophe.leroy@c-s.fr>

Christophe

>   	pr_info("%s[%d]: code: ", current->comm, current->pid);
>   
>   	for (i = 0; i < instructions_to_print; i++) {
> 

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

* Re: [PATCH] powerpc: Don't print kernel instructions in show_user_instructions()
  2018-10-05 13:21 [PATCH] powerpc: Don't print kernel instructions in show_user_instructions() Michael Ellerman
  2018-10-05 13:52 ` Christophe LEROY
@ 2018-10-05 14:02 ` Jann Horn
  2018-10-08  8:23   ` Michael Ellerman
  2018-10-05 17:29 ` Murilo Opsfelder Araujo
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Jann Horn @ 2018-10-05 14:02 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, muriloo

On Fri, Oct 5, 2018 at 3:21 PM Michael Ellerman <mpe@ellerman.id.au> wrote:
> Recently we implemented show_user_instructions() which dumps the code
> around the NIP when a user space process dies with an unhandled
> signal. This was modelled on the x86 code, and we even went so far as
> to implement the exact same bug, namely that if the user process
> crashed with its NIP pointing into the kernel we will dump kernel text
> to dmesg. eg:
>
>   bad-bctr[2996]: segfault (11) at c000000000010000 nip c000000000010000 lr 12d0b0894 code 1
>   bad-bctr[2996]: code: fbe10068 7cbe2b78 7c7f1b78 fb610048 38a10028 38810020 fb810050 7f8802a6
>   bad-bctr[2996]: code: 3860001c f8010080 48242371 60000000 <7c7b1b79> 4082002c e8010080 eb610048
>
> This was discovered on x86 by Jann Horn and fixed in commit
> 342db04ae712 ("x86/dumpstack: Don't dump kernel memory based on usermode RIP").
>
> Fix it by checking the adjusted NIP value (pc) and number of
> instructions against USER_DS, and bail if we fail the check, eg:

This fix looks good to me.

In the long term, I think it is somewhat awkward to use
probe_kernel_address(), which uses set_fs(KERNEL_DS), when you
actually just want to access userspace memory. It might make sense to
provide a better helper for explicitly accessing memory with USER_DS.

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

* Re: [PATCH] powerpc: Don't print kernel instructions in show_user_instructions()
  2018-10-05 13:21 [PATCH] powerpc: Don't print kernel instructions in show_user_instructions() Michael Ellerman
  2018-10-05 13:52 ` Christophe LEROY
  2018-10-05 14:02 ` Jann Horn
@ 2018-10-05 17:29 ` Murilo Opsfelder Araujo
  2018-10-06 12:14 ` Michael Ellerman
  2018-10-18  9:28 ` [PATCH] " Christophe LEROY
  4 siblings, 0 replies; 13+ messages in thread
From: Murilo Opsfelder Araujo @ 2018-10-05 17:29 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, jannh

On Fri, Oct 05, 2018 at 11:21:23PM +1000, Michael Ellerman wrote:
> Recently we implemented show_user_instructions() which dumps the code
> around the NIP when a user space process dies with an unhandled
> signal. This was modelled on the x86 code, and we even went so far as
> to implement the exact same bug, namely that if the user process
> crashed with its NIP pointing into the kernel we will dump kernel text
> to dmesg. eg:
>
>   bad-bctr[2996]: segfault (11) at c000000000010000 nip c000000000010000 lr 12d0b0894 code 1
>   bad-bctr[2996]: code: fbe10068 7cbe2b78 7c7f1b78 fb610048 38a10028 38810020 fb810050 7f8802a6
>   bad-bctr[2996]: code: 3860001c f8010080 48242371 60000000 <7c7b1b79> 4082002c e8010080 eb610048
>
> This was discovered on x86 by Jann Horn and fixed in commit
> 342db04ae712 ("x86/dumpstack: Don't dump kernel memory based on usermode RIP").
>
> Fix it by checking the adjusted NIP value (pc) and number of
> instructions against USER_DS, and bail if we fail the check, eg:
>
>   bad-bctr[2969]: segfault (11) at c000000000010000 nip c000000000010000 lr 107930894 code 1
>   bad-bctr[2969]: Bad NIP, not dumping instructions.
>
> Fixes: 88b0fe175735 ("powerpc: Add show_user_instructions()")
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>

Reviewed-by: Murilo Opsfelder Araujo <muriloo@linux.ibm.com>

Thank you all!

> ---
>  arch/powerpc/kernel/process.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
>
> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
> index 913c5725cdb2..bb6ac471a784 100644
> --- a/arch/powerpc/kernel/process.c
> +++ b/arch/powerpc/kernel/process.c
> @@ -1306,6 +1306,16 @@ void show_user_instructions(struct pt_regs *regs)
>
>  	pc = regs->nip - (instructions_to_print * 3 / 4 * sizeof(int));
>
> +	/*
> +	 * Make sure the NIP points at userspace, not kernel text/data or
> +	 * elsewhere.
> +	 */
> +	if (!__access_ok(pc, instructions_to_print * sizeof(int), USER_DS)) {
> +		pr_info("%s[%d]: Bad NIP, not dumping instructions.\n",
> +			current->comm, current->pid);
> +		return;
> +	}
> +
>  	pr_info("%s[%d]: code: ", current->comm, current->pid);
>
>  	for (i = 0; i < instructions_to_print; i++) {
> --
> 2.17.1
>

--
Murilo


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

* Re: powerpc: Don't print kernel instructions in show_user_instructions()
  2018-10-05 13:21 [PATCH] powerpc: Don't print kernel instructions in show_user_instructions() Michael Ellerman
                   ` (2 preceding siblings ...)
  2018-10-05 17:29 ` Murilo Opsfelder Araujo
@ 2018-10-06 12:14 ` Michael Ellerman
  2018-10-18  9:28 ` [PATCH] " Christophe LEROY
  4 siblings, 0 replies; 13+ messages in thread
From: Michael Ellerman @ 2018-10-06 12:14 UTC (permalink / raw)
  To: Michael Ellerman, linuxppc-dev; +Cc: jannh, muriloo

On Fri, 2018-10-05 at 13:21:23 UTC, Michael Ellerman wrote:
> Recently we implemented show_user_instructions() which dumps the code
> around the NIP when a user space process dies with an unhandled
> signal. This was modelled on the x86 code, and we even went so far as
> to implement the exact same bug, namely that if the user process
> crashed with its NIP pointing into the kernel we will dump kernel text
> to dmesg. eg:
> 
>   bad-bctr[2996]: segfault (11) at c000000000010000 nip c000000000010000 lr 12d0b0894 code 1
>   bad-bctr[2996]: code: fbe10068 7cbe2b78 7c7f1b78 fb610048 38a10028 38810020 fb810050 7f8802a6
>   bad-bctr[2996]: code: 3860001c f8010080 48242371 60000000 <7c7b1b79> 4082002c e8010080 eb610048
> 
> This was discovered on x86 by Jann Horn and fixed in commit
> 342db04ae712 ("x86/dumpstack: Don't dump kernel memory based on usermode RIP").
> 
> Fix it by checking the adjusted NIP value (pc) and number of
> instructions against USER_DS, and bail if we fail the check, eg:
> 
>   bad-bctr[2969]: segfault (11) at c000000000010000 nip c000000000010000 lr 107930894 code 1
>   bad-bctr[2969]: Bad NIP, not dumping instructions.
> 
> Fixes: 88b0fe175735 ("powerpc: Add show_user_instructions()")
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> Reviewed-by: Christophe Leroy <christophe.leroy@c-s.fr>
> Reviewed-by: Murilo Opsfelder Araujo <muriloo@linux.ibm.com>

Applied to powerpc fixes.

https://git.kernel.org/powerpc/c/a932ed3b718147c6537da290b7a91e

cheers

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

* Re: [PATCH] powerpc: Don't print kernel instructions in show_user_instructions()
  2018-10-05 13:52 ` Christophe LEROY
@ 2018-10-08  8:12   ` Michael Ellerman
  0 siblings, 0 replies; 13+ messages in thread
From: Michael Ellerman @ 2018-10-08  8:12 UTC (permalink / raw)
  To: Christophe LEROY, linuxppc-dev; +Cc: jannh, muriloo

Christophe LEROY <christophe.leroy@c-s.fr> writes:
> Le 05/10/2018 à 15:21, Michael Ellerman a écrit :
>> Recently we implemented show_user_instructions() which dumps the code
...
>> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
>> index 913c5725cdb2..bb6ac471a784 100644
>> --- a/arch/powerpc/kernel/process.c
>> +++ b/arch/powerpc/kernel/process.c
>> @@ -1306,6 +1306,16 @@ void show_user_instructions(struct pt_regs *regs)
>>   
>>   	pc = regs->nip - (instructions_to_print * 3 / 4 * sizeof(int));
>>   
>> +	/*
>> +	 * Make sure the NIP points at userspace, not kernel text/data or
>> +	 * elsewhere.
>> +	 */
>> +	if (!__access_ok(pc, instructions_to_print * sizeof(int), USER_DS)) {
>> +		pr_info("%s[%d]: Bad NIP, not dumping instructions.\n",
>> +			current->comm, current->pid);
>> +		return;
>> +	}
>> +
>
> This will conflict with my serie 
> https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=64611 
> which changes instructions_to_print to a constant. Will you merge it or 
> do you expect me to rebase my serie ?

I can fix it up.

But I see you've already rebased it and resent, you're too quick for me :)

cheers

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

* Re: [PATCH] powerpc: Don't print kernel instructions in show_user_instructions()
  2018-10-05 14:02 ` Jann Horn
@ 2018-10-08  8:23   ` Michael Ellerman
  0 siblings, 0 replies; 13+ messages in thread
From: Michael Ellerman @ 2018-10-08  8:23 UTC (permalink / raw)
  To: Jann Horn; +Cc: linuxppc-dev, muriloo

Jann Horn <jannh@google.com> writes:
> On Fri, Oct 5, 2018 at 3:21 PM Michael Ellerman <mpe@ellerman.id.au> wrote:
>> Recently we implemented show_user_instructions() which dumps the code
>> around the NIP when a user space process dies with an unhandled
>> signal. This was modelled on the x86 code, and we even went so far as
>> to implement the exact same bug, namely that if the user process
>> crashed with its NIP pointing into the kernel we will dump kernel text
>> to dmesg. eg:
>>
>>   bad-bctr[2996]: segfault (11) at c000000000010000 nip c000000000010000 lr 12d0b0894 code 1
>>   bad-bctr[2996]: code: fbe10068 7cbe2b78 7c7f1b78 fb610048 38a10028 38810020 fb810050 7f8802a6
>>   bad-bctr[2996]: code: 3860001c f8010080 48242371 60000000 <7c7b1b79> 4082002c e8010080 eb610048
>>
>> This was discovered on x86 by Jann Horn and fixed in commit
>> 342db04ae712 ("x86/dumpstack: Don't dump kernel memory based on usermode RIP").
>>
>> Fix it by checking the adjusted NIP value (pc) and number of
>> instructions against USER_DS, and bail if we fail the check, eg:
>
> This fix looks good to me.

Thanks.

> In the long term, I think it is somewhat awkward to use
> probe_kernel_address(), which uses set_fs(KERNEL_DS), when you
> actually just want to access userspace memory. It might make sense to
> provide a better helper for explicitly accessing memory with USER_DS.

Yes I agree, it's a bit messy. A probe_user_read() that sets USER_DS and
does the access_ok() check would be less error prone I think.

cheers

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

* Re: [PATCH] powerpc: Don't print kernel instructions in show_user_instructions()
  2018-10-05 13:21 [PATCH] powerpc: Don't print kernel instructions in show_user_instructions() Michael Ellerman
                   ` (3 preceding siblings ...)
  2018-10-06 12:14 ` Michael Ellerman
@ 2018-10-18  9:28 ` Christophe LEROY
  2018-10-18 11:12   ` Jann Horn
  2018-10-18 13:16   ` Michael Ellerman
  4 siblings, 2 replies; 13+ messages in thread
From: Christophe LEROY @ 2018-10-18  9:28 UTC (permalink / raw)
  To: Michael Ellerman, linuxppc-dev; +Cc: jannh, muriloo



Le 05/10/2018 à 15:21, Michael Ellerman a écrit :
> Recently we implemented show_user_instructions() which dumps the code
> around the NIP when a user space process dies with an unhandled
> signal. This was modelled on the x86 code, and we even went so far as
> to implement the exact same bug, namely that if the user process
> crashed with its NIP pointing into the kernel we will dump kernel text
> to dmesg. eg:
> 
>    bad-bctr[2996]: segfault (11) at c000000000010000 nip c000000000010000 lr 12d0b0894 code 1
>    bad-bctr[2996]: code: fbe10068 7cbe2b78 7c7f1b78 fb610048 38a10028 38810020 fb810050 7f8802a6
>    bad-bctr[2996]: code: 3860001c f8010080 48242371 60000000 <7c7b1b79> 4082002c e8010080 eb610048
> 
> This was discovered on x86 by Jann Horn and fixed in commit
> 342db04ae712 ("x86/dumpstack: Don't dump kernel memory based on usermode RIP").
> 
> Fix it by checking the adjusted NIP value (pc) and number of
> instructions against USER_DS, and bail if we fail the check, eg:
> 
>    bad-bctr[2969]: segfault (11) at c000000000010000 nip c000000000010000 lr 107930894 code 1
>    bad-bctr[2969]: Bad NIP, not dumping instructions.
> 
> Fixes: 88b0fe175735 ("powerpc: Add show_user_instructions()")
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> ---
>   arch/powerpc/kernel/process.c | 10 ++++++++++
>   1 file changed, 10 insertions(+)
> 
> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
> index 913c5725cdb2..bb6ac471a784 100644
> --- a/arch/powerpc/kernel/process.c
> +++ b/arch/powerpc/kernel/process.c
> @@ -1306,6 +1306,16 @@ void show_user_instructions(struct pt_regs *regs)
>   
>   	pc = regs->nip - (instructions_to_print * 3 / 4 * sizeof(int));
>   
> +	/*
> +	 * Make sure the NIP points at userspace, not kernel text/data or
> +	 * elsewhere.
> +	 */
> +	if (!__access_ok(pc, instructions_to_print * sizeof(int), USER_DS)) {
> +		pr_info("%s[%d]: Bad NIP, not dumping instructions.\n",
> +			current->comm, current->pid);
> +		return;
> +	}
> +

Is there any reason for not using access_ok() here ?

Christophe

>   	pr_info("%s[%d]: code: ", current->comm, current->pid);
>   
>   	for (i = 0; i < instructions_to_print; i++) {
> 

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

* Re: [PATCH] powerpc: Don't print kernel instructions in show_user_instructions()
  2018-10-18  9:28 ` [PATCH] " Christophe LEROY
@ 2018-10-18 11:12   ` Jann Horn
  2018-10-18 11:18     ` Christophe LEROY
  2018-10-18 13:16   ` Michael Ellerman
  1 sibling, 1 reply; 13+ messages in thread
From: Jann Horn @ 2018-10-18 11:12 UTC (permalink / raw)
  To: christophe.leroy; +Cc: muriloo, linuxppc-dev

On Thu, Oct 18, 2018 at 11:28 AM Christophe LEROY
<christophe.leroy@c-s.fr> wrote:
> Le 05/10/2018 à 15:21, Michael Ellerman a écrit :
> > Recently we implemented show_user_instructions() which dumps the code
> > around the NIP when a user space process dies with an unhandled
> > signal. This was modelled on the x86 code, and we even went so far as
> > to implement the exact same bug, namely that if the user process
> > crashed with its NIP pointing into the kernel we will dump kernel text
> > to dmesg. eg:
> >
> >    bad-bctr[2996]: segfault (11) at c000000000010000 nip c000000000010000 lr 12d0b0894 code 1
> >    bad-bctr[2996]: code: fbe10068 7cbe2b78 7c7f1b78 fb610048 38a10028 38810020 fb810050 7f8802a6
> >    bad-bctr[2996]: code: 3860001c f8010080 48242371 60000000 <7c7b1b79> 4082002c e8010080 eb610048
> >
> > This was discovered on x86 by Jann Horn and fixed in commit
> > 342db04ae712 ("x86/dumpstack: Don't dump kernel memory based on usermode RIP").
> >
> > Fix it by checking the adjusted NIP value (pc) and number of
> > instructions against USER_DS, and bail if we fail the check, eg:
> >
> >    bad-bctr[2969]: segfault (11) at c000000000010000 nip c000000000010000 lr 107930894 code 1
> >    bad-bctr[2969]: Bad NIP, not dumping instructions.
> >
> > Fixes: 88b0fe175735 ("powerpc: Add show_user_instructions()")
> > Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> > ---
> >   arch/powerpc/kernel/process.c | 10 ++++++++++
> >   1 file changed, 10 insertions(+)
> >
> > diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
> > index 913c5725cdb2..bb6ac471a784 100644
> > --- a/arch/powerpc/kernel/process.c
> > +++ b/arch/powerpc/kernel/process.c
> > @@ -1306,6 +1306,16 @@ void show_user_instructions(struct pt_regs *regs)
> >
> >       pc = regs->nip - (instructions_to_print * 3 / 4 * sizeof(int));
> >
> > +     /*
> > +      * Make sure the NIP points at userspace, not kernel text/data or
> > +      * elsewhere.
> > +      */
> > +     if (!__access_ok(pc, instructions_to_print * sizeof(int), USER_DS)) {
> > +             pr_info("%s[%d]: Bad NIP, not dumping instructions.\n",
> > +                     current->comm, current->pid);
> > +             return;
> > +     }
> > +
>
> Is there any reason for not using access_ok() here ?

It's probably more robust this way, in case someone decides to call
into this from kernel exception context at some point, or something
like that?

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

* Re: [PATCH] powerpc: Don't print kernel instructions in show_user_instructions()
  2018-10-18 11:12   ` Jann Horn
@ 2018-10-18 11:18     ` Christophe LEROY
  2018-10-18 11:31       ` Jann Horn
  0 siblings, 1 reply; 13+ messages in thread
From: Christophe LEROY @ 2018-10-18 11:18 UTC (permalink / raw)
  To: Jann Horn; +Cc: muriloo, linuxppc-dev



Le 18/10/2018 à 13:12, Jann Horn a écrit :
> On Thu, Oct 18, 2018 at 11:28 AM Christophe LEROY
> <christophe.leroy@c-s.fr> wrote:
>> Le 05/10/2018 à 15:21, Michael Ellerman a écrit :
>>> Recently we implemented show_user_instructions() which dumps the code
>>> around the NIP when a user space process dies with an unhandled
>>> signal. This was modelled on the x86 code, and we even went so far as
>>> to implement the exact same bug, namely that if the user process
>>> crashed with its NIP pointing into the kernel we will dump kernel text
>>> to dmesg. eg:
>>>
>>>     bad-bctr[2996]: segfault (11) at c000000000010000 nip c000000000010000 lr 12d0b0894 code 1
>>>     bad-bctr[2996]: code: fbe10068 7cbe2b78 7c7f1b78 fb610048 38a10028 38810020 fb810050 7f8802a6
>>>     bad-bctr[2996]: code: 3860001c f8010080 48242371 60000000 <7c7b1b79> 4082002c e8010080 eb610048
>>>
>>> This was discovered on x86 by Jann Horn and fixed in commit
>>> 342db04ae712 ("x86/dumpstack: Don't dump kernel memory based on usermode RIP").
>>>
>>> Fix it by checking the adjusted NIP value (pc) and number of
>>> instructions against USER_DS, and bail if we fail the check, eg:
>>>
>>>     bad-bctr[2969]: segfault (11) at c000000000010000 nip c000000000010000 lr 107930894 code 1
>>>     bad-bctr[2969]: Bad NIP, not dumping instructions.
>>>
>>> Fixes: 88b0fe175735 ("powerpc: Add show_user_instructions()")
>>> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
>>> ---
>>>    arch/powerpc/kernel/process.c | 10 ++++++++++
>>>    1 file changed, 10 insertions(+)
>>>
>>> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
>>> index 913c5725cdb2..bb6ac471a784 100644
>>> --- a/arch/powerpc/kernel/process.c
>>> +++ b/arch/powerpc/kernel/process.c
>>> @@ -1306,6 +1306,16 @@ void show_user_instructions(struct pt_regs *regs)
>>>
>>>        pc = regs->nip - (instructions_to_print * 3 / 4 * sizeof(int));
>>>
>>> +     /*
>>> +      * Make sure the NIP points at userspace, not kernel text/data or
>>> +      * elsewhere.
>>> +      */
>>> +     if (!__access_ok(pc, instructions_to_print * sizeof(int), USER_DS)) {
>>> +             pr_info("%s[%d]: Bad NIP, not dumping instructions.\n",
>>> +                     current->comm, current->pid);
>>> +             return;
>>> +     }
>>> +
>>
>> Is there any reason for not using access_ok() here ?
> 
> It's probably more robust this way, in case someone decides to call
> into this from kernel exception context at some point, or something
> like that?
> 

But access_ok() uses current->thread.addr_limit, while USER_DS may 
provide a larger segment:

#ifdef __powerpc64__
/* We use TASK_SIZE_USER64 as TASK_SIZE is not constant */
#define USER_DS		MAKE_MM_SEG(TASK_SIZE_USER64 - 1)
#else
#define USER_DS		MAKE_MM_SEG(TASK_SIZE - 1)
#endif

Christophe

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

* Re: [PATCH] powerpc: Don't print kernel instructions in show_user_instructions()
  2018-10-18 11:18     ` Christophe LEROY
@ 2018-10-18 11:31       ` Jann Horn
  2018-10-21 12:50         ` Michael Ellerman
  0 siblings, 1 reply; 13+ messages in thread
From: Jann Horn @ 2018-10-18 11:31 UTC (permalink / raw)
  To: christophe.leroy
  Cc: linuxppc-dev, Ingo Molnar, Borislav Petkov, Andy Lutomirski,
	muriloo, Thomas Gleixner

+cc x86 folks

On Thu, Oct 18, 2018 at 1:18 PM Christophe LEROY
<christophe.leroy@c-s.fr> wrote:
> Le 18/10/2018 à 13:12, Jann Horn a écrit :
> > On Thu, Oct 18, 2018 at 11:28 AM Christophe LEROY
> > <christophe.leroy@c-s.fr> wrote:
> >> Le 05/10/2018 à 15:21, Michael Ellerman a écrit :
> >>> Recently we implemented show_user_instructions() which dumps the code
> >>> around the NIP when a user space process dies with an unhandled
> >>> signal. This was modelled on the x86 code, and we even went so far as
> >>> to implement the exact same bug, namely that if the user process
> >>> crashed with its NIP pointing into the kernel we will dump kernel text
> >>> to dmesg. eg:
> >>>
> >>>     bad-bctr[2996]: segfault (11) at c000000000010000 nip c000000000010000 lr 12d0b0894 code 1
> >>>     bad-bctr[2996]: code: fbe10068 7cbe2b78 7c7f1b78 fb610048 38a10028 38810020 fb810050 7f8802a6
> >>>     bad-bctr[2996]: code: 3860001c f8010080 48242371 60000000 <7c7b1b79> 4082002c e8010080 eb610048
> >>>
> >>> This was discovered on x86 by Jann Horn and fixed in commit
> >>> 342db04ae712 ("x86/dumpstack: Don't dump kernel memory based on usermode RIP").
> >>>
> >>> Fix it by checking the adjusted NIP value (pc) and number of
> >>> instructions against USER_DS, and bail if we fail the check, eg:
> >>>
> >>>     bad-bctr[2969]: segfault (11) at c000000000010000 nip c000000000010000 lr 107930894 code 1
> >>>     bad-bctr[2969]: Bad NIP, not dumping instructions.
> >>>
> >>> Fixes: 88b0fe175735 ("powerpc: Add show_user_instructions()")
> >>> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> >>> ---
> >>>    arch/powerpc/kernel/process.c | 10 ++++++++++
> >>>    1 file changed, 10 insertions(+)
> >>>
> >>> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
> >>> index 913c5725cdb2..bb6ac471a784 100644
> >>> --- a/arch/powerpc/kernel/process.c
> >>> +++ b/arch/powerpc/kernel/process.c
> >>> @@ -1306,6 +1306,16 @@ void show_user_instructions(struct pt_regs *regs)
> >>>
> >>>        pc = regs->nip - (instructions_to_print * 3 / 4 * sizeof(int));
> >>>
> >>> +     /*
> >>> +      * Make sure the NIP points at userspace, not kernel text/data or
> >>> +      * elsewhere.
> >>> +      */
> >>> +     if (!__access_ok(pc, instructions_to_print * sizeof(int), USER_DS)) {
> >>> +             pr_info("%s[%d]: Bad NIP, not dumping instructions.\n",
> >>> +                     current->comm, current->pid);
> >>> +             return;
> >>> +     }
> >>> +
> >>
> >> Is there any reason for not using access_ok() here ?
> >
> > It's probably more robust this way, in case someone decides to call
> > into this from kernel exception context at some point, or something
> > like that?
> >
>
> But access_ok() uses current->thread.addr_limit, while USER_DS may
> provide a larger segment:
>
> #ifdef __powerpc64__
> /* We use TASK_SIZE_USER64 as TASK_SIZE is not constant */
> #define USER_DS         MAKE_MM_SEG(TASK_SIZE_USER64 - 1)
> #else
> #define USER_DS         MAKE_MM_SEG(TASK_SIZE - 1)
> #endif

Where do you write a smaller value than USER_DS into the addr_limit?

The kernel is full of places that assume that any access up to USER_DS
is safe; for example, perf_output_sample_ustack(),
get_perf_callchain(), do_exit(), flush_old_exec(), vma_dump_size(),
... - and I also don't see anything in the powerpc code that would
ever write a smaller value into the addr_limit.

I don't know powerpc well, but AFAIK the rule on X86 is basically that
even for compat tasks, attempting to access anything up to USER_DS is
safe because the kernel doesn't put any kernel mappings there. Is that
different on powerpc?

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

* Re: [PATCH] powerpc: Don't print kernel instructions in show_user_instructions()
  2018-10-18  9:28 ` [PATCH] " Christophe LEROY
  2018-10-18 11:12   ` Jann Horn
@ 2018-10-18 13:16   ` Michael Ellerman
  1 sibling, 0 replies; 13+ messages in thread
From: Michael Ellerman @ 2018-10-18 13:16 UTC (permalink / raw)
  To: Christophe LEROY, linuxppc-dev; +Cc: jannh, muriloo

Christophe LEROY <christophe.leroy@c-s.fr> writes:
> Le 05/10/2018 à 15:21, Michael Ellerman a écrit :
>> Recently we implemented show_user_instructions() which dumps the code
>> around the NIP when a user space process dies with an unhandled
>> signal. This was modelled on the x86 code, and we even went so far as
>> to implement the exact same bug, namely that if the user process
>> crashed with its NIP pointing into the kernel we will dump kernel text
>> to dmesg. eg:
>> 
>>    bad-bctr[2996]: segfault (11) at c000000000010000 nip c000000000010000 lr 12d0b0894 code 1
>>    bad-bctr[2996]: code: fbe10068 7cbe2b78 7c7f1b78 fb610048 38a10028 38810020 fb810050 7f8802a6
>>    bad-bctr[2996]: code: 3860001c f8010080 48242371 60000000 <7c7b1b79> 4082002c e8010080 eb610048
>> 
>> This was discovered on x86 by Jann Horn and fixed in commit
>> 342db04ae712 ("x86/dumpstack: Don't dump kernel memory based on usermode RIP").
>> 
>> Fix it by checking the adjusted NIP value (pc) and number of
>> instructions against USER_DS, and bail if we fail the check, eg:
>> 
>>    bad-bctr[2969]: segfault (11) at c000000000010000 nip c000000000010000 lr 107930894 code 1
>>    bad-bctr[2969]: Bad NIP, not dumping instructions.
>> 
>> Fixes: 88b0fe175735 ("powerpc: Add show_user_instructions()")
>> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
>> ---
>>   arch/powerpc/kernel/process.c | 10 ++++++++++
>>   1 file changed, 10 insertions(+)
>> 
>> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
>> index 913c5725cdb2..bb6ac471a784 100644
>> --- a/arch/powerpc/kernel/process.c
>> +++ b/arch/powerpc/kernel/process.c
>> @@ -1306,6 +1306,16 @@ void show_user_instructions(struct pt_regs *regs)
>>   
>>   	pc = regs->nip - (instructions_to_print * 3 / 4 * sizeof(int));
>>   
>> +	/*
>> +	 * Make sure the NIP points at userspace, not kernel text/data or
>> +	 * elsewhere.
>> +	 */
>> +	if (!__access_ok(pc, instructions_to_print * sizeof(int), USER_DS)) {
>> +		pr_info("%s[%d]: Bad NIP, not dumping instructions.\n",
>> +			current->comm, current->pid);
>> +		return;
>> +	}
>> +
>
> Is there any reason for not using access_ok() here ?

I wanted to check against USER_DS explicitly. But maybe that was
over-paranoid of me.

cheers

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

* Re: [PATCH] powerpc: Don't print kernel instructions in show_user_instructions()
  2018-10-18 11:31       ` Jann Horn
@ 2018-10-21 12:50         ` Michael Ellerman
  0 siblings, 0 replies; 13+ messages in thread
From: Michael Ellerman @ 2018-10-21 12:50 UTC (permalink / raw)
  To: Jann Horn, christophe.leroy
  Cc: linuxppc-dev, Ingo Molnar, Borislav Petkov, Andy Lutomirski,
	muriloo, Thomas Gleixner

Jann Horn <jannh@google.com> writes:
> +cc x86 folks
>
> On Thu, Oct 18, 2018 at 1:18 PM Christophe LEROY
> <christophe.leroy@c-s.fr> wrote:
>> Le 18/10/2018 à 13:12, Jann Horn a écrit :
>> > On Thu, Oct 18, 2018 at 11:28 AM Christophe LEROY
>> > <christophe.leroy@c-s.fr> wrote:
>> >> Le 05/10/2018 à 15:21, Michael Ellerman a écrit :
>> >>> Recently we implemented show_user_instructions() which dumps the code
>> >>> around the NIP when a user space process dies with an unhandled
>> >>> signal. This was modelled on the x86 code, and we even went so far as
>> >>> to implement the exact same bug, namely that if the user process
>> >>> crashed with its NIP pointing into the kernel we will dump kernel text
>> >>> to dmesg. eg:
>> >>>
>> >>>     bad-bctr[2996]: segfault (11) at c000000000010000 nip c000000000010000 lr 12d0b0894 code 1
>> >>>     bad-bctr[2996]: code: fbe10068 7cbe2b78 7c7f1b78 fb610048 38a10028 38810020 fb810050 7f8802a6
>> >>>     bad-bctr[2996]: code: 3860001c f8010080 48242371 60000000 <7c7b1b79> 4082002c e8010080 eb610048
>> >>>
>> >>> This was discovered on x86 by Jann Horn and fixed in commit
>> >>> 342db04ae712 ("x86/dumpstack: Don't dump kernel memory based on usermode RIP").
>> >>>
>> >>> Fix it by checking the adjusted NIP value (pc) and number of
>> >>> instructions against USER_DS, and bail if we fail the check, eg:
>> >>>
>> >>>     bad-bctr[2969]: segfault (11) at c000000000010000 nip c000000000010000 lr 107930894 code 1
>> >>>     bad-bctr[2969]: Bad NIP, not dumping instructions.
>> >>>
>> >>> Fixes: 88b0fe175735 ("powerpc: Add show_user_instructions()")
>> >>> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
>> >>> ---
>> >>>    arch/powerpc/kernel/process.c | 10 ++++++++++
>> >>>    1 file changed, 10 insertions(+)
>> >>>
>> >>> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
>> >>> index 913c5725cdb2..bb6ac471a784 100644
>> >>> --- a/arch/powerpc/kernel/process.c
>> >>> +++ b/arch/powerpc/kernel/process.c
>> >>> @@ -1306,6 +1306,16 @@ void show_user_instructions(struct pt_regs *regs)
>> >>>
>> >>>        pc = regs->nip - (instructions_to_print * 3 / 4 * sizeof(int));
>> >>>
>> >>> +     /*
>> >>> +      * Make sure the NIP points at userspace, not kernel text/data or
>> >>> +      * elsewhere.
>> >>> +      */
>> >>> +     if (!__access_ok(pc, instructions_to_print * sizeof(int), USER_DS)) {
>> >>> +             pr_info("%s[%d]: Bad NIP, not dumping instructions.\n",
>> >>> +                     current->comm, current->pid);
>> >>> +             return;
>> >>> +     }
>> >>> +
>> >>
>> >> Is there any reason for not using access_ok() here ?
>> >
>> > It's probably more robust this way, in case someone decides to call
>> > into this from kernel exception context at some point, or something
>> > like that?
>> >
>>
>> But access_ok() uses current->thread.addr_limit, while USER_DS may
>> provide a larger segment:
>>
>> #ifdef __powerpc64__
>> /* We use TASK_SIZE_USER64 as TASK_SIZE is not constant */
>> #define USER_DS         MAKE_MM_SEG(TASK_SIZE_USER64 - 1)
>> #else
>> #define USER_DS         MAKE_MM_SEG(TASK_SIZE - 1)
>> #endif
>
> Where do you write a smaller value than USER_DS into the addr_limit?

I don't think we do.

> The kernel is full of places that assume that any access up to USER_DS
> is safe; for example, perf_output_sample_ustack(),
> get_perf_callchain(), do_exit(), flush_old_exec(), vma_dump_size(),
> ... - and I also don't see anything in the powerpc code that would
> ever write a smaller value into the addr_limit.
>
> I don't know powerpc well, but AFAIK the rule on X86 is basically that
> even for compat tasks, attempting to access anything up to USER_DS is
> safe because the kernel doesn't put any kernel mappings there. Is that
> different on powerpc?

That's how it works on powerpc too.

A compat task will have a TASK_SIZE of 4GB - 1 page, but the kernel is
still at c000000000000000 and there aren't any kernel mappings below
that. So it's still safe to just check against the maximum possible user
address, which is 4PB.

cheers

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

end of thread, other threads:[~2018-10-21 12:52 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-05 13:21 [PATCH] powerpc: Don't print kernel instructions in show_user_instructions() Michael Ellerman
2018-10-05 13:52 ` Christophe LEROY
2018-10-08  8:12   ` Michael Ellerman
2018-10-05 14:02 ` Jann Horn
2018-10-08  8:23   ` Michael Ellerman
2018-10-05 17:29 ` Murilo Opsfelder Araujo
2018-10-06 12:14 ` Michael Ellerman
2018-10-18  9:28 ` [PATCH] " Christophe LEROY
2018-10-18 11:12   ` Jann Horn
2018-10-18 11:18     ` Christophe LEROY
2018-10-18 11:31       ` Jann Horn
2018-10-21 12:50         ` Michael Ellerman
2018-10-18 13:16   ` Michael Ellerman

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.