summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authordeischen <deischen@FreeBSD.org>2007-12-06 06:04:01 +0000
committerdeischen <deischen@FreeBSD.org>2007-12-06 06:04:01 +0000
commit32cdd5f202579af2492069e0916ed60a6aa664c3 (patch)
tree9b67c8f99c5e2e786796a9e1fe1daa2c859b154c /lib
parent7b59d90c86943d65f82a939c2575f05e65260596 (diff)
downloadFreeBSD-src-32cdd5f202579af2492069e0916ed60a6aa664c3.zip
FreeBSD-src-32cdd5f202579af2492069e0916ed60a6aa664c3.tar.gz
Set the tcb (thread control block) in the child process after a fork.
This protects against a race with an upcall in the parent during the fork which can clobber the parent's tcb before the vm space is copied in the child. The child then gets a corrupted tcb that is either null or that points to another thread that doesn't exist in the child (after a fork, only the fork()ing thread exists in the child). Reported by: Arno J. Klaassen (arno at heho / snv / jussieu / fr)
Diffstat (limited to 'lib')
-rw-r--r--lib/libkse/thread/thr_kern.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/lib/libkse/thread/thr_kern.c b/lib/libkse/thread/thr_kern.c
index d28636c..6563ca7 100644
--- a/lib/libkse/thread/thr_kern.c
+++ b/lib/libkse/thread/thr_kern.c
@@ -361,6 +361,19 @@ _kse_single_thread(struct pthread *curthread)
curthread->kse->k_kcb->kcb_kmbx.km_curthread = NULL;
curthread->attr.flags |= PTHREAD_SCOPE_SYSTEM;
+ /*
+ * After a fork, it is possible that an upcall occurs in
+ * the parent KSE that fork()'d before the child process
+ * is fully created and before its vm space is copied.
+ * During the upcall, the tcb is set to null or to another
+ * thread, and this is what gets copied in the child process
+ * when the vm space is cloned sometime after the upcall
+ * occurs. Note that we shouldn't have to set the kcb, but
+ * we do it for completeness.
+ */
+ _kcb_set(curthread->kse->k_kcb);
+ _tcb_set(curthread->kse->k_kcb, curthread->tcb);
+
/* After a fork(), there child should have no pending signals. */
sigemptyset(&curthread->sigpend);
OpenPOWER on IntegriCloud