summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2020-09-14 12:51:28 +0000
committerkettenis <kettenis@openbsd.org>2020-09-14 12:51:28 +0000
commit0619dcec08ecca28766f760d881ad9d8cf8c3706 (patch)
tree1deac2febfe7f3f31e947f2ed2cae0885fb3ba94
parentAdd initial man page for new x509_verify chain validator (diff)
downloadwireguard-openbsd-0619dcec08ecca28766f760d881ad9d8cf8c3706.tar.xz
wireguard-openbsd-0619dcec08ecca28766f760d881ad9d8cf8c3706.zip
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 mpi@, semarie@, deraadt@
-rw-r--r--sys/arch/amd64/amd64/trap.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c
index 4a4c6275aa7..c401042f03e 100644
--- a/sys/arch/amd64/amd64/trap.c
+++ b/sys/arch/amd64/amd64/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.80 2020/08/19 10:10:57 mpi Exp $ */
+/* $OpenBSD: trap.c,v 1.81 2020/09/14 12:51:28 kettenis Exp $ */
/* $NetBSD: trap.c,v 1.2 2003/05/04 23:51:56 fvdl Exp $ */
/*-
@@ -92,7 +92,7 @@
#include "isa.h"
-int pageflttrap(struct trapframe *, int _usermode);
+int pageflttrap(struct trapframe *, uint64_t, int _usermode);
void kerntrap(struct trapframe *);
void usertrap(struct trapframe *);
void ast(struct trapframe *);
@@ -157,12 +157,11 @@ fault(const char *format, ...)
* if something was so broken that we should panic.
*/
int
-pageflttrap(struct trapframe *frame, int usermode)
+pageflttrap(struct trapframe *frame, uint64_t cr2, int usermode)
{
struct proc *p = curproc;
struct pcb *pcb;
int error;
- uint64_t cr2;
vaddr_t va;
struct vm_map *map;
vm_prot_t ftype;
@@ -172,7 +171,6 @@ pageflttrap(struct trapframe *frame, int usermode)
map = &p->p_vmspace->vm_map;
pcb = &p->p_addr->u_pcb;
- cr2 = rcr2();
va = trunc_page((vaddr_t)cr2);
KERNEL_LOCK();
@@ -280,6 +278,7 @@ void
kerntrap(struct trapframe *frame)
{
int type = (int)frame->tf_trapno;
+ uint64_t cr2 = rcr2();
verify_smap(__func__);
uvmexp.traps++;
@@ -299,7 +298,7 @@ kerntrap(struct trapframe *frame)
/*NOTREACHED*/
case T_PAGEFLT: /* allow page faults in kernel mode */
- if (pageflttrap(frame, 0))
+ if (pageflttrap(frame, cr2, 0))
return;
goto we_re_toast;
@@ -333,6 +332,7 @@ usertrap(struct trapframe *frame)
{
struct proc *p = curproc;
int type = (int)frame->tf_trapno;
+ uint64_t cr2 = rcr2();
union sigval sv;
int sig, code;
@@ -381,7 +381,7 @@ usertrap(struct trapframe *frame)
break;
case T_PAGEFLT: /* page fault */
- if (pageflttrap(frame, 1))
+ if (pageflttrap(frame, cr2, 1))
goto out;
/* FALLTHROUGH */