All of lore.kernel.org
 help / color / mirror / Atom feed
From: Will Deacon <will.deacon@arm.com>
To: Ashish Sangwan <ashishsangwan2@gmail.com>
Cc: "linux-arm-kernel@lists.infradead.org" 
	<linux-arm-kernel@lists.infradead.org>,
	Namjae Jeon <namjae.jeon@samsung.com>,
	Al Viro <viro@zeniv.linux.org.uk>,
	LKML <linux-kernel@vger.kernel.org>,
	Ashish Sangwan <a.sangwan@samsung.com>,
	"linux-arm@lists.infradead.org" <linux-arm@lists.infradead.org>
Subject: Re: Seg fault occurs when running statically compiled binary from kernel using call_usermodehelper
Date: Wed, 10 Jul 2013 17:34:11 +0100	[thread overview]
Message-ID: <20130710163410.GA30514@mudshark.cambridge.arm.com> (raw)
In-Reply-To: <CAOiN93nH9fyHoz4yrZmJ-OKCy6ogdt5bYartXCBgP5eHMUBPdw@mail.gmail.com>

On Wed, Jul 10, 2013 at 11:42:25AM +0100, Ashish Sangwan wrote:
> Any heads up on this?
> 
> or could someone just advice what can we do to debug this?
> 
> The ret_from_fork currently looks like following:
> /*
>  * This is how we return from a fork.
>  */
> ENTRY(ret_from_fork)
>         bl      schedule_tail
>         cmp     r5, #0
>         movne   r0, r4
>         adrne   lr, BSYM(1f)
>         movne   pc, r5
> 1:      get_thread_info tsk
>         b       ret_slow_syscall
> ENDPROC(ret_from_fork)
> 
> Is this a real issue? Because we are getting this just for static binaries.

Ok, I've finally got to the bottom of this, but I'm not sure on the best way
to fix it. The issue is that libc expects r0 to contain a function pointer
to be invoked at exit (rtld_fini), to clean up after a dynamic linker. If
this pointer is NULL, then it is ignored. We actually zero this pointer in
our ELF_PLAT_INIT macro.

At the same time, we have this strange code called next from the ARM ELF
loader:

	regs->ARM_r2 = stack[2];	/* r2 (envp) */			\
	regs->ARM_r1 = stack[1];	/* r1 (argv) */			\
	regs->ARM_r0 = stack[0];	/* r0 (argc) */			\

which puts argc into r0. Usually this gets overwritten by the return value
of execve (0), so everything hangs together. With kernel threads this is
different since we do the exec from ____call_usermodehelper on the stack and
then return to the new application via ret_from_fork, which takes the
slowpath; popping r0 from pt_regs and making argc visible to the library.

When the application exits and libc starts running its exit functions, we
jump to hyperspace.

My inclination would be to remove the stack popping above (patch below),
but it's a user-visible change and I'm not sure if something like OABI
requires it.

Will

--->8

diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index 06e7d50..413f387 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -54,7 +54,6 @@ struct thread_struct {
 
 #define start_thread(regs,pc,sp)                                       \
 ({                                                                     \
-       unsigned long *stack = (unsigned long *)sp;                     \
        memset(regs->uregs, 0, sizeof(regs->uregs));                    \
        if (current->personality & ADDR_LIMIT_32BIT)                    \
                regs->ARM_cpsr = USR_MODE;                              \
@@ -65,9 +64,6 @@ struct thread_struct {
        regs->ARM_cpsr |= PSR_ENDSTATE;                                 \
        regs->ARM_pc = pc & ~1;         /* pc */                        \
        regs->ARM_sp = sp;              /* sp */                        \
-       regs->ARM_r2 = stack[2];        /* r2 (envp) */                 \
-       regs->ARM_r1 = stack[1];        /* r1 (argv) */                 \
-       regs->ARM_r0 = stack[0];        /* r0 (argc) */                 \
        nommu_start_thread(regs);                                       \
 })
 

WARNING: multiple messages have this Message-ID (diff)
From: will.deacon@arm.com (Will Deacon)
To: linux-arm-kernel@lists.infradead.org
Subject: Seg fault occurs when running statically compiled binary from kernel using call_usermodehelper
Date: Wed, 10 Jul 2013 17:34:11 +0100	[thread overview]
Message-ID: <20130710163410.GA30514@mudshark.cambridge.arm.com> (raw)
In-Reply-To: <CAOiN93nH9fyHoz4yrZmJ-OKCy6ogdt5bYartXCBgP5eHMUBPdw@mail.gmail.com>

On Wed, Jul 10, 2013 at 11:42:25AM +0100, Ashish Sangwan wrote:
> Any heads up on this?
> 
> or could someone just advice what can we do to debug this?
> 
> The ret_from_fork currently looks like following:
> /*
>  * This is how we return from a fork.
>  */
> ENTRY(ret_from_fork)
>         bl      schedule_tail
>         cmp     r5, #0
>         movne   r0, r4
>         adrne   lr, BSYM(1f)
>         movne   pc, r5
> 1:      get_thread_info tsk
>         b       ret_slow_syscall
> ENDPROC(ret_from_fork)
> 
> Is this a real issue? Because we are getting this just for static binaries.

Ok, I've finally got to the bottom of this, but I'm not sure on the best way
to fix it. The issue is that libc expects r0 to contain a function pointer
to be invoked at exit (rtld_fini), to clean up after a dynamic linker. If
this pointer is NULL, then it is ignored. We actually zero this pointer in
our ELF_PLAT_INIT macro.

At the same time, we have this strange code called next from the ARM ELF
loader:

	regs->ARM_r2 = stack[2];	/* r2 (envp) */			\
	regs->ARM_r1 = stack[1];	/* r1 (argv) */			\
	regs->ARM_r0 = stack[0];	/* r0 (argc) */			\

which puts argc into r0. Usually this gets overwritten by the return value
of execve (0), so everything hangs together. With kernel threads this is
different since we do the exec from ____call_usermodehelper on the stack and
then return to the new application via ret_from_fork, which takes the
slowpath; popping r0 from pt_regs and making argc visible to the library.

When the application exits and libc starts running its exit functions, we
jump to hyperspace.

My inclination would be to remove the stack popping above (patch below),
but it's a user-visible change and I'm not sure if something like OABI
requires it.

Will

--->8

diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index 06e7d50..413f387 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -54,7 +54,6 @@ struct thread_struct {
 
 #define start_thread(regs,pc,sp)                                       \
 ({                                                                     \
-       unsigned long *stack = (unsigned long *)sp;                     \
        memset(regs->uregs, 0, sizeof(regs->uregs));                    \
        if (current->personality & ADDR_LIMIT_32BIT)                    \
                regs->ARM_cpsr = USR_MODE;                              \
@@ -65,9 +64,6 @@ struct thread_struct {
        regs->ARM_cpsr |= PSR_ENDSTATE;                                 \
        regs->ARM_pc = pc & ~1;         /* pc */                        \
        regs->ARM_sp = sp;              /* sp */                        \
-       regs->ARM_r2 = stack[2];        /* r2 (envp) */                 \
-       regs->ARM_r1 = stack[1];        /* r1 (argv) */                 \
-       regs->ARM_r0 = stack[0];        /* r0 (argc) */                 \
        nommu_start_thread(regs);                                       \
 })
 

  reply	other threads:[~2013-07-10 16:34 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-08  1:45 Seg fault occurs when running statically compiled binary from kernel using call_usermodehelper Ashish Sangwan
2013-07-08  1:46 ` Ashish Sangwan
2013-07-10 10:42   ` Ashish Sangwan
2013-07-10 10:42     ` Ashish Sangwan
2013-07-10 16:34     ` Will Deacon [this message]
2013-07-10 16:34       ` Will Deacon
2013-07-10 18:09       ` Dave Martin
2013-07-10 18:09         ` Dave Martin
2013-07-10 18:52       ` Russell King - ARM Linux
2013-07-10 18:52         ` Russell King - ARM Linux
2013-07-11 10:54         ` Will Deacon
2013-07-11 10:54           ` Will Deacon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130710163410.GA30514@mudshark.cambridge.arm.com \
    --to=will.deacon@arm.com \
    --cc=a.sangwan@samsung.com \
    --cc=ashishsangwan2@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-arm@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=namjae.jeon@samsung.com \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.