diff options
author | 2020-09-14 12:56:20 +0000 | |
---|---|---|
committer | 2020-09-14 12:56:20 +0000 | |
commit | 9009fc67337b9bbc98f5beeadfb41070c15d55bc (patch) | |
tree | 1e9a7c7362cf9c1049a572abe7c0b09403c769f0 | |
parent | The uvm_map_inentry() check may sleep to grab the lock of the map. (diff) | |
download | wireguard-openbsd-9009fc67337b9bbc98f5beeadfb41070c15d55bc.tar.xz wireguard-openbsd-9009fc67337b9bbc98f5beeadfb41070c15d55bc.zip |
similar to fix by kettenis on amd64:
The uvm_map_inentry() check may sleep to grab the lock of the map.
The fault address is read from cr2 in pageflttrap() which
gets called after this check and if the check sleeps, cr2 is likely to
be clobbered by a page fault in another process.
Fix this by reading cr2 early and pass it to pageflttrap().
ok kettenis
-rw-r--r-- | sys/arch/i386/i386/trap.c | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/sys/arch/i386/i386/trap.c b/sys/arch/i386/i386/trap.c index 747dac01582..04af21910bc 100644 --- a/sys/arch/i386/i386/trap.c +++ b/sys/arch/i386/i386/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.143 2020/08/19 10:10:58 mpi Exp $ */ +/* $OpenBSD: trap.c,v 1.144 2020/09/14 12:56:20 deraadt Exp $ */ /* $NetBSD: trap.c,v 1.95 1996/05/05 06:50:02 mycroft Exp $ */ /*- @@ -119,7 +119,7 @@ trap(struct trapframe *frame) vm_prot_t ftype; union sigval sv; caddr_t onfault; - uint32_t cr2; + uint32_t cr2 = rcr2(); uvmexp.traps++; @@ -135,7 +135,7 @@ trap(struct trapframe *frame) if (trapdebug) { printf("trap %d code %x eip %x cs %x eflags %x cr2 %x cpl %x\n", frame->tf_trapno, frame->tf_err, frame->tf_eip, - frame->tf_cs, frame->tf_eflags, rcr2(), lapic_tpr); + frame->tf_cs, frame->tf_eflags, rcr2, lapic_tpr); printf("curproc %p\n", curproc); } #endif @@ -182,7 +182,7 @@ trap(struct trapframe *frame) printf(" in %s mode\n", (type & T_USER) ? "user" : "supervisor"); printf("trap type %d code %x eip %x cs %x eflags %x cr2 %x cpl %x\n", type, frame->tf_err, frame->tf_eip, frame->tf_cs, - frame->tf_eflags, rcr2(), lapic_tpr); + frame->tf_eflags, rcr2, lapic_tpr); panic("trap type %d, code=%x, pc=%x", type, frame->tf_err, frame->tf_eip); @@ -333,7 +333,6 @@ trap(struct trapframe *frame) goto we_re_toast; pcb = &p->p_addr->u_pcb; - cr2 = rcr2(); KERNEL_LOCK(); /* This will only trigger if SMEP is enabled */ if (cr2 <= VM_MAXUSER_ADDRESS && frame->tf_err & PGEX_I) @@ -353,7 +352,6 @@ trap(struct trapframe *frame) int error; int signal, sicode; - cr2 = rcr2(); KERNEL_LOCK(); faultcommon: vm = p->p_vmspace; @@ -434,11 +432,11 @@ trap(struct trapframe *frame) #endif case T_BPTFLT|T_USER: /* bpt instruction fault */ - sv.sival_int = rcr2(); + sv.sival_int = rcr2; trapsignal(p, SIGTRAP, type &~ T_USER, TRAP_BRKPT, sv); break; case T_TRCTRAP|T_USER: /* trace trap */ - sv.sival_int = rcr2(); + sv.sival_int = rcr2; trapsignal(p, SIGTRAP, type &~ T_USER, TRAP_TRACE, sv); break; |