From 89e86492b36cd15876ebb0ed725fbb4308828a9e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 3 Dec 2015 12:38:19 +0100 Subject: [PATCH] Safely recognize when fork is running from main thread or another pthread * child_info.h (struct child_info): Add member from_main. * fork.cc (frok::child): Check from_main rather than stackaddr. (frok::parent): Set ch.from_main if running in the main thread. Signed-off-by: Corinna Vinschen --- winsup/cygwin/ChangeLog | 6 ++++++ winsup/cygwin/child_info.h | 3 ++- winsup/cygwin/fork.cc | 3 ++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index cffd7c2ca..a24c55ebe 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,9 @@ +2015-12-03 Corinna Vinschen + + * child_info.h (struct child_info): Add member from_main. + * fork.cc (frok::child): Check from_main rather than stackaddr. + (frok::parent): Set ch.from_main if running in the main thread. + 2015-12-02 Corinna Vinschen * child_info.h (CURR_CHILD_INFO_MAGIC): Align to below change. diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h index 1ec612788..ddd5b8bc8 100644 --- a/winsup/cygwin/child_info.h +++ b/winsup/cygwin/child_info.h @@ -39,7 +39,7 @@ enum child_status #define EXEC_MAGIC_SIZE sizeof(child_info) /* Change this value if you get a message indicating that it is out-of-sync. */ -#define CURR_CHILD_INFO_MAGIC 0xc96f5e9U +#define CURR_CHILD_INFO_MAGIC 0x30ea98f6U #define NPROCS 256 @@ -109,6 +109,7 @@ public: void *stackbase; // StackBase of parent thread size_t guardsize; // size of POSIX guard region or (size_t) -1 if // user stack + bool from_main; // true if started from parent's main thread char filler[4]; child_info_fork (); void __reg1 handle_fork (); diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index d4a973eb2..158186781 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -149,7 +149,7 @@ frok::child (volatile char * volatile here) /* If we've played with the stack, stacksize != 0. That means that fork() was invoked from other than the main thread. Make sure that the threadinfo information is properly set up. */ - if (fork_info->stackaddr) + if (!fork_info->from_main) { _main_tls = &_my_tls; _main_tls->init_thread (NULL, NULL); @@ -307,6 +307,7 @@ frok::parent (volatile char * volatile stack_here) ch.forker_finished = forker_finished; + ch.from_main = &_my_tls == _main_tls; ch.stackbase = NtCurrentTeb()->Tib.StackBase; ch.stackaddr = NtCurrentTeb ()->DeallocationStack; if (!ch.stackaddr)