From f7d6afc696c4845c9023b7ba99ebce21c77c71c5 Mon Sep 17 00:00:00 2001 From: David Greenman Date: Sun, 11 Sep 1994 11:26:18 +0000 Subject: [PATCH] Be more careful about dereferencing curproc, p_vmspace, and curpcb, otherwise the machine will overflow the stack in a recursive fault loop (causing the machine to spontaneously reboot because of the stack fault that ultimately happens). Submitted by: Inspired by Bruce Evans, but this change is different than what he suggested. --- sys/amd64/amd64/trap.c | 32 ++++++++++++++++++++------------ sys/i386/i386/trap.c | 32 ++++++++++++++++++++------------ sys/kern/subr_trap.c | 32 ++++++++++++++++++++------------ 3 files changed, 60 insertions(+), 36 deletions(-) diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index bc984c6f9331..49b4ffd69711 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.32 1994/08/28 16:16:33 bde Exp $ + * $Id: trap.c,v 1.33 1994/09/08 11:48:52 bde Exp $ */ /* @@ -337,7 +337,7 @@ trap_pfault(frame, usermode) int usermode; { vm_offset_t va; - struct vmspace *vm; + struct vmspace *vm = NULL; vm_map_t map = 0; int rv = 0, oldflags; vm_prot_t ftype; @@ -348,18 +348,26 @@ trap_pfault(frame, usermode) eva = rcr2(); va = trunc_page((vm_offset_t)eva); - /* - * Don't allow user-mode faults in kernel address space - */ - if (usermode && (va >= KERNBASE)) { - goto nogo; - } + if (va >= KERNBASE) { + /* + * Don't allow user-mode faults in kernel address space. + */ + if (usermode) + goto nogo; - if ((p == 0) || (va >= KERNBASE)) { - vm = 0; map = kernel_map; } else { - vm = p->p_vmspace; + /* + * This is a fault on non-kernel virtual memory. + * vm is initialized above to NULL. If curproc is NULL + * or curproc->p_vmspace is NULL the fault is fatal. + */ + if (p != NULL) + vm = p->p_vmspace; + + if (vm == NULL) + goto nogo; + map = &vm->vm_map; } @@ -433,7 +441,7 @@ trap_pfault(frame, usermode) return (0); nogo: if (!usermode) { - if (curpcb->pcb_onfault) { + if (curpcb && curpcb->pcb_onfault) { frame->tf_eip = (int)curpcb->pcb_onfault; return (0); } diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index bc984c6f9331..49b4ffd69711 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.32 1994/08/28 16:16:33 bde Exp $ + * $Id: trap.c,v 1.33 1994/09/08 11:48:52 bde Exp $ */ /* @@ -337,7 +337,7 @@ trap_pfault(frame, usermode) int usermode; { vm_offset_t va; - struct vmspace *vm; + struct vmspace *vm = NULL; vm_map_t map = 0; int rv = 0, oldflags; vm_prot_t ftype; @@ -348,18 +348,26 @@ trap_pfault(frame, usermode) eva = rcr2(); va = trunc_page((vm_offset_t)eva); - /* - * Don't allow user-mode faults in kernel address space - */ - if (usermode && (va >= KERNBASE)) { - goto nogo; - } + if (va >= KERNBASE) { + /* + * Don't allow user-mode faults in kernel address space. + */ + if (usermode) + goto nogo; - if ((p == 0) || (va >= KERNBASE)) { - vm = 0; map = kernel_map; } else { - vm = p->p_vmspace; + /* + * This is a fault on non-kernel virtual memory. + * vm is initialized above to NULL. If curproc is NULL + * or curproc->p_vmspace is NULL the fault is fatal. + */ + if (p != NULL) + vm = p->p_vmspace; + + if (vm == NULL) + goto nogo; + map = &vm->vm_map; } @@ -433,7 +441,7 @@ trap_pfault(frame, usermode) return (0); nogo: if (!usermode) { - if (curpcb->pcb_onfault) { + if (curpcb && curpcb->pcb_onfault) { frame->tf_eip = (int)curpcb->pcb_onfault; return (0); } diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index bc984c6f9331..49b4ffd69711 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.32 1994/08/28 16:16:33 bde Exp $ + * $Id: trap.c,v 1.33 1994/09/08 11:48:52 bde Exp $ */ /* @@ -337,7 +337,7 @@ trap_pfault(frame, usermode) int usermode; { vm_offset_t va; - struct vmspace *vm; + struct vmspace *vm = NULL; vm_map_t map = 0; int rv = 0, oldflags; vm_prot_t ftype; @@ -348,18 +348,26 @@ trap_pfault(frame, usermode) eva = rcr2(); va = trunc_page((vm_offset_t)eva); - /* - * Don't allow user-mode faults in kernel address space - */ - if (usermode && (va >= KERNBASE)) { - goto nogo; - } + if (va >= KERNBASE) { + /* + * Don't allow user-mode faults in kernel address space. + */ + if (usermode) + goto nogo; - if ((p == 0) || (va >= KERNBASE)) { - vm = 0; map = kernel_map; } else { - vm = p->p_vmspace; + /* + * This is a fault on non-kernel virtual memory. + * vm is initialized above to NULL. If curproc is NULL + * or curproc->p_vmspace is NULL the fault is fatal. + */ + if (p != NULL) + vm = p->p_vmspace; + + if (vm == NULL) + goto nogo; + map = &vm->vm_map; } @@ -433,7 +441,7 @@ trap_pfault(frame, usermode) return (0); nogo: if (!usermode) { - if (curpcb->pcb_onfault) { + if (curpcb && curpcb->pcb_onfault) { frame->tf_eip = (int)curpcb->pcb_onfault; return (0); }