From 9436d5c32b1ac8d4efdbc933611b5e699908854e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 10 Nov 2012 01:15:42 -0500 Subject: [PATCH 1/5] um: get_safe_registers() should be done in flush_thread(), not start_thread() ... or we'll end up buggering the results of ELF_PLAT_INIT() Signed-off-by: Al Viro --- arch/um/kernel/exec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 3a8ece7d09ca..0d7103c9eff3 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -32,13 +32,14 @@ void flush_thread(void) "err = %d\n", ret); force_sig(SIGKILL, current); } + get_safe_registers(current_pt_regs()->regs.gp, + current_pt_regs()->regs.fp); __switch_mm(¤t->mm->context.id); } void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) { - get_safe_registers(regs->regs.gp, regs->regs.fp); PT_REGS_IP(regs) = eip; PT_REGS_SP(regs) = esp; current->ptrace &= ~PT_DTRACE; From d26654e5f9cd27815ab5bc8148c826f3b960396c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 20 Sep 2012 15:49:09 -0400 Subject: [PATCH 2/5] openrisk: fix altstack switching on sigreturn do_sigaltstack() expects _userland_ address, TYVM... Signed-off-by: Al Viro --- arch/openrisc/kernel/signal.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c index 30110297f4f9..ddedc8a77861 100644 --- a/arch/openrisc/kernel/signal.c +++ b/arch/openrisc/kernel/signal.c @@ -84,7 +84,6 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs) { struct rt_sigframe *frame = (struct rt_sigframe __user *)regs->sp; sigset_t set; - stack_t st; /* * Since we stacked the signal on a dword boundary, @@ -104,11 +103,10 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs) if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) goto badframe; - if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) - goto badframe; /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - do_sigaltstack(&st, NULL, regs->sp); + if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) + goto badframe; return regs->gpr[11]; From 9dc87c7b5b0a2db407e086f45cf08ca78208cc16 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 20 Sep 2012 16:38:34 -0400 Subject: [PATCH 3/5] sh64: fix altstack switching on sigreturn incidentally, declaring a local variable as __user (!) to make sparse STFU is really sick. Especially since sparse had been 100% right - it *is* a bug. Signed-off-by: Al Viro --- arch/sh/kernel/signal_64.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c index 23853814bd17..d867cd95a622 100644 --- a/arch/sh/kernel/signal_64.c +++ b/arch/sh/kernel/signal_64.c @@ -347,7 +347,6 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3, { struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (long) REF_REG_SP; sigset_t set; - stack_t __user st; long long ret; /* Always make any pending restarted system calls return -EINTR */ @@ -365,11 +364,10 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3, goto badframe; regs->pc -= 4; - if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) - goto badframe; /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - do_sigaltstack(&st, NULL, REF_REG_SP); + if (do_sigaltstack(&frame->uc.uc_stack, NULL, REF_REG_SP) == -EFAULT) + goto badframe; return (int) ret; From afd3f96dc34357584763c2dc453192c78a9dbce0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 20 Nov 2012 10:36:17 -0500 Subject: [PATCH 4/5] score: do_sigaltstack() expects a userland pointer... Signed-off-by: Al Viro --- arch/score/kernel/signal.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/arch/score/kernel/signal.c b/arch/score/kernel/signal.c index c268bbf8b410..02353bde92d8 100644 --- a/arch/score/kernel/signal.c +++ b/arch/score/kernel/signal.c @@ -148,7 +148,6 @@ score_rt_sigreturn(struct pt_regs *regs) { struct rt_sigframe __user *frame; sigset_t set; - stack_t st; int sig; /* Always make any pending restarted system calls return -EINTR */ @@ -168,12 +167,10 @@ score_rt_sigreturn(struct pt_regs *regs) else if (sig) force_sig(sig, current); - if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st))) - goto badframe; - /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - do_sigaltstack((stack_t __user *)&st, NULL, regs->regs[0]); + if (do_sigaltstack(&frame->rs_uc.uc_stack, NULL, regs->regs[0]) == -EFAULT) + goto badframe; regs->is_syscall = 0; __asm__ __volatile__( From 02232f8d2b22708f0651dc515544f4a7ef1e0224 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 20 Nov 2012 10:41:11 -0500 Subject: [PATCH 5/5] microblaze: rt_sigreturn is too trigger-happy about sigaltstack errors Signed-off-by: Al Viro --- arch/microblaze/kernel/signal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c index 3847e5b9c601..3903e3d11f5a 100644 --- a/arch/microblaze/kernel/signal.c +++ b/arch/microblaze/kernel/signal.c @@ -111,7 +111,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1)) + if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1) == -EFAULT) goto badframe; return rval;