summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_fork.c
diff options
context:
space:
mode:
authoraaron <aaron@openbsd.org>2005-11-02 20:03:16 +0000
committeraaron <aaron@openbsd.org>2005-11-02 20:03:16 +0000
commit6c7e538ed9432c1bb0a78a78fa3775981406ad70 (patch)
tree8dfc64d2e79e649b05c8dbadb3de62dd543d0b00 /sys/kern/kern_fork.c
parentfix inspired by pr#4590 (diff)
downloadwireguard-openbsd-6c7e538ed9432c1bb0a78a78fa3775981406ad70.tar.xz
wireguard-openbsd-6c7e538ed9432c1bb0a78a78fa3775981406ad70.zip
Avoid a theoretical race condition.
In fork1(), setup the p_{prof,virt}_to timeouts _before_ putting the process on the runqueue. Since SCHED_UNLOCK() can cause pre-emption, it is possible (with the old code) for the newly created process to run and become curproc before the timeouts were set. If itimers are set early, and you're unlucky, hardclock() might fire at this time and attempt timeout_add() on the unset timeouts, leading to "panic: timeout_add: not initialized". deraadt@, miod@ ok
Diffstat (limited to 'sys/kern/kern_fork.c')
-rw-r--r--sys/kern/kern_fork.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 45d51df536d..62e68a3d51c 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_fork.c,v 1.77 2005/09/14 20:55:59 kettenis Exp $ */
+/* $OpenBSD: kern_fork.c,v 1.78 2005/11/02 20:03:16 aaron Exp $ */
/* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */
/*
@@ -375,6 +375,9 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize,
systrace_fork(p1, p2);
#endif
+ timeout_set(&p2->p_stats->p_virt_to, virttimer_trampoline, p2);
+ timeout_set(&p2->p_stats->p_prof_to, proftimer_trampoline, p2);
+
/*
* Make child runnable, set start time, and add to run queue.
*/
@@ -385,9 +388,6 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize,
setrunqueue(p2);
SCHED_UNLOCK(s);
- timeout_set(&p2->p_stats->p_virt_to, virttimer_trampoline, p2);
- timeout_set(&p2->p_stats->p_prof_to, proftimer_trampoline, p2);
-
/*
* Now can be swapped.
*/