summaryrefslogtreecommitdiff
path: root/src/pal
diff options
context:
space:
mode:
authorJan Vorlicek <janvorli@microsoft.com>2019-08-07 18:15:14 +0200
committerWilliam Godbe <wigodbe@microsoft.com>2019-08-07 09:15:14 -0700
commit1f03924256d50493a0d61e46b9d36985d256e355 (patch)
treed1ac51617defa3694bbe34068f267223d614a7ef /src/pal
parentfe139940e7211be4f631a3a35ede45e350a1d7b9 (diff)
downloadcoreclr-1f03924256d50493a0d61e46b9d36985d256e355.tar.gz
coreclr-1f03924256d50493a0d61e46b9d36985d256e355.tar.bz2
coreclr-1f03924256d50493a0d61e46b9d36985d256e355.zip
Port to 3.0 - Fix WSL alternate stack check (#25980)
On WSL, the alternate stack check in sigsegv_handler doesn't work. The uc_stack members are always zero no matter whether the handler is executed on an alternate or default stack. So the check to detect whether we are running on an alternate stack or not is always returning false on WSL and it prevents NULL reference exceptions from being handled. The fix is to introduce an env variable COMPlus_EnableAlternateStackCheck that can be used to enable the alternate stack check. By default, the sigsegv_handler is considered to always run on an alternate stack.
Diffstat (limited to 'src/pal')
-rw-r--r--src/pal/src/exception/signal.cpp31
-rw-r--r--src/pal/src/include/pal/signal.hpp1
2 files changed, 27 insertions, 5 deletions
diff --git a/src/pal/src/exception/signal.cpp b/src/pal/src/exception/signal.cpp
index fbd94a886b..7e00483417 100644
--- a/src/pal/src/exception/signal.cpp
+++ b/src/pal/src/exception/signal.cpp
@@ -91,7 +91,9 @@ static void restore_signal_and_resend(int code, struct sigaction* action);
#if !HAVE_MACH_EXCEPTIONS
bool g_registered_signal_handlers = false;
+bool g_enable_alternate_stack_check = false;
#endif // !HAVE_MACH_EXCEPTIONS
+
static bool g_registered_sigterm_handler = false;
struct sigaction g_previous_sigterm;
@@ -132,6 +134,11 @@ BOOL SEHInitializeSignals(CorUnix::CPalThread *pthrCurrent, DWORD flags)
TRACE("Initializing signal handlers\n");
#if !HAVE_MACH_EXCEPTIONS
+
+ char* enableAlternateStackCheck = getenv("COMPlus_EnableAlternateStackCheck");
+
+ g_enable_alternate_stack_check = enableAlternateStackCheck && (strtoul(enableAlternateStackCheck, NULL, 10) != 0);
+
if (flags & PAL_INITIALIZE_REGISTER_SIGNALS)
{
g_registered_signal_handlers = true;
@@ -402,11 +409,25 @@ Return :
--*/
bool IsRunningOnAlternateStack(void *context)
{
- stack_t *signalStack = &((native_context_t *)context)->uc_stack;
- // Check if the signalStack local variable address is within the alternate stack range. If it is not,
- // then either the alternate stack was not installed at all or the current method is not running on it.
- void* alternateStackEnd = (char *)signalStack->ss_sp + signalStack->ss_size;
- return ((signalStack->ss_flags & SS_DISABLE) == 0) && (signalStack->ss_sp <= &signalStack) && (&signalStack < alternateStackEnd);
+ bool isRunningOnAlternateStack;
+ if (g_enable_alternate_stack_check)
+ {
+ // Note: WSL doesn't return the alternate signal ranges in the uc_stack (the whole structure is zeroed no
+ // matter whether the code is running on an alternate stack or not). So the check would always fail on WSL.
+ stack_t *signalStack = &((native_context_t *)context)->uc_stack;
+ // Check if the signalStack local variable address is within the alternate stack range. If it is not,
+ // then either the alternate stack was not installed at all or the current method is not running on it.
+ void* alternateStackEnd = (char *)signalStack->ss_sp + signalStack->ss_size;
+ isRunningOnAlternateStack = ((signalStack->ss_flags & SS_DISABLE) == 0) && (signalStack->ss_sp <= &signalStack) && (&signalStack < alternateStackEnd);
+ }
+ else
+ {
+ // If alternate stack check is disabled, consider always that we are running on an alternate
+ // signal handler stack.
+ isRunningOnAlternateStack = true;
+ }
+
+ return isRunningOnAlternateStack;
}
/*++
diff --git a/src/pal/src/include/pal/signal.hpp b/src/pal/src/include/pal/signal.hpp
index 9c14d2f714..244f161b5c 100644
--- a/src/pal/src/include/pal/signal.hpp
+++ b/src/pal/src/include/pal/signal.hpp
@@ -30,6 +30,7 @@ struct SignalHandlerWorkerReturnPoint
};
extern bool g_registered_signal_handlers;
+extern bool g_enable_alternate_stack_check;
/*++
Function :