summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Mooney <pmooney@pfmooney.com>2016-05-09 20:10:32 +0000
committerPatrick Mooney <pmooney@pfmooney.com>2016-05-09 21:20:02 +0000
commit27a01456dc8f0848242e768b7ff8c6e8d057b160 (patch)
tree16c738f4be0c9b02f6ec157e4ba7423900922a2a
parent8f9f8986fdd3d337ed7d2b6950d4362d82cbae06 (diff)
downloadillumos-joyent-27a01456dc8f0848242e768b7ff8c6e8d057b160.tar.gz
OS-5392 lxbrand thread race in clone(CLONE_VFORK)
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/clone.c30
1 files changed, 15 insertions, 15 deletions
diff --git a/usr/src/lib/brand/lx/lx_brand/common/clone.c b/usr/src/lib/brand/lx/lx_brand/common/clone.c
index f6cc2fff31..59037a38b8 100644
--- a/usr/src/lib/brand/lx/lx_brand/common/clone.c
+++ b/usr/src/lib/brand/lx/lx_brand/common/clone.c
@@ -425,16 +425,15 @@ lx_clone(uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4, uintptr_t p5)
* path here.
*/
if (rval != 0) {
- if (!IS_VFORK(flags) || rval < 0) {
- /*
- * Run the stack management postfork handler in
- * the parent. If this was a vfork(2), we only
- * run it in the parent if the fork operation
- * failed; the vfork(2) child has already run
- * it for our address space.
- */
- lx_stack_postfork();
- }
+ /*
+ * Run the stack management postfork handler in the
+ * parent. In the CLONE_VFORK case, where it only
+ * needs to be performed once due to the shared address
+ * space, it is critical that this step is performed in
+ * the parent and not the child. The latter can result
+ * in un-woken threads blocked on lx_stack_list_lock.
+ */
+ lx_stack_postfork();
/*
* Since we've already forked, we can't do much if
@@ -464,13 +463,14 @@ lx_clone(uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4, uintptr_t p5)
* process.
*/
- /*
- * Run the stack management postfork handler in the child.
- */
- lx_stack_postfork();
-
if (!IS_VFORK(flags)) {
/*
+ * For non-vfork children run the stack management
+ * postfork handler.
+ */
+ lx_stack_postfork();
+
+ /*
* We must free the stacks and thread-specific data
* objects for every thread except the one duplicated
* from the parent by forkx().