This commit updates the behavior of signal handling under !MMU environment. 1) the stack preparation for the signal handlers and 2) retoration of stack after rt_sigreturn(2) syscall. Those are needed as the stack usage on vfork(2) syscall is different.
Signed-off-by: Hajime Tazaki <thehaj...@gmail.com> --- arch/x86/um/signal.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/x86/um/signal.c b/arch/x86/um/signal.c index 2cc8c2309022..ae9b231dd8f8 100644 --- a/arch/x86/um/signal.c +++ b/arch/x86/um/signal.c @@ -537,6 +537,18 @@ int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig, /* could use a vstub here */ return err; +#ifndef CONFIG_MMU + /* + * we need to push handler address at top of stack, as + * __kernel_vsyscall, called after this returns with ret with + * stack contents, thus push the handler here. + */ + frame = (struct rt_sigframe __user *) ((unsigned long) frame - + sizeof(unsigned long)); + err |= __put_user((unsigned long)ksig->ka.sa.sa_handler, + (unsigned long *)frame); +#endif + if (err) return err; @@ -562,6 +574,20 @@ SYSCALL_DEFINE0(rt_sigreturn) unsigned long sp = PT_REGS_SP(¤t->thread.regs); struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(sp - sizeof(long)); +#ifndef CONFIG_MMU + /** + * we enter here with: + * + * __restore_rt: + * mov $15, %rax + * call *%rax (translated from syscall) + * + * (code is from musl libc) + * so, stack needs to be popped of "call"ed address before + * looking at rt_sigframe. + */ + frame = (struct rt_sigframe __user *)((unsigned long)frame + sizeof(long)); +#endif struct ucontext __user *uc = &frame->uc; sigset_t set; -- 2.43.0