diff options
author | Philip Guenthe <guenther@cvs.openbsd.org> | 2012-12-02 07:03:33 +0000 |
---|---|---|
committer | Philip Guenthe <guenther@cvs.openbsd.org> | 2012-12-02 07:03:33 +0000 |
commit | 15c7623306062239f832ef81bd0bdfc804b4d186 (patch) | |
tree | d4c341f7fa4f162d4c4cd1ede1db5c9089f0afb6 /sys/arch/arm | |
parent | b02dfe0ab7aae6700f0c15419373891118eab134 (diff) |
Determine whether we're currently on the alternative signal stack
dynamically, by comparing the stack pointer against the altstack
base and size, so that you get the correct answer if you longjmp
out of the signal handler, as tested by regress/sys/kern/stackjmp/.
Also, fix alt stack handling on vax, where it was completely broken.
Testing and corrections by miod@, krw@, tobiasu@, pirofti@
Diffstat (limited to 'sys/arch/arm')
-rw-r--r-- | sys/arch/arm/arm/sig_machdep.c | 46 | ||||
-rw-r--r-- | sys/arch/arm/include/cpu.h | 3 | ||||
-rw-r--r-- | sys/arch/arm/include/signal.h | 4 |
3 files changed, 10 insertions, 43 deletions
diff --git a/sys/arch/arm/arm/sig_machdep.c b/sys/arch/arm/arm/sig_machdep.c index 13b9bfc113f..22ec82356ca 100644 --- a/sys/arch/arm/arm/sig_machdep.c +++ b/sys/arch/arm/arm/sig_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sig_machdep.c,v 1.7 2011/09/20 22:02:11 miod Exp $ */ +/* $OpenBSD: sig_machdep.c,v 1.8 2012/12/02 07:03:31 guenther Exp $ */ /* $NetBSD: sig_machdep.c,v 1.22 2003/10/08 00:28:41 thorpej Exp $ */ /* @@ -65,9 +65,6 @@ process_frame(struct proc *p) return p->p_addr->u_pcb.pcb_tf; } -void *getframe(struct proc *p, int sig, int *onstack); - - /* * Send an interrupt to process. * @@ -85,21 +82,19 @@ sendsig(sig_t catcher, int sig, int returnmask, u_long code, int type, struct trapframe *tf; struct sigframe *fp, frame; struct sigacts *psp = p->p_sigacts; - int oonstack = p->p_sigstk.ss_flags & SS_ONSTACK; - int onstack = 0; tf = process_frame(p); /* Do we need to jump onto the signal stack? */ /* Allocate space for the signal handler context. */ - if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 && !oonstack && - (psp->ps_sigonstack & sigmask(sig))) { - onstack = 1; + if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 && + !sigonstack(tf->tf_usr_sp) && (psp->ps_sigonstack & sigmask(sig))) fp = (struct sigframe *)((caddr_t)p->p_sigstk.ss_sp + p->p_sigstk.ss_size); - } else + else fp = (struct sigframe *)tf->tf_usr_sp; + /* make room on the stack */ fp--; @@ -107,6 +102,7 @@ sendsig(sig_t catcher, int sig, int returnmask, u_long code, int type, fp = (void *)STACKALIGN(fp); /* Build stack frame for signal trampoline. */ + bzero(&frame, sizeof(frame)); frame.sf_signum = sig; frame.sf_sip = NULL; frame.sf_scp = &fp->sf_sc; @@ -132,9 +128,6 @@ sendsig(sig_t catcher, int sig, int returnmask, u_long code, int type, frame.sf_sc.sc_pc = tf->tf_pc; frame.sf_sc.sc_spsr = tf->tf_spsr; - /* Save signal stack. */ - frame.sf_sc.sc_onstack = p->p_sigstk.ss_flags & SS_ONSTACK; - /* Save signal mask. */ frame.sf_sc.sc_mask = returnmask; @@ -172,28 +165,7 @@ sendsig(sig_t catcher, int sig, int returnmask, u_long code, int type, tf->tf_usr_lr = (int)p->p_sigcode; /* XXX This should not be needed. */ cpu_icache_sync_all(); - - /* Remember that we're now on the signal stack. */ - if (onstack) - p->p_sigstk.ss_flags |= SS_ONSTACK; -} - -#if 0 -void * -getframe(struct proc *p, int sig, int *onstack) -{ - struct sigctx *ctx = &p->p_sigctx; - struct trapframe *tf = process_frame(l); - - /* Do we need to jump onto the signal stack? */ - *onstack = (ctx->ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 - && (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; - if (*onstack) - return (char *)ctx->ps_sigstk.ss_sp + ctx->ps_sigstk.ss_size; - return (void *)tf->tf_usr_sp; } -#endif - /* * System call to cleanup state after a signal @@ -259,12 +231,6 @@ sys_sigreturn(struct proc *p, void *v, register_t *retval) tf->tf_pc = context.sc_pc; tf->tf_spsr = context.sc_spsr; - /* Restore signal stack. */ - if (context.sc_onstack & SS_ONSTACK) - p->p_sigstk.ss_flags |= SS_ONSTACK; - else - p->p_sigstk.ss_flags &= ~SS_ONSTACK; - /* Restore signal mask. */ p->p_sigmask = context.sc_mask & ~sigcantmask; diff --git a/sys/arch/arm/include/cpu.h b/sys/arch/arm/include/cpu.h index b9260fd852f..155a2a2a57e 100644 --- a/sys/arch/arm/include/cpu.h +++ b/sys/arch/arm/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.30 2011/11/16 20:50:18 deraadt Exp $ */ +/* $OpenBSD: cpu.h,v 1.31 2012/12/02 07:03:31 guenther Exp $ */ /* $NetBSD: cpu.h,v 1.34 2003/06/23 11:01:08 martin Exp $ */ /* @@ -154,6 +154,7 @@ extern int current_intr_depth; * PROC_PC: Find out the program counter for the given process. */ #define PROC_PC(p) ((p)->p_addr->u_pcb.pcb_tf->tf_pc) +#define PROC_STACK(p) ((p)->p_addr->u_pcb.pcb_tf->tf_usr_sp) /* The address of the vector page. */ extern vaddr_t vector_page; diff --git a/sys/arch/arm/include/signal.h b/sys/arch/arm/include/signal.h index 5af8396e380..564ea4f5bfc 100644 --- a/sys/arch/arm/include/signal.h +++ b/sys/arch/arm/include/signal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: signal.h,v 1.7 2011/09/20 22:02:13 miod Exp $ */ +/* $OpenBSD: signal.h,v 1.8 2012/12/02 07:03:31 guenther Exp $ */ /* $NetBSD: signal.h,v 1.5 2003/10/18 17:57:21 briggs Exp $ */ /* @@ -61,7 +61,7 @@ typedef int sig_atomic_t; * a non-standard exit is performed. */ struct sigcontext { - int sc_onstack; /* sigstack state to restore */ + int __sc_unused; int sc_mask; /* signal mask to restore (old style) */ unsigned int sc_spsr; |