mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-14 15:54:15 +08:00
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.
This commit is contained in:
commit
89f92d6425
@ -245,15 +245,29 @@ static inline int invalid_frame_pointer(void __user *fp, int fplen)
|
||||
|
||||
static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize)
|
||||
{
|
||||
unsigned long sp;
|
||||
unsigned long sp = regs->u_regs[UREG_FP];
|
||||
|
||||
sp = regs->u_regs[UREG_FP];
|
||||
/*
|
||||
* 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 (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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -406,11 +406,27 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns
|
||||
regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
|
||||
sp = regs->u_regs[UREG_FP];
|
||||
|
||||
/*
|
||||
* 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 (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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user