From 2ca66c1ef5cfe7375661f37bb1c99b02a5ce51ba Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Mon, 19 Feb 2018 00:54:08 +0000 Subject: [PATCH] Fix process exit vs reap race introduced in r329449 The race manifested itself mostly in terms of crashes with "spin lock held too long". Relevant parts of respective code paths: exit: reap: PROC_LOCK(p); PROC_SLOCK(p); p->p_state == PRS_ZOMBIE PROC_UNLOCK(p); PROC_LOCK(p); /* exit work */ if (p->p_state == PRS_ZOMBIE) /* true */ proc_reap() free proc /* more exit work */ PROC_SUNLOCK(p); Thus a still exiting process is reaped. Prior to the change the zombie check was followed by slock/sunlock trip which prevented the problem. Even code prior to this commit has a bug: the proc is still accessed for statistic collection purposes. However, the severity is rather small and the bug may be fixed in a future commit. Reported by: many Tested by: allanjude --- sys/kern/kern_exit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 4ae24bcd705..78ca692a903 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -819,6 +819,8 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options) PROC_LOCK_ASSERT(p, MA_OWNED); KASSERT(p->p_state == PRS_ZOMBIE, ("proc_reap: !PRS_ZOMBIE")); + mtx_spin_wait_unlocked(&p->p_slock); + q = td->td_proc; if (status)