summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_fork.c
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2006-03-15 23:24:14 +0000
committerdavidxu <davidxu@FreeBSD.org>2006-03-15 23:24:14 +0000
commit7e196fdd6e6e603b0fa194e187cb4884cd865f6d (patch)
treef30a8458f1ec1fd1754c0ad912e7bd3409d03c51 /sys/kern/kern_fork.c
parentabccf6f3e27b07055242c9c80666260c85d09e6a (diff)
downloadFreeBSD-src-7e196fdd6e6e603b0fa194e187cb4884cd865f6d.zip
FreeBSD-src-7e196fdd6e6e603b0fa194e187cb4884cd865f6d.tar.gz
Fix a race between file operations and rfork(RFCFDG) by parking
all other threads at user boundary, the race can crash kernel under stress testing. Reviewed by: jhb MFC after: 3 days
Diffstat (limited to 'sys/kern/kern_fork.c')
-rw-r--r--sys/kern/kern_fork.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index dfbd315..c6724b7 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -220,6 +220,16 @@ fork1(td, flags, pages, procp)
* certain parts of a process from itself.
*/
if ((flags & RFPROC) == 0) {
+ if ((p1->p_flag & P_HADTHREADS) &&
+ (flags & (RFCFDG | RFFDG))) {
+ PROC_LOCK(p1);
+ if (thread_single(SINGLE_BOUNDARY)) {
+ PROC_UNLOCK(p1);
+ return (ERESTART);
+ }
+ PROC_UNLOCK(p1);
+ }
+
vm_forkproc(td, NULL, NULL, flags);
/*
@@ -237,6 +247,13 @@ fork1(td, flags, pages, procp)
*/
if (flags & RFFDG)
fdunshare(p1, td);
+
+ if ((p1->p_flag & P_HADTHREADS) &&
+ (flags & (RFCFDG | RFFDG))) {
+ PROC_LOCK(p1);
+ thread_single_end();
+ PROC_UNLOCK(p1);
+ }
*procp = NULL;
return (0);
}
OpenPOWER on IntegriCloud