Commit 89f92d64 authored by Linus Torvalds's avatar Linus Torvalds
parents 8d539108 dc5dc7e6
...@@ -245,15 +245,29 @@ static inline int invalid_frame_pointer(void __user *fp, int fplen) ...@@ -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) 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. */ /* This is the X/Open sanctioned signal stack switching. */
if (sa->sa_flags & SA_ONSTACK) { 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; 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); return (void __user *)(sp - framesize);
} }
......
...@@ -376,16 +376,29 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) ...@@ -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) 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. */ /* This is the X/Open sanctioned signal stack switching. */
if (ka->sa.sa_flags & SA_ONSTACK) { if (ka->sa.sa_flags & SA_ONSTACK) {
if (!on_sig_stack(sp) && if (sas_ss_flags(sp) == 0)
!((current->sas_ss_sp + current->sas_ss_size) & 7))
sp = current->sas_ss_sp + current->sas_ss_size; 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); return (void __user *)(sp - framesize);
} }
......
...@@ -406,11 +406,27 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns ...@@ -406,11 +406,27 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns
regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
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. */ /* This is the X/Open sanctioned signal stack switching. */
if (sa->sa_flags & SA_ONSTACK) { 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; 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); return (void __user *)(sp - framesize);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment