diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2014-04-17 14:52:51 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2014-04-17 14:52:51 +0000 |
commit | dfd85523c97869c8a8d2e7a12807122bb1b31379 (patch) | |
tree | 5f36099985943d477c405f4615c66055cd482278 /sys | |
parent | 9fd60ed2d04de20db973eeea834aada64cd82311 (diff) |
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@
Diffstat (limited to 'sys')
-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); } |