summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2020-07-06 21:41:57 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2020-07-06 21:41:57 +0000
commit4e526a6aa77e6abcee3f8ea6ff3eab4e57605701 (patch)
tree813a28608d0736413ca426ea31ffbb47338f58e2
parentefa5c8fd0130d682124e5b29408493892e55174b (diff)
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)
-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);
}