summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2018-04-12 17:13:45 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2018-04-12 17:13:45 +0000
commit9e91f96d779c665c5377cfd5667ee7e276f4c6eb (patch)
treefe187bb093929803715228a98ffc99028915fbad /sys/arch
parent0f04bf0af32f3ceff2d723822807131626fbff5d (diff)
Implement MAP_STACK option for mmap(). Synchronous faults (pagefault and
syscall) confirm the stack register points at MAP_STACK memory, otherwise SIGSEGV is delivered. sigaltstack() and pthread_attr_setstack() are modified to create a MAP_STACK sub-region which satisfies alignment requirements. Observe that MAP_STACK can only be set/cleared by mmap(), which zeroes the contents of the region -- there is no mprotect() equivalent operation, so there is no MAP_STACK-adding gadget. This opportunistic software-emulation of a stack protection bit makes stack-pivot operations during ROPchain fragile (kind of like removing a tool from the toolbox). original discussion with tedu, uvm work by stefan, testing by mortimer ok kettenis
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/alpha/alpha/machdep.c7
-rw-r--r--sys/arch/alpha/alpha/trap.c20
-rw-r--r--sys/arch/amd64/amd64/machdep.c4
-rw-r--r--sys/arch/amd64/amd64/trap.c21
-rw-r--r--sys/arch/arm/arm/fault.c20
-rw-r--r--sys/arch/arm/arm/sig_machdep.c8
-rw-r--r--sys/arch/arm64/arm64/ast.c5
-rw-r--r--sys/arch/arm64/arm64/sig_machdep.c8
-rw-r--r--sys/arch/arm64/arm64/trap.c18
-rw-r--r--sys/arch/hppa/hppa/machdep.c4
-rw-r--r--sys/arch/hppa/hppa/trap.c24
-rw-r--r--sys/arch/i386/i386/machdep.c4
-rw-r--r--sys/arch/i386/i386/trap.c20
-rw-r--r--sys/arch/m88k/m88k/sig_machdep.c5
-rw-r--r--sys/arch/macppc/macppc/machdep.c6
-rw-r--r--sys/arch/mips64/mips64/sendsig.c7
-rw-r--r--sys/arch/mips64/mips64/trap.c25
-rw-r--r--sys/arch/powerpc/powerpc/trap.c20
-rw-r--r--sys/arch/sh/sh/sh_machdep.c6
-rw-r--r--sys/arch/socppc/socppc/machdep.c6
-rw-r--r--sys/arch/sparc64/sparc64/machdep.c6
-rw-r--r--sys/arch/sparc64/sparc64/trap.c19
22 files changed, 219 insertions, 44 deletions
diff --git a/sys/arch/alpha/alpha/machdep.c b/sys/arch/alpha/alpha/machdep.c
index a4f9a41cd7f..a4ff49d2e6b 100644
--- a/sys/arch/alpha/alpha/machdep.c
+++ b/sys/arch/alpha/alpha/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.183 2017/12/30 20:46:59 guenther Exp $ */
+/* $OpenBSD: machdep.c,v 1.184 2018/04/12 17:13:41 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.210 2000/06/01 17:12:38 thorpej Exp $ */
/*-
@@ -1414,8 +1414,9 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
*/
if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
!sigonstack(oldsp) && (psp->ps_sigonstack & sigmask(sig)))
- scp = (struct sigcontext *)(p->p_sigstk.ss_sp +
- p->p_sigstk.ss_size - rndfsize);
+ scp = (struct sigcontext *)
+ (trunc_page((vaddr_t)p->p_sigstk.ss_sp + p->p_sigstk.ss_size)
+ - rndfsize);
else
scp = (struct sigcontext *)(oldsp - rndfsize);
diff --git a/sys/arch/alpha/alpha/trap.c b/sys/arch/alpha/alpha/trap.c
index 2fee1864859..2dce18bcb26 100644
--- a/sys/arch/alpha/alpha/trap.c
+++ b/sys/arch/alpha/alpha/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.84 2018/04/09 04:11:02 deraadt Exp $ */
+/* $OpenBSD: trap.c,v 1.85 2018/04/12 17:13:41 deraadt Exp $ */
/* $NetBSD: trap.c,v 1.52 2000/05/24 16:48:33 thorpej Exp $ */
/*-
@@ -242,8 +242,26 @@ trap(a0, a1, a2, entry, framep)
framep->tf_regs[FRAME_SP] = alpha_pal_rdusp();
user = (framep->tf_regs[FRAME_PS] & ALPHA_PSL_USERMODE) != 0;
if (user) {
+ vaddr_t sp;
+
p->p_md.md_tf = framep;
refreshcreds(p);
+
+ sp = PROC_STACK(p);
+ if (p->p_vmspace->vm_map.serial != p->p_spserial ||
+ p->p_spstart == 0 || sp < p->p_spstart ||
+ sp >= p->p_spend) {
+ KERNEL_LOCK();
+ if (!uvm_map_check_stack_range(p, sp)) {
+ printf("trap [%s]%d/%d type %d: sp %lx not inside %lx-%lx\n",
+ p->p_p->ps_comm, p->p_p->ps_pid, p->p_tid,
+ 0, sp, p->p_spstart, p->p_spend);
+ sv.sival_ptr = (void *)PROC_PC(p);
+ trapsignal(p, SIGSEGV, entry, SEGV_ACCERR, sv);
+ }
+
+ KERNEL_UNLOCK();
+ }
}
switch (entry) {
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index b05455ab943..8810f71dcb8 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.240 2018/03/29 01:21:02 guenther Exp $ */
+/* $OpenBSD: machdep.c,v 1.241 2018/04/12 17:13:43 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */
/*-
@@ -593,7 +593,7 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
/* Allocate space for the signal handler context. */
if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
!sigonstack(tf->tf_rsp) && (psp->ps_sigonstack & sigmask(sig)))
- sp = (register_t)p->p_sigstk.ss_sp + p->p_sigstk.ss_size;
+ sp = trunc_page((vaddr_t)p->p_sigstk.ss_sp + p->p_sigstk.ss_size);
else
sp = tf->tf_rsp - 128;
diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c
index dc2d115c207..418395b54b7 100644
--- a/sys/arch/amd64/amd64/trap.c
+++ b/sys/arch/amd64/amd64/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.64 2018/02/21 19:24:15 guenther Exp $ */
+/* $OpenBSD: trap.c,v 1.65 2018/04/12 17:13:43 deraadt Exp $ */
/* $NetBSD: trap.c,v 1.2 2003/05/04 23:51:56 fvdl Exp $ */
/*-
@@ -175,9 +175,28 @@ trap(struct trapframe *frame)
#endif
if (!KERNELMODE(frame->tf_cs, frame->tf_rflags)) {
+ vaddr_t sp;
+
type |= T_USER;
p->p_md.md_regs = frame;
refreshcreds(p);
+
+ sp = PROC_STACK(p);
+ if (p->p_vmspace->vm_map.serial != p->p_spserial ||
+ p->p_spstart == 0 || sp < p->p_spstart ||
+ sp >= p->p_spend) {
+ KERNEL_LOCK();
+ if (!uvm_map_check_stack_range(p, sp)) {
+ printf("trap [%s]%d/%d type %d: sp %lx not inside %lx-%lx\n",
+ p->p_p->ps_comm, p->p_p->ps_pid, p->p_tid,
+ (int)frame->tf_trapno, sp, p->p_spstart, p->p_spend);
+ sv.sival_ptr = (void *)PROC_PC(p);
+ trapsignal(p, SIGSEGV, type & ~T_USER,
+ SEGV_ACCERR, sv);
+ }
+
+ KERNEL_UNLOCK();
+ }
}
switch (type) {
diff --git a/sys/arch/arm/arm/fault.c b/sys/arch/arm/arm/fault.c
index 8ece22e083b..c69f5ea9439 100644
--- a/sys/arch/arm/arm/fault.c
+++ b/sys/arch/arm/arm/fault.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fault.c,v 1.32 2018/01/26 16:22:19 kettenis Exp $ */
+/* $OpenBSD: fault.c,v 1.33 2018/04/12 17:13:43 deraadt Exp $ */
/* $NetBSD: fault.c,v 1.46 2004/01/21 15:39:21 skrll Exp $ */
/*
@@ -237,8 +237,26 @@ data_abort_handler(trapframe_t *tf)
*/
if (user) {
+ vaddr_t sp;
+
p->p_addr->u_pcb.pcb_tf = tf;
refreshcreds(p);
+
+ sp = PROC_STACK(p);
+ if (p->p_vmspace->vm_map.serial != p->p_spserial ||
+ p->p_spstart == 0 || sp < p->p_spstart ||
+ sp >= p->p_spend) {
+ KERNEL_LOCK();
+ if (!uvm_map_check_stack_range(p, sp)) {
+ printf("trap [%s]%d/%d type %d: sp %lx not inside %lx-%lx\n",
+ p->p_p->ps_comm, p->p_p->ps_pid, p->p_tid,
+ 0, sp, p->p_spstart, p->p_spend);
+
+ sv.sival_ptr = (void *)PROC_PC(p);
+ trapsignal(p, SIGSEGV, 0, SEGV_ACCERR, sv);
+ }
+ KERNEL_UNLOCK();
+ }
}
/*
diff --git a/sys/arch/arm/arm/sig_machdep.c b/sys/arch/arm/arm/sig_machdep.c
index a0655e1bab1..8808158457a 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.15 2017/03/12 17:57:12 kettenis Exp $ */
+/* $OpenBSD: sig_machdep.c,v 1.16 2018/04/12 17:13:43 deraadt Exp $ */
/* $NetBSD: sig_machdep.c,v 1.22 2003/10/08 00:28:41 thorpej Exp $ */
/*
@@ -58,6 +58,8 @@
#include <machine/pcb.h>
#include <arm/cpufunc.h>
+#include <uvm/uvm_extern.h>
+
static __inline struct trapframe *
process_frame(struct proc *p)
{
@@ -87,8 +89,8 @@ sendsig(sig_t catcher, int sig, int returnmask, u_long code, int type,
/* Allocate space for the signal handler context. */
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);
+ fp = (struct sigframe *)
+ trunc_page((vaddr_t)p->p_sigstk.ss_sp + p->p_sigstk.ss_size);
else
fp = (struct sigframe *)tf->tf_usr_sp;
diff --git a/sys/arch/arm64/arm64/ast.c b/sys/arch/arm64/arm64/ast.c
index 240d6cc5355..dc5586ff085 100644
--- a/sys/arch/arm64/arm64/ast.c
+++ b/sys/arch/arm64/arm64/ast.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ast.c,v 1.4 2017/09/08 05:36:51 deraadt Exp $ */
+/* $OpenBSD: ast.c,v 1.5 2018/04/12 17:13:43 deraadt Exp $ */
/*
* Copyright (c) 2015 Dale Rahn <drahn@dalerahn.com>
*
@@ -18,7 +18,10 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/proc.h>
#include <sys/user.h>
+#include <sys/signal.h>
#include <sys/syscall.h>
#include <sys/syscall_mi.h>
#include <machine/pcb.h>
diff --git a/sys/arch/arm64/arm64/sig_machdep.c b/sys/arch/arm64/arm64/sig_machdep.c
index 739544a5424..dcd0e38c0d6 100644
--- a/sys/arch/arm64/arm64/sig_machdep.c
+++ b/sys/arch/arm64/arm64/sig_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sig_machdep.c,v 1.4 2017/08/08 21:52:41 drahn Exp $ */
+/* $OpenBSD: sig_machdep.c,v 1.5 2018/04/12 17:13:43 deraadt Exp $ */
/*
* Copyright (c) 1990 The Regents of the University of California.
@@ -78,6 +78,8 @@
#include <machine/frame.h>
#include <machine/pcb.h>
+#include <uvm/uvm_extern.h>
+
static __inline struct trapframe *
process_frame(struct proc *p)
{
@@ -109,8 +111,8 @@ sendsig(sig_t catcher, int sig, int returnmask, u_long code, int type,
/* Allocate space for the signal handler context. */
if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
!sigonstack(tf->tf_sp) && (psp->ps_sigonstack & sigmask(sig)))
- fp = (struct sigframe *)((caddr_t)p->p_sigstk.ss_sp +
- p->p_sigstk.ss_size);
+ fp = (struct sigframe *)
+ trunc_page((vaddr_t)p->p_sigstk.ss_sp + p->p_sigstk.ss_size);
else
fp = (struct sigframe *)tf->tf_sp;
diff --git a/sys/arch/arm64/arm64/trap.c b/sys/arch/arm64/arm64/trap.c
index c655e5e6607..6e493a4e15f 100644
--- a/sys/arch/arm64/arm64/trap.c
+++ b/sys/arch/arm64/arm64/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.18 2018/04/09 22:21:05 kettenis Exp $ */
+/* $OpenBSD: trap.c,v 1.19 2018/04/12 17:13:43 deraadt Exp $ */
/*-
* Copyright (c) 2014 Andrew Turner
* All rights reserved.
@@ -225,6 +225,7 @@ do_el0_sync(struct trapframe *frame)
union sigval sv;
uint32_t exception;
uint64_t esr, far;
+ vaddr_t sp;
esr = READ_SPECIALREG(esr_el1);
exception = ESR_ELx_EXCEPTION(esr);
@@ -235,6 +236,21 @@ do_el0_sync(struct trapframe *frame)
p->p_addr->u_pcb.pcb_tf = frame;
refreshcreds(p);
+ sp = PROC_STACK(p);
+ if (p->p_vmspace->vm_map.serial != p->p_spserial ||
+ p->p_spstart == 0 || sp < p->p_spstart ||
+ sp >= p->p_spend) {
+ KERNEL_LOCK();
+ if (!uvm_map_check_stack_range(p, sp)) {
+ printf("trap [%s]%d/%d type %d: sp %lx not inside %lx-%lx\n",
+ p->p_p->ps_comm, p->p_p->ps_pid, p->p_tid,
+ exception, sp, p->p_spstart, p->p_spend);
+ sv.sival_ptr = (void *)PROC_PC(p);
+ trapsignal(p, SIGSEGV, exception, SEGV_ACCERR, sv);
+ }
+ KERNEL_UNLOCK();
+ }
+
switch(exception) {
case EXCP_UNKNOWN:
vfp_save();
diff --git a/sys/arch/hppa/hppa/machdep.c b/sys/arch/hppa/hppa/machdep.c
index 3cbd49e0e02..3f9b5f2ab77 100644
--- a/sys/arch/hppa/hppa/machdep.c
+++ b/sys/arch/hppa/hppa/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.250 2017/12/30 20:46:59 guenther Exp $ */
+/* $OpenBSD: machdep.c,v 1.251 2018/04/12 17:13:43 deraadt Exp $ */
/*
* Copyright (c) 1999-2003 Michael Shalayeff
@@ -1224,7 +1224,7 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
*/
if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
!sigonstack(tf->tf_sp) && (psp->ps_sigonstack & sigmask(sig)))
- scp = (register_t)p->p_sigstk.ss_sp;
+ scp = round_page((vaddr_t)p->p_sigstk.ss_sp);
else
scp = (tf->tf_sp + 63) & ~63;
diff --git a/sys/arch/hppa/hppa/trap.c b/sys/arch/hppa/hppa/trap.c
index b58f2c9158d..4769647a5d6 100644
--- a/sys/arch/hppa/hppa/trap.c
+++ b/sys/arch/hppa/hppa/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.142 2017/07/22 15:20:11 kettenis Exp $ */
+/* $OpenBSD: trap.c,v 1.143 2018/04/12 17:13:43 deraadt Exp $ */
/*
* Copyright (c) 1998-2004 Michael Shalayeff
@@ -213,9 +213,29 @@ trap(int type, struct trapframe *frame)
mtctl(frame->tf_eiem, CR_EIEM);
}
- if (type & T_USER)
+ if (type & T_USER) {
+ vaddr_t sp;
+
refreshcreds(p);
+ //sp = frame->tf_sp;
+ sp = PROC_STACK(p);
+ if (p->p_vmspace->vm_map.serial != p->p_spserial ||
+ p->p_spstart == 0 || sp < p->p_spstart ||
+ sp >= p->p_spend) {
+ KERNEL_LOCK();
+ if (!uvm_map_check_stack_range(p, sp)) {
+ printf("trap [%s]%d/%d type %d: sp %lx not inside %lx-%lx\n",
+ p->p_p->ps_comm, p->p_p->ps_pid, p->p_tid,
+ type & ! ~T_USER, sp, p->p_spstart, p->p_spend);
+ sv.sival_ptr = (void *)PROC_PC(p);
+ trapsignal(p, SIGSEGV, type & ~T_USER,
+ SEGV_ACCERR, sv);
+ }
+ KERNEL_UNLOCK();
+ }
+ }
+
switch (type) {
case T_NONEXIST:
case T_NONEXIST | T_USER:
diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c
index 14f8a48bd8e..6f7c5d4fca1 100644
--- a/sys/arch/i386/i386/machdep.c
+++ b/sys/arch/i386/i386/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.615 2018/04/11 15:44:08 bluhm Exp $ */
+/* $OpenBSD: machdep.c,v 1.616 2018/04/12 17:13:43 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */
/*-
@@ -2401,7 +2401,7 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
*/
if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
!sigonstack(tf->tf_esp) && (psp->ps_sigonstack & sigmask(sig)))
- sp = (long)p->p_sigstk.ss_sp + p->p_sigstk.ss_size;
+ sp = trunc_page((vaddr_t)p->p_sigstk.ss_sp + p->p_sigstk.ss_size);
else
sp = tf->tf_esp;
diff --git a/sys/arch/i386/i386/trap.c b/sys/arch/i386/i386/trap.c
index c801739197b..046cbc9e274 100644
--- a/sys/arch/i386/i386/trap.c
+++ b/sys/arch/i386/i386/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.136 2017/10/04 17:41:01 deraadt Exp $ */
+/* $OpenBSD: trap.c,v 1.137 2018/04/12 17:13:43 deraadt Exp $ */
/* $NetBSD: trap.c,v 1.95 1996/05/05 06:50:02 mycroft Exp $ */
/*-
@@ -154,9 +154,27 @@ trap(struct trapframe *frame)
#endif
if (!KERNELMODE(frame->tf_cs, frame->tf_eflags)) {
+ vaddr_t sp;
+
type |= T_USER;
p->p_md.md_regs = frame;
refreshcreds(p);
+
+ sp = PROC_STACK(p);
+ if (p->p_vmspace->vm_map.serial != p->p_spserial ||
+ p->p_spstart == 0 || sp < p->p_spstart ||
+ sp >= p->p_spend) {
+ KERNEL_LOCK();
+ if (!uvm_map_check_stack_range(p, sp)) {
+ printf("trap [%s]%d/%d type %d: sp %lx not inside %lx-%lx\n",
+ p->p_p->ps_comm, p->p_p->ps_pid, p->p_tid,
+ (int)frame->tf_trapno, sp, p->p_spstart, p->p_spend);
+ sv.sival_ptr = (void *)PROC_PC(p);
+ trapsignal(p, SIGSEGV, type & ~T_USER,
+ SEGV_ACCERR, sv);
+ }
+ KERNEL_UNLOCK();
+ }
}
switch (type) {
diff --git a/sys/arch/m88k/m88k/sig_machdep.c b/sys/arch/m88k/m88k/sig_machdep.c
index 534b173b712..7b9766ab7b5 100644
--- a/sys/arch/m88k/m88k/sig_machdep.c
+++ b/sys/arch/m88k/m88k/sig_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sig_machdep.c,v 1.27 2016/10/08 23:31:57 guenther Exp $ */
+/* $OpenBSD: sig_machdep.c,v 1.28 2018/04/12 17:13:43 deraadt Exp $ */
/*
* Copyright (c) 2014 Miodrag Vallat.
*
@@ -128,7 +128,8 @@ sendsig(sig_t catcher, int sig, int mask, unsigned long code, int type,
if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
!sigonstack(tf->tf_r[31]) && (psp->ps_sigonstack & sigmask(sig))) {
addr = local_stack_frame(tf,
- (vaddr_t)p->p_sigstk.ss_sp + p->p_sigstk.ss_size, fsize);
+ trunc_page((vaddr_t)p->p_sigstk.ss_sp + p->p_sigstk.ss_size),
+ fsize);
} else
addr = local_stack_frame(tf, tf->tf_r[31], fsize);
diff --git a/sys/arch/macppc/macppc/machdep.c b/sys/arch/macppc/macppc/machdep.c
index 6aaae3cb1cb..1470b2a78df 100644
--- a/sys/arch/macppc/macppc/machdep.c
+++ b/sys/arch/macppc/macppc/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.182 2017/12/11 05:27:40 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.183 2018/04/12 17:13:43 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */
/*
@@ -461,8 +461,8 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
!sigonstack(tf->fixreg[1]) &&
(psp->ps_sigonstack & sigmask(sig)))
- fp = (struct sigframe *)(p->p_sigstk.ss_sp
- + p->p_sigstk.ss_size);
+ fp = (struct sigframe *)
+ trunc_page((vaddr_t)p->p_sigstk.ss_sp + p->p_sigstk.ss_size);
else
fp = (struct sigframe *)tf->fixreg[1];
diff --git a/sys/arch/mips64/mips64/sendsig.c b/sys/arch/mips64/mips64/sendsig.c
index 3e6ebfd02e8..38b8324aa22 100644
--- a/sys/arch/mips64/mips64/sendsig.c
+++ b/sys/arch/mips64/mips64/sendsig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sendsig.c,v 1.27 2016/05/21 00:56:43 deraadt Exp $ */
+/* $OpenBSD: sendsig.c,v 1.28 2018/04/12 17:13:43 deraadt Exp $ */
/*
* Copyright (c) 1990 The Regents of the University of California.
@@ -121,8 +121,9 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
fsize -= sizeof(siginfo_t);
if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
!sigonstack(regs->sp) && (psp->ps_sigonstack & sigmask(sig)))
- fp = (struct sigframe *)(p->p_sigstk.ss_sp +
- p->p_sigstk.ss_size - fsize);
+ fp = (struct sigframe *)
+ (trunc_page((vaddr_t)p->p_sigstk.ss_sp + p->p_sigstk.ss_size)
+ - fsize);
else
fp = (struct sigframe *)(regs->sp - fsize);
/*
diff --git a/sys/arch/mips64/mips64/trap.c b/sys/arch/mips64/mips64/trap.c
index 75f6c1360cd..4ffa78973cf 100644
--- a/sys/arch/mips64/mips64/trap.c
+++ b/sys/arch/mips64/mips64/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.130 2017/09/02 15:56:29 visa Exp $ */
+/* $OpenBSD: trap.c,v 1.131 2018/04/12 17:13:43 deraadt Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -251,9 +251,30 @@ trap(struct trapframe *trapframe)
}
#endif
- if (type & T_USER)
+ if (type & T_USER) {
+ vaddr_t sp;
+
refreshcreds(p);
+ sp = trapframe->sp;
+ if (p->p_vmspace->vm_map.serial != p->p_spserial ||
+ p->p_spstart == 0 || sp < p->p_spstart ||
+ sp >= p->p_spend) {
+ KERNEL_LOCK();
+ if (!uvm_map_check_stack_range(p, sp)) {
+ union sigval sv;
+
+ printf("trap [%s]%d/%d type %d: sp %lx not inside %lx-%lx\n",
+ p->p_p->ps_comm, p->p_p->ps_pid, p->p_tid, type,
+ sp, p->p_spstart, p->p_spend);
+
+ sv.sival_ptr = (void *)trapframe->pc;
+ trapsignal(p, SIGSEGV, 0, SEGV_ACCERR, sv);
+ }
+ KERNEL_UNLOCK();
+ }
+ }
+
itsa(trapframe, ci, p, type);
if (type & T_USER)
diff --git a/sys/arch/powerpc/powerpc/trap.c b/sys/arch/powerpc/powerpc/trap.c
index 5974f88b802..564cdf2f640 100644
--- a/sys/arch/powerpc/powerpc/trap.c
+++ b/sys/arch/powerpc/powerpc/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.106 2016/12/20 12:08:01 jsg Exp $ */
+/* $OpenBSD: trap.c,v 1.107 2018/04/12 17:13:44 deraadt Exp $ */
/* $NetBSD: trap.c,v 1.3 1996/10/13 03:31:37 christos Exp $ */
/*
@@ -234,8 +234,26 @@ trap(struct trapframe *frame)
db_expr_t offset;
if (frame->srr1 & PSL_PR) {
+ vaddr_t sp;
+
type |= EXC_USER;
refreshcreds(p);
+
+ sp = PROC_STACK(p);
+ if (p->p_vmspace->vm_map.serial != p->p_spserial ||
+ p->p_spstart == 0 || sp < p->p_spstart ||
+ sp >= p->p_spend) {
+ KERNEL_LOCK();
+ if (!uvm_map_check_stack_range(p, sp)) {
+ printf("trap [%s]%d/%d type %d: sp %lx not inside %lx-%lx\n",
+ p->p_p->ps_comm, p->p_p->ps_pid, p->p_tid,
+ type, sp, p->p_spstart, p->p_spend);
+ sv.sival_ptr = (void *)PROC_PC(p);
+ trapsignal(p, SIGSEGV, type, SEGV_ACCERR, sv);
+ }
+
+ KERNEL_UNLOCK();
+ }
}
switch (type) {
diff --git a/sys/arch/sh/sh/sh_machdep.c b/sys/arch/sh/sh/sh_machdep.c
index ec1c393a77d..218db7f2e75 100644
--- a/sys/arch/sh/sh/sh_machdep.c
+++ b/sys/arch/sh/sh/sh_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sh_machdep.c,v 1.46 2016/05/21 00:56:44 deraadt Exp $ */
+/* $OpenBSD: sh_machdep.c,v 1.47 2018/04/12 17:13:44 deraadt Exp $ */
/* $NetBSD: sh3_machdep.c,v 1.59 2006/03/04 01:13:36 uwe Exp $ */
/*
@@ -460,8 +460,8 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
!sigonstack(p->p_md.md_regs->tf_r15) &&
(psp->ps_sigonstack & sigmask(sig)))
- fp = (struct sigframe *)((vaddr_t)p->p_sigstk.ss_sp +
- p->p_sigstk.ss_size);
+ fp = (struct sigframe *)
+ trunc_page((vaddr_t)p->p_sigstk.ss_sp + p->p_sigstk.ss_size);
else
fp = (void *)p->p_md.md_regs->tf_r15;
--fp;
diff --git a/sys/arch/socppc/socppc/machdep.c b/sys/arch/socppc/socppc/machdep.c
index bf0b0228074..830a2e24307 100644
--- a/sys/arch/socppc/socppc/machdep.c
+++ b/sys/arch/socppc/socppc/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.73 2017/12/11 05:27:40 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.74 2018/04/12 17:13:44 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */
/*
@@ -487,8 +487,8 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
!sigonstack(tf->fixreg[1]) &&
(psp->ps_sigonstack & sigmask(sig)))
- fp = (struct sigframe *)(p->p_sigstk.ss_sp
- + p->p_sigstk.ss_size);
+ fp = (struct sigframe *)
+ trunc_page(vaddr_t)p->p_sigstk.ss_sp + pp->p_sigstk.ss_size);
else
fp = (struct sigframe *)tf->fixreg[1];
diff --git a/sys/arch/sparc64/sparc64/machdep.c b/sys/arch/sparc64/sparc64/machdep.c
index 153633b01fb..1aa11f69ac7 100644
--- a/sys/arch/sparc64/sparc64/machdep.c
+++ b/sys/arch/sparc64/sparc64/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.187 2017/12/30 20:46:59 guenther Exp $ */
+/* $OpenBSD: machdep.c,v 1.188 2018/04/12 17:13:44 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.108 2001/07/24 19:30:14 eeh Exp $ */
/*-
@@ -432,8 +432,8 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
*/
if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
!sigonstack(oldsp) && (psp->ps_sigonstack & sigmask(sig)))
- fp = (struct sigframe *)((caddr_t)p->p_sigstk.ss_sp +
- p->p_sigstk.ss_size);
+ fp = (struct sigframe *)
+ trunc_page((vaddr_t)p->p_sigstk.ss_sp + p->p_sigstk.ss_size);
else
fp = (struct sigframe *)oldsp;
/* Allocate an aligned sigframe */
diff --git a/sys/arch/sparc64/sparc64/trap.c b/sys/arch/sparc64/sparc64/trap.c
index 55c8bd6213d..7cc1973a107 100644
--- a/sys/arch/sparc64/sparc64/trap.c
+++ b/sys/arch/sparc64/sparc64/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.98 2017/07/22 15:17:49 kettenis Exp $ */
+/* $OpenBSD: trap.c,v 1.99 2018/04/12 17:13:44 deraadt Exp $ */
/* $NetBSD: trap.c,v 1.73 2001/08/09 01:03:01 eeh Exp $ */
/*
@@ -348,6 +348,7 @@ trap(struct trapframe64 *tf, unsigned type, vaddr_t pc, long tstate)
struct proc *p;
struct pcb *pcb;
int pstate = (tstate>>TSTATE_PSTATE_SHIFT);
+ vaddr_t sp;
u_int64_t s;
int64_t n;
union sigval sv;
@@ -427,6 +428,22 @@ trap(struct trapframe64 *tf, unsigned type, vaddr_t pc, long tstate)
p->p_md.md_tf = tf; /* for ptrace/signals */
refreshcreds(p);
+ sp = PROC_STACK(p);
+ if (p->p_vmspace->vm_map.serial != p->p_spserial ||
+ p->p_spstart == 0 || sp < p->p_spstart ||
+ sp >= p->p_spend) {
+ KERNEL_LOCK();
+ if (!uvm_map_check_stack_range(p, sp)) {
+ printf("trap [%s]%d/%d type %d: sp %lx not inside %lx-%lx\n",
+ p->p_p->ps_comm, p->p_p->ps_pid, p->p_tid,
+ (int)type, sp, p->p_spstart, p->p_spend);
+ sv.sival_ptr = (void *)PROC_PC(p);
+ trapsignal(p, SIGSEGV, type, SEGV_ACCERR, sv);
+ }
+
+ KERNEL_UNLOCK();
+ }
+
switch (type) {
default: