summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2020-07-06 21:41:56 +0000
committerkettenis <kettenis@openbsd.org>2020-07-06 21:41:56 +0000
commit6a3d01b2d6d10414d3e08ac548347e782c1381df (patch)
tree228a95f68b6a48acf503a775a7c8ac3cef18d08d /sys
parentProtect the whole pipex(4) layer by NET_LOCK(). pipex(4) was (diff)
downloadwireguard-openbsd-6a3d01b2d6d10414d3e08ac548347e782c1381df.tar.xz
wireguard-openbsd-6a3d01b2d6d10414d3e08ac548347e782c1381df.zip
Wire down the timekeep page. If we don't do this, the pagedaemon may
page it out and bad things will happen when we try to page it back in from within the clock interrupt handler. While there, make sure we set timekeep_object back to NULL if we fail to make the timekeep page into kernel space. ok deraadt@ (who had a very similar diff)
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_exec.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index 863686de932..24d0d97a3be 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_exec.c,v 1.214 2020/07/06 13:33:09 pirofti Exp $ */
+/* $OpenBSD: kern_exec.c,v 1.215 2020/07/06 21:41:56 kettenis Exp $ */
/* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */
/*-
@@ -881,7 +881,7 @@ exec_sigcode_map(struct process *pr, struct emul *e)
int
exec_timekeep_map(struct process *pr)
{
- size_t timekeep_sz = sizeof(struct timekeep);
+ size_t timekeep_sz = round_page(sizeof(struct timekeep));
/*
* Similar to the sigcode object, except that there is a single
@@ -893,10 +893,18 @@ exec_timekeep_map(struct process *pr)
timekeep_object = uao_create(timekeep_sz, 0);
uao_reference(timekeep_object);
- if (uvm_map(kernel_map, &va, round_page(timekeep_sz), timekeep_object,
+ if (uvm_map(kernel_map, &va, timekeep_sz, timekeep_object,
0, 0, UVM_MAPFLAG(PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
MAP_INHERIT_SHARE, MADV_RANDOM, 0))) {
uao_detach(timekeep_object);
+ timekeep_object = NULL;
+ return (ENOMEM);
+ }
+ if (uvm_fault_wire(kernel_map, va, va + timekeep_sz,
+ PROT_READ | PROT_WRITE)) {
+ uvm_unmap(kernel_map, va, va + timekeep_sz);
+ uao_detach(timekeep_object);
+ timekeep_object = NULL;
return (ENOMEM);
}