From 790430fde60bf8a8347ecf4822ba70b34338a932 Mon Sep 17 00:00:00 2001 From: Konstantin Baladurin Date: Fri, 9 Feb 2018 16:07:25 +0300 Subject: Fix asan false-positive issues and proper signal handling Change-Id: I2641576ec44bad7aa34d314b1113414479458cf9 (cherry picked from commit 399653b670d9e14c47cef78c7e4dcdc369f66ed7) --- packaging/0001-Fix-build-with-Asan-15372.patch | 121 +++++++++++ ...0002-Fix-asan-false-positive-errors-15563.patch | 232 +++++++++++++++++++++ ...ionFromContextInternal-RtlCaptureContext-.patch | 81 +++++++ ...lerOnOriginalStack-handle-case-when-it-is.patch | 146 +++++++++++++ packaging/coreclr.spec | 10 +- 5 files changed, 589 insertions(+), 1 deletion(-) create mode 100644 packaging/0001-Fix-build-with-Asan-15372.patch create mode 100644 packaging/0002-Fix-asan-false-positive-errors-15563.patch create mode 100644 packaging/0003-ThrowExceptionFromContextInternal-RtlCaptureContext-.patch create mode 100644 packaging/0004-ExecuteHandlerOnOriginalStack-handle-case-when-it-is.patch diff --git a/packaging/0001-Fix-build-with-Asan-15372.patch b/packaging/0001-Fix-build-with-Asan-15372.patch new file mode 100644 index 0000000000..0163c78f0c --- /dev/null +++ b/packaging/0001-Fix-build-with-Asan-15372.patch @@ -0,0 +1,121 @@ +From 1cf30166f8b1489ff3c9958e7ad21f097aa5065e Mon Sep 17 00:00:00 2001 +From: Konstantin Baladurin +Date: Sat, 9 Dec 2017 13:57:20 +0300 +Subject: [PATCH 1/4] Fix build with Asan (#15372) + +- verify_dependencies: disable checking dependencies for Asan build + because in this case shared libraries can have undefined symbols + (if static linking with compiler-rt is used). + +- enablesanitizers.sh: remove excess quotes for ASAN_OPTIONS and + UBSAN_OPTIONS environment variable because otherwise Asan cannot + parse flags. Also doesn't export ASAN_SYMBOLIZER_PATH for clang > 3.6. +--- + enablesanitizers.sh | 36 +++++++++++++++++++++++++++--------- + functions.cmake | 16 +++++++++++++++- + 2 files changed, 42 insertions(+), 10 deletions(-) + +diff --git a/enablesanitizers.sh b/enablesanitizers.sh +index 70555aa..2937b0b 100755 +--- a/enablesanitizers.sh ++++ b/enablesanitizers.sh +@@ -26,6 +26,7 @@ else + __EnableLSan=0 + __TurnOff=0 + __Options= ++ __ExportSymbolizerPath=1 + + for i in "$@" + do +@@ -60,6 +61,17 @@ else + clang3.7) + __ClangMajorVersion=3 + __ClangMinorVersion=7 ++ __ExportSymbolizerPath=0 ++ ;; ++ clang3.8) ++ __ClangMajorVersion=3 ++ __ClangMinorVersion=8 ++ __ExportSymbolizerPath=0 ++ ;; ++ clang3.9) ++ __ClangMajorVersion=3 ++ __ClangMinorVersion=9 ++ __ExportSymbolizerPath=0 + ;; + *) + echo "Unknown arg: $i" +@@ -83,7 +95,9 @@ else + __Options="$__Options ubsan" + fi + if [ $__EnableLSan == 1 ]; then +- ASAN_OPTIONS="$ASAN_OPTIONS detect_leaks" ++ ASAN_OPTIONS="$ASAN_OPTIONS detect_leaks=1" ++ else ++ ASAN_OPTIONS="$ASAN_OPTIONS detect_leaks=0" + fi + + # passed to build.sh +@@ -92,18 +106,22 @@ else + echo "Setting DEBUG_SANITIZERS=$DEBUG_SANITIZERS" + + # used by ASan at run-time +- ASAN_OPTIONS="\"$ASAN_OPTIONS\"" + export ASAN_OPTIONS +- echo "Setting ASAN_OPTIONS=$ASAN_OPTIONS" ++ echo "Setting ASAN_OPTIONS=\"$ASAN_OPTIONS\"" + +- UBSAN_OPTIONS="\"$UBSAN_OPTIONS\"" + export UBSAN_OPTIONS +- echo "Setting UBSAN_OPTIONS=$UBSAN_OPTIONS" ++ echo "Setting UBSAN_OPTIONS=\"$UBSAN_OPTIONS\"" + +- # used by ASan at run-time +- ASAN_SYMBOLIZER_PATH="/usr/bin/llvm-symbolizer-$__ClangMajorVersion.$__ClangMinorVersion" +- export ASAN_SYMBOLIZER_PATH +- echo "Setting ASAN_SYMBOLIZER_PATH=$ASAN_SYMBOLIZER_PATH" ++ # for compiler-rt > 3.6 Asan check that binary name is 'llvm-symbolizer', 'addr2line' or ++ # 'atos' (for Darwin) otherwise it returns error ++ if [ $__ExportSymbolizerPath == 1 ]; then ++ # used by ASan at run-time ++ ASAN_SYMBOLIZER_PATH="/usr/bin/llvm-symbolizer-$__ClangMajorVersion.$__ClangMinorVersion" ++ export ASAN_SYMBOLIZER_PATH ++ echo "Setting ASAN_SYMBOLIZER_PATH=$ASAN_SYMBOLIZER_PATH" ++ else ++ unset ASAN_SYMBOLIZER_PATH ++ fi + echo "Done. You can now run: build.sh Debug clang$__ClangMajorVersion.$__ClangMinorVersion" + fi + +diff --git a/functions.cmake b/functions.cmake +index cf4d08f..50e4bbe 100644 +--- a/functions.cmake ++++ b/functions.cmake +@@ -223,9 +223,23 @@ function(_install) + endfunction() + + function(verify_dependencies targetName errorMessage) ++ set(SANITIZER_BUILD OFF) ++ ++ if (CLR_CMAKE_PLATFORM_UNIX) ++ if (UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG OR UPPERCASE_CMAKE_BUILD_TYPE STREQUAL CHECKED) ++ string(FIND "$ENV{DEBUG_SANITIZERS}" "asan" __ASAN_POS) ++ string(FIND "$ENV{DEBUG_SANITIZERS}" "ubsan" __UBSAN_POS) ++ if ((${__ASAN_POS} GREATER -1) OR (${__UBSAN_POS} GREATER -1)) ++ set(SANITIZER_BUILD ON) ++ endif() ++ endif() ++ endif() ++ + # We don't need to verify dependencies on OSX, since missing dependencies + # result in link error over there. +- if (NOT CLR_CMAKE_PLATFORM_DARWIN AND NOT CLR_CMAKE_PLATFORM_ANDROID) ++ # Also don't verify dependencies for Asan build because in this case shared ++ # libraries can contain undefined symbols ++ if (NOT CLR_CMAKE_PLATFORM_DARWIN AND NOT CLR_CMAKE_PLATFORM_ANDROID AND NOT SANITIZER_BUILD) + add_custom_command( + TARGET ${targetName} + POST_BUILD +-- +2.7.4 + diff --git a/packaging/0002-Fix-asan-false-positive-errors-15563.patch b/packaging/0002-Fix-asan-false-positive-errors-15563.patch new file mode 100644 index 0000000000..05b649c55f --- /dev/null +++ b/packaging/0002-Fix-asan-false-positive-errors-15563.patch @@ -0,0 +1,232 @@ +From 99bc9451f0dff634101734c53358f2bea88b2d83 Mon Sep 17 00:00:00 2001 +From: Konstantin Baladurin +Date: Fri, 26 Jan 2018 01:19:19 +0300 +Subject: [PATCH 2/4] Fix asan false-positive errors: (#15563) + +- Call __asan_handle_no_return in RtlRestoreContext if it doesn't return + and in ThrowExceptionFromContextInternal function; + +- Increase alternate signal stack size and use it also for asan. +--- + CMakeLists.txt | 1 + + enablesanitizers.sh | 7 ++++--- + src/pal/src/arch/amd64/context2.S | 13 ++++++++++++- + src/pal/src/arch/amd64/exceptionhelper.S | 6 ++++++ + src/pal/src/arch/arm/context2.S | 13 ++++++++++++- + src/pal/src/arch/arm/exceptionhelper.S | 6 ++++++ + src/pal/src/arch/arm64/context2.S | 11 +++++++++++ + src/pal/src/arch/arm64/exceptionhelper.S | 6 ++++++ + src/pal/src/arch/i386/context2.S | 5 ++++- + src/pal/src/arch/i386/exceptionhelper.S | 6 ++++++ + src/pal/src/exception/signal.cpp | 5 +++++ + 11 files changed, 73 insertions(+), 6 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 45dd65b..1a3ad16 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -408,6 +408,7 @@ elseif (CLR_CMAKE_PLATFORM_UNIX) + if (${__ASAN_POS} GREATER -1) + set(CLR_SANITIZE_CXX_FLAGS "${CLR_SANITIZE_CXX_FLAGS}address,") + set(CLR_SANITIZE_LINK_FLAGS "${CLR_SANITIZE_LINK_FLAGS}address,") ++ add_definitions(-DHAS_ASAN) + message("Address Sanitizer (asan) enabled") + endif () + if (${__UBSAN_POS} GREATER -1) +diff --git a/enablesanitizers.sh b/enablesanitizers.sh +index 2937b0b..aedb95d 100755 +--- a/enablesanitizers.sh ++++ b/enablesanitizers.sh +@@ -83,8 +83,9 @@ else + unset DEBUG_SANITIZERS + echo "Setting DEBUG_SANITIZERS=" + else +- # for now, specify alloc_dealloc_mismatch=0 as there are too many error reports that are not an issue +- ASAN_OPTIONS="symbolize=1 alloc_dealloc_mismatch=0" ++ # for now, specify alloc_dealloc_mismatch=0 as there are too many error reports that are not an issue. ++ # Also specify use_sigaltstack=0 as coreclr uses own alternate stack for signal handlers ++ ASAN_OPTIONS="symbolize=1 alloc_dealloc_mismatch=0 use_sigaltstack=0" + # when Clang 3.8 available, add: suppressions=$(readlink -f sanitizersuppressions.txt) + UBSAN_OPTIONS="print_stacktrace=1" + +@@ -132,4 +133,4 @@ else + unset __EnableLSan + unset __TurnOff + unset __Options +-fi +\ No newline at end of file ++fi +diff --git a/src/pal/src/arch/amd64/context2.S b/src/pal/src/arch/amd64/context2.S +index 0e93e81..46c941f 100644 +--- a/src/pal/src/arch/amd64/context2.S ++++ b/src/pal/src/arch/amd64/context2.S +@@ -104,7 +104,18 @@ LEAF_END RtlCaptureContext, _TEXT + LEAF_ENTRY RtlRestoreContext, _TEXT + push_nonvol_reg rbp + alloc_stack (IRetFrameLengthAligned) +- ++ ++#ifdef HAS_ASAN ++ test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_CONTROL ++ je LOCAL_LABEL(Restore_CONTEXT_DEBUG_REGISTERS) ++ ++ push_nonvol_reg rdi ++ push_nonvol_reg rsi ++ call EXTERNAL_C_FUNC(__asan_handle_no_return) ++ pop_nonvol_reg rsi ++ pop_nonvol_reg rdi ++LOCAL_LABEL(Restore_CONTEXT_DEBUG_REGISTERS): ++#endif + test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_DEBUG_REGISTERS + je LOCAL_LABEL(Done_Restore_CONTEXT_DEBUG_REGISTERS) + mov rdx, [rdi + CONTEXT_Dr0] +diff --git a/src/pal/src/arch/amd64/exceptionhelper.S b/src/pal/src/arch/amd64/exceptionhelper.S +index b7b34ac..72a1393 100644 +--- a/src/pal/src/arch/amd64/exceptionhelper.S ++++ b/src/pal/src/arch/amd64/exceptionhelper.S +@@ -14,6 +14,12 @@ + // Then it uses the ThrowExceptionHelper to throw the passed in exception from that context. + // EXTERN_C void ThrowExceptionFromContextInternal(CONTEXT* context, PAL_SEHException* ex); + LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT ++#ifdef HAS_ASAN ++ // Need to call __asan_handle_no_return explicitly here because we re-intialize RSP before ++ // throwing exception in ThrowExceptionHelper ++ call EXTERNAL_C_FUNC(__asan_handle_no_return) ++#endif ++ + // Save the RBP to the stack so that the unwind can work at the instruction after + // loading the RBP from the context, but before loading the RSP from the context. + push_nonvol_reg rbp +diff --git a/src/pal/src/arch/arm/context2.S b/src/pal/src/arch/arm/context2.S +index 61e9ab8..42f50c9 100644 +--- a/src/pal/src/arch/arm/context2.S ++++ b/src/pal/src/arch/arm/context2.S +@@ -112,7 +112,18 @@ LEAF_END RtlCaptureContext, _TEXT + // + LEAF_ENTRY RtlRestoreContext, _TEXT + END_PROLOGUE +- ++ ++#ifdef HAS_ASAN ++ ldr r2, [r0, #(CONTEXT_ContextFlags)] ++ tst r2, #(CONTEXT_CONTROL) ++ beq LOCAL_LABEL(Restore_CONTEXT_FLOATING_POINT) ++ ++ push {r0, r1} ++ bl EXTERNAL_C_FUNC(__asan_handle_no_return) ++ pop {r0, r1} ++ ++LOCAL_LABEL(Restore_CONTEXT_FLOATING_POINT): ++#endif + ldr r2, [r0, #(CONTEXT_ContextFlags)] + tst r2, #(CONTEXT_FLOATING_POINT) + +diff --git a/src/pal/src/arch/arm/exceptionhelper.S b/src/pal/src/arch/arm/exceptionhelper.S +index 76cdcba..dad48de 100644 +--- a/src/pal/src/arch/arm/exceptionhelper.S ++++ b/src/pal/src/arch/arm/exceptionhelper.S +@@ -11,6 +11,12 @@ + // EXTERN_C void ThrowExceptionFromContextInternal(CONTEXT* context, PAL_SEHException* ex); + LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT + // Ported from src/pal/src/arch/amd64/exceptionhelper.S ++#ifdef HAS_ASAN ++ // Need to call __asan_handle_no_return explicitly here because we re-intialize SP before ++ // throwing exception in ThrowExceptionHelper ++ bl EXTERNAL_C_FUNC(__asan_handle_no_return) ++#endif ++ + push_nonvol_reg {r7} /* FP. x64-RBP */ + + ldr r4, [r0, #(CONTEXT_R4)] +diff --git a/src/pal/src/arch/arm64/context2.S b/src/pal/src/arch/arm64/context2.S +index e62a9ac..ac3661a 100644 +--- a/src/pal/src/arch/arm64/context2.S ++++ b/src/pal/src/arch/arm64/context2.S +@@ -133,6 +133,17 @@ LEAF_END RtlCaptureContext, _TEXT + // x1: Exception* + // + LEAF_ENTRY RtlRestoreContext, _TEXT ++ ++#ifdef HAS_ASAN ++ ldr w17, [x0, #(CONTEXT_ContextFlags)] ++ tbz w17, #CONTEXT_CONTROL_BIT, LOCAL_LABEL(Restore_CONTEXT_FLOATING_POINT) ++ ++ stp x0, x1, [sp] ++ bl EXTERNAL_C_FUNC(__asan_handle_no_return) ++ ldp x0, x1, [sp] ++ ++LOCAL_LABEL(Restore_CONTEXT_FLOATING_POINT): ++#endif + // aarch64 specifies: + // IP0 and IP1, the Intra-Procedure Call temporary registers, + // are available for use by e.g. veneers or branch islands during a procedure call. +diff --git a/src/pal/src/arch/arm64/exceptionhelper.S b/src/pal/src/arch/arm64/exceptionhelper.S +index 480846e..7deeee6 100644 +--- a/src/pal/src/arch/arm64/exceptionhelper.S ++++ b/src/pal/src/arch/arm64/exceptionhelper.S +@@ -12,6 +12,12 @@ + // Then it uses the ThrowExceptionHelper to throw the passed in exception from that context. + // EXTERN_C void ThrowExceptionFromContextInternal(CONTEXT* context, PAL_SEHException* ex); + LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT ++#ifdef HAS_ASAN ++ // Need to call __asan_handle_no_return explicitly here because we re-intialize SP before ++ // throwing exception in ThrowExceptionHelper ++ bl EXTERNAL_C_FUNC(__asan_handle_no_return) ++#endif ++ + // Save the FP & LR to the stack so that the unwind can work at the instruction after + // loading the FP from the context, but before loading the SP from the context. + stp fp, lr, [sp, -16]! +diff --git a/src/pal/src/arch/i386/context2.S b/src/pal/src/arch/i386/context2.S +index cf7581d..8c5db20 100644 +--- a/src/pal/src/arch/i386/context2.S ++++ b/src/pal/src/arch/i386/context2.S +@@ -94,8 +94,11 @@ LEAF_ENTRY RtlCaptureContext, _TEXT + LEAF_END RtlCaptureContext, _TEXT + + LEAF_ENTRY RtlRestoreContext, _TEXT +- mov eax, [esp + 4] + ++#ifdef HAS_ASAN ++ call EXTERNAL_C_FUNC(__asan_handle_no_return) ++#endif ++ mov eax, [esp + 4] + test BYTE PTR [eax + CONTEXT_ContextFlags], CONTEXT_FLOATING_POINT + je LOCAL_LABEL(Done_Restore_CONTEXT_FLOATING_POINT) + frstor [eax + CONTEXT_FloatSave] +diff --git a/src/pal/src/arch/i386/exceptionhelper.S b/src/pal/src/arch/i386/exceptionhelper.S +index b9ceffc..609efcf 100644 +--- a/src/pal/src/arch/i386/exceptionhelper.S ++++ b/src/pal/src/arch/i386/exceptionhelper.S +@@ -18,6 +18,12 @@ + ////////////////////////////////////////////////////////////////////////// + + LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT ++#ifdef HAS_ASAN ++ // Need to call __asan_handle_no_return explicitly here because we re-intialize ESP before ++ // throwing exception in ThrowExceptionHelper ++ call EXTERNAL_C_FUNC(__asan_handle_no_return) ++#endif ++ + push ebp + mov ecx, [esp + 12] // ecx: PAL_SEHException * (first argument for ThrowExceptionHelper) + mov eax, [esp + 8] // ebx: CONTEXT * +diff --git a/src/pal/src/exception/signal.cpp b/src/pal/src/exception/signal.cpp +index 10eecf7..f795b81 100644 +--- a/src/pal/src/exception/signal.cpp ++++ b/src/pal/src/exception/signal.cpp +@@ -153,6 +153,11 @@ BOOL EnsureSignalAlternateStack() + // We include the size of the SignalHandlerWorkerReturnPoint in the alternate stack size since the + // context contained in it is large and the SIGSTKSZ was not sufficient on ARM64 during testing. + int altStackSize = SIGSTKSZ + ALIGN_UP(sizeof(SignalHandlerWorkerReturnPoint), 16) + VIRTUAL_PAGE_SIZE; ++#ifdef HAS_ASAN ++ // Asan also uses alternate stack so we increase its size on the SIGSTKSZ * 4 that enough for asan ++ // (see kAltStackSize in compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc) ++ altStackSize += SIGSTKSZ * 4; ++#endif + void* altStack; + int st = posix_memalign(&altStack, VIRTUAL_PAGE_SIZE, altStackSize); + if (st == 0) +-- +2.7.4 + diff --git a/packaging/0003-ThrowExceptionFromContextInternal-RtlCaptureContext-.patch b/packaging/0003-ThrowExceptionFromContextInternal-RtlCaptureContext-.patch new file mode 100644 index 0000000000..058fe3fe5e --- /dev/null +++ b/packaging/0003-ThrowExceptionFromContextInternal-RtlCaptureContext-.patch @@ -0,0 +1,81 @@ +From b71438bf6607d6d35f3cfb1bbfe4a525c06cf656 Mon Sep 17 00:00:00 2001 +From: Konstantin Baladurin +Date: Tue, 30 Jan 2018 17:05:57 +0300 +Subject: [PATCH 3/4] ThrowExceptionFromContextInternal, RtlCaptureContext: fix + for asan (#16074) + +- Save arguments on stack before calling __asan_handle_no_return in + ThrowExceptionFromContextInternal + +- Fix saving arguments on stack before calling __asan_handle_no_return + in RtlCaptureContext for arm64 +--- + src/pal/src/arch/amd64/exceptionhelper.S | 4 ++++ + src/pal/src/arch/arm/exceptionhelper.S | 2 ++ + src/pal/src/arch/arm64/context2.S | 4 ++-- + src/pal/src/arch/arm64/exceptionhelper.S | 2 ++ + 4 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/src/pal/src/arch/amd64/exceptionhelper.S b/src/pal/src/arch/amd64/exceptionhelper.S +index 72a1393..cb9a545 100644 +--- a/src/pal/src/arch/amd64/exceptionhelper.S ++++ b/src/pal/src/arch/amd64/exceptionhelper.S +@@ -17,7 +17,11 @@ LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT + #ifdef HAS_ASAN + // Need to call __asan_handle_no_return explicitly here because we re-intialize RSP before + // throwing exception in ThrowExceptionHelper ++ push_nonvol_reg rdi ++ push_nonvol_reg rsi + call EXTERNAL_C_FUNC(__asan_handle_no_return) ++ pop_nonvol_reg rsi ++ pop_nonvol_reg rdi + #endif + + // Save the RBP to the stack so that the unwind can work at the instruction after +diff --git a/src/pal/src/arch/arm/exceptionhelper.S b/src/pal/src/arch/arm/exceptionhelper.S +index dad48de..4e324ce 100644 +--- a/src/pal/src/arch/arm/exceptionhelper.S ++++ b/src/pal/src/arch/arm/exceptionhelper.S +@@ -14,7 +14,9 @@ LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT + #ifdef HAS_ASAN + // Need to call __asan_handle_no_return explicitly here because we re-intialize SP before + // throwing exception in ThrowExceptionHelper ++ push_nonvol_reg "{r0, r1}" + bl EXTERNAL_C_FUNC(__asan_handle_no_return) ++ pop_nonvol_reg "{r0, r1}" + #endif + + push_nonvol_reg {r7} /* FP. x64-RBP */ +diff --git a/src/pal/src/arch/arm64/context2.S b/src/pal/src/arch/arm64/context2.S +index ac3661a..64a19c9 100644 +--- a/src/pal/src/arch/arm64/context2.S ++++ b/src/pal/src/arch/arm64/context2.S +@@ -138,9 +138,9 @@ LEAF_ENTRY RtlRestoreContext, _TEXT + ldr w17, [x0, #(CONTEXT_ContextFlags)] + tbz w17, #CONTEXT_CONTROL_BIT, LOCAL_LABEL(Restore_CONTEXT_FLOATING_POINT) + +- stp x0, x1, [sp] ++ stp x0, x1, [sp, -16]! + bl EXTERNAL_C_FUNC(__asan_handle_no_return) +- ldp x0, x1, [sp] ++ ldp x0, x1, [sp], 16 + + LOCAL_LABEL(Restore_CONTEXT_FLOATING_POINT): + #endif +diff --git a/src/pal/src/arch/arm64/exceptionhelper.S b/src/pal/src/arch/arm64/exceptionhelper.S +index 7deeee6..c4499fb 100644 +--- a/src/pal/src/arch/arm64/exceptionhelper.S ++++ b/src/pal/src/arch/arm64/exceptionhelper.S +@@ -15,7 +15,9 @@ LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT + #ifdef HAS_ASAN + // Need to call __asan_handle_no_return explicitly here because we re-intialize SP before + // throwing exception in ThrowExceptionHelper ++ stp x0, x1, [sp, -16]! + bl EXTERNAL_C_FUNC(__asan_handle_no_return) ++ ldp x0, x1, [sp], 16 + #endif + + // Save the FP & LR to the stack so that the unwind can work at the instruction after +-- +2.7.4 + 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 +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 + diff --git a/packaging/coreclr.spec b/packaging/coreclr.spec index 875e4796a9..29e1ca3e32 100644 --- a/packaging/coreclr.spec +++ b/packaging/coreclr.spec @@ -23,7 +23,7 @@ Source1000: downloaded_files.tar.gz Source1001: %{name}.manifest Source1002: libicu.tar.gz Source1003: dep_libs.tar.gz -# Gbp-Ignore-Patches: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 +# Gbp-Ignore-Patches: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 Patch0: 0001-Add-project.assets.json-files.patch Patch1: 0001-ARM-Linux-Support-unaligned-struct-read-write-11290.patch Patch2: 0002-x86-Linux-Thread-safe-UMThunkMarshInfo-RunTimeInit-1.patch @@ -66,6 +66,10 @@ Patch38: 0001-Fix-uaf-in-DestroyThread-function.patch Patch39: 0001-Enable-gdbjit-while-NI-file-exist.patch Patch40: 0001-Fix-crossgen-debug-directory-generation-problems.-12.patch Patch41: 0001-Fix-SIGSEGV-in-EventPipe-on-Shutdown-14123.patch +Patch42: 0001-Fix-build-with-Asan-15372.patch +Patch43: 0002-Fix-asan-false-positive-errors-15563.patch +Patch44: 0003-ThrowExceptionFromContextInternal-RtlCaptureContext-.patch +Patch45: 0004-ExecuteHandlerOnOriginalStack-handle-case-when-it-is.patch ExcludeArch: aarch64 @@ -211,6 +215,10 @@ cp %{SOURCE1001} . %patch39 -p1 %patch40 -p1 %patch41 -p1 +%patch42 -p1 +%patch43 -p1 +%patch44 -p1 +%patch45 -p1 %if 0%{skipmscorlib} %else -- cgit v1.2.3