This is the mail archive of the
cygwin-cvs@cygwin.com
mailing list for the Cygwin project.
[newlib-cygwin] Fix fork after recovered stack overflow
- From: Corinna Vinschen <corinna at sourceware dot org>
- To: cygwin-cvs at sourceware dot org
- Date: 1 Jul 2015 13:28:26 -0000
- Subject: [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)
{