aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/signal32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/signal32.c')
-rw-r--r--arch/sparc64/kernel/signal32.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 9415d2c918c5..0f6b7b156efd 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -406,11 +406,27 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns
406 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; 406 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
407 sp = regs->u_regs[UREG_FP]; 407 sp = regs->u_regs[UREG_FP];
408 408
409 /*
410 * If we are on the alternate signal stack and would overflow it, don't.
411 * Return an always-bogus address instead so we will die with SIGSEGV.
412 */
413 if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
414 return (void __user *) -1L;
415
409 /* This is the X/Open sanctioned signal stack switching. */ 416 /* This is the X/Open sanctioned signal stack switching. */
410 if (sa->sa_flags & SA_ONSTACK) { 417 if (sa->sa_flags & SA_ONSTACK) {
411 if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7)) 418 if (sas_ss_flags(sp) == 0)
412 sp = current->sas_ss_sp + current->sas_ss_size; 419 sp = current->sas_ss_sp + current->sas_ss_size;
413 } 420 }
421
422 /* Always align the stack frame. This handles two cases. First,
423 * sigaltstack need not be mindful of platform specific stack
424 * alignment. Second, if we took this signal because the stack
425 * is not aligned properly, we'd like to take the signal cleanly
426 * and report that.
427 */
428 sp &= ~7UL;
429
414 return (void __user *)(sp - framesize); 430 return (void __user *)(sp - framesize);
415} 431}
416 432