summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2008-10-31 10:38:30 +0000
committerkib <kib@FreeBSD.org>2008-10-31 10:38:30 +0000
commit288874a97d33df16756a3874686562313e150f80 (patch)
treefe6fa4d3bbb1630a25ba4365c47834c54444096d /sys/compat
parente200f7c9b6fc508b9497ebb976b2d97cdc95b524 (diff)
downloadFreeBSD-src-288874a97d33df16756a3874686562313e150f80.zip
FreeBSD-src-288874a97d33df16756a3874686562313e150f80.tar.gz
The code in linux_proc_exit() contains a race when multiple linux based
processes exits at the same time. The linux_emuldata structure is freed but p->p_emuldata is left as a dangling pointer to the just freed memory. The check for W_EXIT in the loop scanning the child processes isn't safe since the state of the child process can change right afterwards. Lock the process and check the W_EXIT before delivering signal. Submitted by: tegge Reviewed by: davidxu MFC after: 1 week
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/linux/linux_emul.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/sys/compat/linux/linux_emul.c b/sys/compat/linux/linux_emul.c
index 16e6033..1ca48a3 100644
--- a/sys/compat/linux/linux_emul.c
+++ b/sys/compat/linux/linux_emul.c
@@ -235,11 +235,11 @@ linux_proc_exit(void *arg __unused, struct proc *p)
continue;
em = em_find(q, EMUL_DOLOCK);
KASSERT(em != NULL, ("linux_reparent: emuldata not found: %i\n", q->p_pid));
- if (em->pdeath_signal != 0) {
- PROC_LOCK(q);
+ PROC_LOCK(q);
+ if ((q->p_flag & P_WEXIT) == 0 && em->pdeath_signal != 0) {
psignal(q, em->pdeath_signal);
- PROC_UNLOCK(q);
}
+ PROC_UNLOCK(q);
EMUL_UNLOCK(&emul_lock);
}
sx_xunlock(&proctree_lock);
OpenPOWER on IntegriCloud