summaryrefslogtreecommitdiff
path: root/packaging/0004-ExecuteHandlerOnOriginalStack-handle-case-when-it-is.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packaging/0004-ExecuteHandlerOnOriginalStack-handle-case-when-it-is.patch')
-rw-r--r--packaging/0004-ExecuteHandlerOnOriginalStack-handle-case-when-it-is.patch146
1 files changed, 146 insertions, 0 deletions
diff --git a/packaging/0004-ExecuteHandlerOnOriginalStack-handle-case-when-it-is.patch b/packaging/0004-ExecuteHandlerOnOriginalStack-handle-case-when-it-is.patch
new file mode 100644
index 0000000000..618206640c
--- /dev/null
+++ b/packaging/0004-ExecuteHandlerOnOriginalStack-handle-case-when-it-is.patch
@@ -0,0 +1,146 @@
+From a72739ab5a9c40788557dbc4084c275b5a62a657 Mon Sep 17 00:00:00 2001
+From: Konstantin Baladurin <k.baladurin@partner.samsung.com>
+Date: Wed, 7 Feb 2018 18:44:10 +0300
+Subject: [PATCH 4/4] ExecuteHandlerOnOriginalStack: handle case when it is
+ called on original stack.
+
+If ExecuteHandlerOnOriginalStack is called on original stack (for example,
+if segmentation fault occurs in native application's thread that hasn't
+alternate signal stack) we should use faultSp from its frame otherwise
+stackframe of the caller function will be corrupted.
+---
+ src/pal/src/arch/amd64/signalhandlerhelper.cpp | 20 ++++++++++++++++++--
+ src/pal/src/arch/arm/signalhandlerhelper.cpp | 18 +++++++++++++++++-
+ src/pal/src/arch/arm64/signalhandlerhelper.cpp | 19 ++++++++++++++++++-
+ src/pal/src/arch/i386/signalhandlerhelper.cpp | 18 +++++++++++++++++-
+ 4 files changed, 70 insertions(+), 5 deletions(-)
+
+diff --git a/src/pal/src/arch/amd64/signalhandlerhelper.cpp b/src/pal/src/arch/amd64/signalhandlerhelper.cpp
+index 8789f5a..803479c 100644
+--- a/src/pal/src/arch/amd64/signalhandlerhelper.cpp
++++ b/src/pal/src/arch/amd64/signalhandlerhelper.cpp
+@@ -27,7 +27,23 @@ Parameters :
+ void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context, SignalHandlerWorkerReturnPoint* returnPoint)
+ {
+ ucontext_t *ucontext = (ucontext_t *)context;
+- size_t faultSp = (size_t)MCREG_Rsp(ucontext->uc_mcontext);
++ size_t faultSp;
++
++ // check whether this function is called on alternate stack or not. In the second case we already
++ // on original stack and we should use faultSp from this frame otherwise stackframe of the caller
++ // function will be corrupted.
++ char fakeStackFrame[128 /* redzone */ + 16 /* aligment */ + 4 * sizeof(size_t) /* registers */];
++ stack_t oss;
++ int st = sigaltstack(NULL, &oss);
++ if ((st == 0) && ((oss.ss_flags == SS_DISABLE) ||
++ ((size_t)oss.ss_sp > (size_t)&faultSp) || (((size_t)oss.ss_sp + oss.ss_size) < (size_t)&faultSp)))
++ {
++ faultSp = (size_t)&fakeStackFrame[sizeof(fakeStackFrame)];
++ }
++ else
++ {
++ faultSp = (size_t)MCREG_Rsp(ucontext->uc_mcontext);
++ }
+
+ _ASSERTE(IS_ALIGNED(faultSp, 8));
+
+@@ -58,7 +74,7 @@ void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context,
+ // We don't care about the other registers state since the stack unwinding restores
+ // them for the target frame directly from the signal context.
+ context2.Rsp = (size_t)sp;
+- context2.Rbx = (size_t)faultSp;
++ context2.Rbx = (size_t)MCREG_Rsp(ucontext->uc_mcontext);
+ context2.Rbp = (size_t)fp;
+ context2.Rip = (size_t)signal_handler_worker;
+ context2.Rdi = code;
+diff --git a/src/pal/src/arch/arm/signalhandlerhelper.cpp b/src/pal/src/arch/arm/signalhandlerhelper.cpp
+index 3936204..fbf33e3 100644
+--- a/src/pal/src/arch/arm/signalhandlerhelper.cpp
++++ b/src/pal/src/arch/arm/signalhandlerhelper.cpp
+@@ -27,7 +27,23 @@ Parameters :
+ void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context, SignalHandlerWorkerReturnPoint* returnPoint)
+ {
+ ucontext_t *ucontext = (ucontext_t *)context;
+- size_t faultSp = (size_t)MCREG_Sp(ucontext->uc_mcontext);
++ size_t faultSp;
++
++ // check whether this function is called on alternate stack or not. In the second case we already
++ // on original stack and we should use faultSp from this frame otherwise stackframe of the caller
++ // function will be corrupted.
++ char fakeStackFrame[8 /* redzone */ + 8 /* aligment */ + sizeof(ucontext->uc_mcontext) + 8 /* registers */];
++ stack_t oss;
++ int st = sigaltstack(NULL, &oss);
++ if ((st == 0) && ((oss.ss_flags == SS_DISABLE) ||
++ ((size_t)oss.ss_sp > (size_t)&faultSp) || (((size_t)oss.ss_sp + oss.ss_size) < (size_t)&faultSp)))
++ {
++ faultSp = (size_t)&fakeStackFrame[sizeof(fakeStackFrame)];
++ }
++ else
++ {
++ faultSp = (size_t)MCREG_Sp(ucontext->uc_mcontext);
++ }
+
+ _ASSERTE(IS_ALIGNED(faultSp, 4));
+
+diff --git a/src/pal/src/arch/arm64/signalhandlerhelper.cpp b/src/pal/src/arch/arm64/signalhandlerhelper.cpp
+index c35c629..958b8af 100644
+--- a/src/pal/src/arch/arm64/signalhandlerhelper.cpp
++++ b/src/pal/src/arch/arm64/signalhandlerhelper.cpp
+@@ -27,7 +27,24 @@ Parameters :
+ void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context, SignalHandlerWorkerReturnPoint* returnPoint)
+ {
+ ucontext_t *ucontext = (ucontext_t *)context;
+- size_t faultSp = (size_t)MCREG_Sp(ucontext->uc_mcontext);
++ size_t faultSp;
++
++ // check whether this function is called on alternate stack or not. In the second case we already
++ // on original stack and we should use faultSp from this frame otherwise stackframe of the caller
++ // function will be corrupted.
++ char fakeStackFrame[128 /* redzone */ + 16 /* aligment */ + 3 * sizeof(size_t) /* registers */];
++ stack_t oss;
++ int st = sigaltstack(NULL, &oss);
++ if ((st == 0) && ((oss.ss_flags == SS_DISABLE) ||
++ ((size_t)oss.ss_sp > (size_t)&faultSp) || (((size_t)oss.ss_sp + oss.ss_size) < (size_t)&faultSp)))
++ {
++ faultSp = (size_t)&fakeStackFrame[sizeof(fakeStackFrame)];
++ }
++ else
++ {
++ faultSp = (size_t)MCREG_Sp(ucontext->uc_mcontext);
++ }
++
+ _ASSERTE(IS_ALIGNED(faultSp, 8));
+
+ size_t fakeFrameReturnAddress;
+diff --git a/src/pal/src/arch/i386/signalhandlerhelper.cpp b/src/pal/src/arch/i386/signalhandlerhelper.cpp
+index a7d418a..d534f96 100644
+--- a/src/pal/src/arch/i386/signalhandlerhelper.cpp
++++ b/src/pal/src/arch/i386/signalhandlerhelper.cpp
+@@ -27,7 +27,23 @@ Parameters :
+ void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context, SignalHandlerWorkerReturnPoint* returnPoint)
+ {
+ ucontext_t *ucontext = (ucontext_t *)context;
+- size_t faultSp = (size_t)MCREG_Esp(ucontext->uc_mcontext);
++ size_t faultSp;
++
++ // check whether this function is called on alternate stack or not. In the second case we already
++ // on original stack and we should use faultSp from this frame otherwise stackframe of the caller
++ // function will be corrupted.
++ char fakeStackFrame[16 /* aligment */ + 10 * sizeof(size_t) /* registers */];
++ stack_t oss;
++ int st = sigaltstack(NULL, &oss);
++ if ((st == 0) && ((oss.ss_flags == SS_DISABLE) ||
++ ((size_t)oss.ss_sp > (size_t)&faultSp) || (((size_t)oss.ss_sp + oss.ss_size) < (size_t)&faultSp)))
++ {
++ faultSp = (size_t)&fakeStackFrame[sizeof(fakeStackFrame)];
++ }
++ else
++ {
++ faultSp = (size_t)MCREG_Esp(ucontext->uc_mcontext);
++ }
+
+ _ASSERTE(IS_ALIGNED(faultSp, 4));
+
+--
+2.7.4
+