diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2018-06-22 18:50:43 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2018-06-22 18:50:43 +0000 |
commit | 99c3fdf230484eb763f0fcbbabd99f56b03d6f5d (patch) | |
tree | 40d218e3ed4f976aac6678c5c23690392c2e34e6 /sys/arch | |
parent | 7305cd78fbafd66d144f95f3293f0d7ac4a1cfb5 (diff) |
Move up the setting of pcb_tf, refreshcreds(), and stack check so that
we can be sure signals posted from userret() are based on the correct
information
ok kettenis@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/arm/arm/fault.c | 54 |
1 files changed, 26 insertions, 28 deletions
diff --git a/sys/arch/arm/arm/fault.c b/sys/arch/arm/arm/fault.c index 8fc4836d47c..2661783217c 100644 --- a/sys/arch/arm/arm/fault.c +++ b/sys/arch/arm/arm/fault.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fault.c,v 1.34 2018/06/03 18:58:11 kettenis Exp $ */ +/* $OpenBSD: fault.c,v 1.35 2018/06/22 18:50:42 guenther Exp $ */ /* $NetBSD: fault.c,v 1.46 2004/01/21 15:39:21 skrll Exp $ */ /* @@ -205,6 +205,29 @@ data_abort_handler(trapframe_t *tf) /* Grab the current pcb */ pcb = &p->p_addr->u_pcb; + if (user) { + vaddr_t sp; + + 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(); + } + } + /* Invoke the appropriate handler, if necessary */ if (__predict_false(data_aborts[ftyp].func != NULL)) { if ((data_aborts[ftyp].func)(tf, fsr, far, p, &sd)) { @@ -236,29 +259,6 @@ data_abort_handler(trapframe_t *tf) * the MMU. */ - 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(); - } - } - /* * Make sure the Program Counter is sane. We could fall foul of * someone executing Thumb code, in which case the PC might not @@ -476,8 +476,6 @@ dab_align(trapframe_t *tf, u_int fsr, u_int far, struct proc *p, sd->addr = far; sd->trap = fsr; - p->p_addr->u_pcb.pcb_tf = tf; - return (1); } @@ -570,14 +568,14 @@ prefetch_abort_handler(trapframe_t *tf) p = curproc; + p->p_addr->u_pcb.pcb_tf = tf; + /* Invoke access fault handler if appropriate */ if (FAULT_TYPE_V7(fsr) == FAULT_ACCESS_2) { dab_access(tf, fsr, far, p, NULL); goto out; } - p->p_addr->u_pcb.pcb_tf = tf; - /* Ok validate the address, can only execute in USER space */ if (__predict_false(far >= VM_MAXUSER_ADDRESS || (far < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW))) { |