From 15c7623306062239f832ef81bd0bdfc804b4d186 Mon Sep 17 00:00:00 2001 From: Philip Guenthe Date: Sun, 2 Dec 2012 07:03:33 +0000 Subject: 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@ --- sys/arch/m68k/include/cpu.h | 3 ++- sys/arch/m68k/include/signal.h | 4 ++-- sys/arch/m68k/m68k/sig_machdep.c | 22 ++++++++-------------- 3 files changed, 12 insertions(+), 17 deletions(-) (limited to 'sys/arch/m68k') diff --git a/sys/arch/m68k/include/cpu.h b/sys/arch/m68k/include/cpu.h index c88366858b8..4a3df3f5514 100644 --- a/sys/arch/m68k/include/cpu.h +++ b/sys/arch/m68k/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.25 2011/11/16 20:50:18 deraadt Exp $ */ +/* $OpenBSD: cpu.h,v 1.26 2012/12/02 07:03:31 guenther Exp $ */ /* $NetBSD: cpu.h,v 1.3 1997/02/02 06:56:57 thorpej Exp $ */ /* @@ -253,6 +253,7 @@ int cachectl(struct proc *, int, vaddr_t, int); * This is used during profiling to integrate system time. */ #define PROC_PC(p) (((struct trapframe *)((p)->p_md.md_regs))->tf_pc) +#define PROC_STACK(p) (((struct trapframe *)((p)->p_md.md_regs))->tf_regs[15]) #define cpu_idle_enter() do { /* nothing */ } while (0) #define cpu_idle_leave() do { /* nothing */ } while (0) diff --git a/sys/arch/m68k/include/signal.h b/sys/arch/m68k/include/signal.h index 731b01b0a50..9115367cfcb 100644 --- a/sys/arch/m68k/include/signal.h +++ b/sys/arch/m68k/include/signal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: signal.h,v 1.5 2006/01/08 14:20:17 millert Exp $ */ +/* $OpenBSD: signal.h,v 1.6 2012/12/02 07:03:31 guenther Exp $ */ /* $NetBSD: signal.h,v 1.4 1995/01/10 19:01:31 jtc Exp $ */ /* @@ -55,7 +55,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 */ int sc_sp; /* sp to restore */ int sc_fp; /* fp to restore */ diff --git a/sys/arch/m68k/m68k/sig_machdep.c b/sys/arch/m68k/m68k/sig_machdep.c index eae3162703f..f3933fdf9d4 100644 --- a/sys/arch/m68k/m68k/sig_machdep.c +++ b/sys/arch/m68k/m68k/sig_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sig_machdep.c,v 1.26 2012/08/22 13:33:32 okan Exp $ */ +/* $OpenBSD: sig_machdep.c,v 1.27 2012/12/02 07:03:31 guenther Exp $ */ /* $NetBSD: sig_machdep.c,v 1.3 1997/04/30 23:28:03 gwr Exp $ */ /* @@ -131,11 +131,10 @@ sendsig(catcher, sig, mask, code, type, val) struct frame *frame; struct sigacts *psp = p->p_sigacts; short ft; - int oonstack, fsize; + int fsize; frame = (struct frame *)p->p_md.md_regs; ft = frame->f_format; - oonstack = p->p_sigstk.ss_flags & SS_ONSTACK; /* * Allocate and validate space for the signal handler @@ -145,22 +144,22 @@ sendsig(catcher, sig, mask, code, type, val) * the space with a `brk'. */ fsize = sizeof(struct sigframe); - if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 && !oonstack && - (psp->ps_sigonstack & sigmask(sig))) { + if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 && + !sigonstack(frame->f_regs[SP]) && + (psp->ps_sigonstack & sigmask(sig))) fp = (struct sigframe *)(p->p_sigstk.ss_sp + p->p_sigstk.ss_size - fsize); - p->p_sigstk.ss_flags |= SS_ONSTACK; - } else + else fp = (struct sigframe *)(frame->f_regs[SP] - fsize); if ((unsigned)fp <= USRSTACK - ptoa(p->p_vmspace->vm_ssize)) (void)uvm_grow(p, (unsigned)fp); #ifdef DEBUG if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) printf("sendsig(%d): sig %d ssp %p usp %p scp %p ft %d\n", - p->p_pid, sig, &oonstack, fp, &fp->sf_sc, ft); + p->p_pid, sig, &fsize, fp, &fp->sf_sc, ft); #endif kfp = (struct sigframe *)malloc((u_long)fsize, M_TEMP, - M_WAITOK | M_CANFAIL); + M_WAITOK | M_CANFAIL | M_ZERO); if (kfp == NULL) { /* Better halt the process in its track than panicing */ sigexit(p, SIGILL); @@ -226,7 +225,6 @@ sendsig(catcher, sig, mask, code, type, val) /* * Build the signal context to be used by sigreturn. */ - kfp->sf_sc.sc_onstack = oonstack; kfp->sf_sc.sc_mask = mask; kfp->sf_sc.sc_sp = frame->f_regs[SP]; kfp->sf_sc.sc_fp = frame->f_regs[A6]; @@ -320,10 +318,6 @@ sys_sigreturn(p, v, retval) /* * Restore the user supplied information */ - if (scp->sc_onstack & 1) - p->p_sigstk.ss_flags |= SS_ONSTACK; - else - p->p_sigstk.ss_flags &= ~SS_ONSTACK; p->p_sigmask = scp->sc_mask &~ sigcantmask; frame = (struct frame *) p->p_md.md_regs; frame->f_regs[SP] = scp->sc_sp; -- cgit v1.2.3