diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 7f33687ec..31b429ba1 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,10 @@ +2015-06-27 Corinna Vinschen + + * exceptions.cc (_cygtls::call_signal_handler): Drop manipulating + thread's ss_flags here. It's not safe against longjmp. + * signal.cc (sigaltstack): Check if we're running on the alternate + stack and set ss_flags returned in oss to SS_ONSTACK. + 2015-06-26 Corinna Vinschen * include/cygwin/signal.h: Revert to define MINSIGSTKSZ and SIGSTKSZ diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index d493abb00..90a8ff25d 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -1599,8 +1599,6 @@ _cygtls::call_signal_handler () uintptr_t new_sp = (uintptr_t) _my_tls.altstack.ss_sp + _my_tls.altstack.ss_size; new_sp &= ~0xf; - /* Mark alternate stack as used. */ - _my_tls.altstack.ss_flags = SS_ONSTACK; /* In assembler: Save regs on new stack, move to alternate stack, call thisfunc, revert stack regs. */ #ifdef __x86_64__ @@ -1671,8 +1669,6 @@ _cygtls::call_signal_handler () [FUNC] "o" (thisfunc) : "memory"); #endif - /* Revert alternate stack to unused. */ - _my_tls.altstack.ss_flags = 0; } else /* No alternate signal stack requested or available, just call diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 94faaf308..467c919c3 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -667,7 +667,17 @@ sigaltstack (const stack_t *ss, stack_t *oss) } } if (oss) - memcpy (oss, &me.altstack, sizeof *oss); + { + char stack_marker; + memcpy (oss, &me.altstack, sizeof *oss); + if (!me.altstack.ss_flags && me.altstack.ss_sp) + { + if (&stack_marker >= (char *) me.altstack.ss_sp + && &stack_marker < (char *) me.altstack.ss_sp + + me.altstack.ss_size) + oss->ss_flags = SS_ONSTACK; + } + } } __except (EFAULT) {