diff options
Diffstat (limited to 'packaging/0004-ExecuteHandlerOnOriginalStack-handle-case-when-it-is.patch')
-rw-r--r-- | packaging/0004-ExecuteHandlerOnOriginalStack-handle-case-when-it-is.patch | 146 |
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 + |