diff options
author | 2014-04-17 14:52:50 +0000 | |
---|---|---|
committer | 2014-04-17 14:52:50 +0000 | |
commit | 665e07d6cfe372a9cb7c136fce813ece1d8a4be8 (patch) | |
tree | c17e5ed747b43b8e5938517045eae51862658791 | |
parent | remove special case for uucp entries. (diff) | |
download | wireguard-openbsd-665e07d6cfe372a9cb7c136fce813ece1d8a4be8.tar.xz wireguard-openbsd-665e07d6cfe372a9cb7c136fce813ece1d8a4be8.zip |
Make sure the original thread is blocked until any other threads are
completely detached from the process before letting it exit, so that
sleeping in systrace_exit() doesn't reorder them and lead to a panic.
Panic reported by Fabian Raetz (fabian.raetz (at) gmail.com)
ok tedu@
-rw-r--r-- | sys/kern/kern_exit.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index d559c72fae0..9f16c28216a 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exit.c,v 1.138 2014/03/30 21:54:48 guenther Exp $ */ +/* $OpenBSD: kern_exit.c,v 1.139 2014/04/17 14:52:50 guenther Exp $ */ /* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */ /* @@ -158,12 +158,10 @@ exit1(struct proc *p, int rv, int flags) TAILQ_REMOVE(&pr->ps_threads, p, p_thr_link); if ((p->p_flag & P_THREAD) == 0) { /* main thread gotta wait because it has the pid, et al */ - while (!TAILQ_EMPTY(&pr->ps_threads)) + while (pr->ps_refcnt > 1) tsleep(&pr->ps_threads, PUSER, "thrdeath", 0); if (pr->ps_flags & PS_PROFIL) stopprofclock(pr); - } else if (TAILQ_EMPTY(&pr->ps_threads)) { - wakeup(&pr->ps_threads); } rup = pr->ps_ru; @@ -356,7 +354,8 @@ exit1(struct proc *p, int rv, int flags) /* just a thread? detach it from its process */ if (p->p_flag & P_THREAD) { /* scheduler_wait_hook(pr->ps_mainproc, p); XXX */ - --pr->ps_refcnt; + if (--pr->ps_refcnt == 1) + wakeup(&pr->ps_threads); KASSERT(pr->ps_refcnt > 0); } |