diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-08 19:03:19 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-08 19:03:19 -0700 |
commit | 89f92d6425b099538932e9b881588f87ef9f3184 (patch) | |
tree | d60eef7715df2a34459fc118fd59f7f8701cf7fd /arch/sparc64/kernel/signal.c | |
parent | 8d539108560ec121d59eee05160236488266221c (diff) | |
parent | dc5dc7e6d71ca9fd1ea01a1418150af3b2937489 (diff) | |
download | op-kernel-dev-89f92d6425b099538932e9b881588f87ef9f3184.zip op-kernel-dev-89f92d6425b099538932e9b881588f87ef9f3184.tar.gz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6:
sparc: Fix SA_ONSTACK signal handling.
Diffstat (limited to 'arch/sparc64/kernel/signal.c')
-rw-r--r-- | arch/sparc64/kernel/signal.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index 45d6bf6..07c0443 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c @@ -376,16 +376,29 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize) { - unsigned long sp; + unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS; - sp = regs->u_regs[UREG_FP] + STACK_BIAS; + /* + * If we are on the alternate signal stack and would overflow it, don't. + * Return an always-bogus address instead so we will die with SIGSEGV. + */ + if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) + return (void __user *) -1L; /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { - if (!on_sig_stack(sp) && - !((current->sas_ss_sp + current->sas_ss_size) & 7)) + if (sas_ss_flags(sp) == 0) sp = current->sas_ss_sp + current->sas_ss_size; } + + /* Always align the stack frame. This handles two cases. First, + * sigaltstack need not be mindful of platform specific stack + * alignment. Second, if we took this signal because the stack + * is not aligned properly, we'd like to take the signal cleanly + * and report that. + */ + sp &= ~7UL; + return (void __user *)(sp - framesize); } |