diff options
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 45d6bf632daa..07c0443ea3f5 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) | |||
376 | 376 | ||
377 | static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize) | 377 | static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize) |
378 | { | 378 | { |
379 | unsigned long sp; | 379 | unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS; |
380 | 380 | ||
381 | sp = regs->u_regs[UREG_FP] + STACK_BIAS; | 381 | /* |
382 | * If we are on the alternate signal stack and would overflow it, don't. | ||
383 | * Return an always-bogus address instead so we will die with SIGSEGV. | ||
384 | */ | ||
385 | if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) | ||
386 | return (void __user *) -1L; | ||
382 | 387 | ||
383 | /* This is the X/Open sanctioned signal stack switching. */ | 388 | /* This is the X/Open sanctioned signal stack switching. */ |
384 | if (ka->sa.sa_flags & SA_ONSTACK) { | 389 | if (ka->sa.sa_flags & SA_ONSTACK) { |
385 | if (!on_sig_stack(sp) && | 390 | if (sas_ss_flags(sp) == 0) |
386 | !((current->sas_ss_sp + current->sas_ss_size) & 7)) | ||
387 | sp = current->sas_ss_sp + current->sas_ss_size; | 391 | sp = current->sas_ss_sp + current->sas_ss_size; |
388 | } | 392 | } |
393 | |||
394 | /* Always align the stack frame. This handles two cases. First, | ||
395 | * sigaltstack need not be mindful of platform specific stack | ||
396 | * alignment. Second, if we took this signal because the stack | ||
397 | * is not aligned properly, we'd like to take the signal cleanly | ||
398 | * and report that. | ||
399 | */ | ||
400 | sp &= ~7UL; | ||
401 | |||
389 | return (void __user *)(sp - framesize); | 402 | return (void __user *)(sp - framesize); |
390 | } | 403 | } |
391 | 404 | ||