This is the mail archive of the cygwin-cvs@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[newlib-cygwin] Fix fork after recovered stack overflow


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=e3d345c5c39c79db00c8601682ed6fe35d8953c8

commit e3d345c5c39c79db00c8601682ed6fe35d8953c8
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Wed Jul 1 15:28:16 2015 +0200

    Fix fork after recovered stack overflow
    
    	* fork.cc (frok::parent): Set stacktop value based on requested stack
    	pointer value in child.  Explain why.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/ChangeLog |  5 +++++
 winsup/cygwin/fork.cc   | 16 ++++++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 01bb3eb..eaa62a0 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,8 @@
+2015-07-01  Corinna Vinschen  <corinna@vinschen.de>
+
+	* fork.cc (frok::parent): Set stacktop value based on requested stack
+	pointer value in child.  Explain why.
+
 2015-06-30  Corinna Vinschen  <corinna@vinschen.de>
 
 	* signal.cc (sigaltstack): Add comment.
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index faccb48..951c7fd 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -308,9 +308,21 @@ frok::parent (volatile char * volatile stack_here)
   ch.forker_finished = forker_finished;
 
   PTEB teb = NtCurrentTeb ();
-  ch.stackbottom = _tlsbase;
-  ch.stacktop = (void *) _tlstop;
   ch.stackaddr = teb->DeallocationStack;
+  ch.stackbottom = _tlsbase;
+  /* If DeallocationStack is NULL, we're running on an application-provided
+     stack.  If so, the entire stack is committed anyway and StackLimit points
+     to the allocation address of the stack.  Otherwise we're running on a
+     system-allocated stack and using StackLimit is dangerous, in case the
+     application encountered a stack overflow and recovered from it via
+     a signal handler running on an alternate stack.  Since stack_here is
+     the address of the stack pointer we start the child with anyway, we
+     can set ch.stacktop to this value rounded down to page size.  The
+     child will not need the rest of the stack anyway. */
+  if (!ch.stackaddr)
+    ch.stacktop = _tlstop;
+  else
+    ch.stacktop = (void *) ((uintptr_t) stack_here & ~wincap.page_size ());
   ch.guardsize = 0;
   if (&_my_tls != _main_tls)
     {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]