Fix asan false-positive issues and proper signal handling 31/169831/1 accepted/tizen/4.0/unified/20180220.064248 submit/tizen_4.0/20180220.011653 submit/tizen_4.0_tv/20180312.052402
authorKonstantin Baladurin <k.baladurin@partner.samsung.com>
Fri, 9 Feb 2018 13:07:25 +0000 (16:07 +0300)
committerKonstantin Baladurin <k.baladurin@partner.samsung.com>
Fri, 9 Feb 2018 13:07:25 +0000 (16:07 +0300)
Change-Id: I2641576ec44bad7aa34d314b1113414479458cf9

packaging/0001-Fix-build-with-Asan-15372.patch [new file with mode: 0644]
packaging/0002-Fix-asan-false-positive-errors-15563.patch [new file with mode: 0644]
packaging/0003-ThrowExceptionFromContextInternal-RtlCaptureContext-.patch [new file with mode: 0644]
packaging/0004-ExecuteHandlerOnOriginalStack-handle-case-when-it-is.patch [new file with mode: 0644]
packaging/coreclr.spec

diff --git a/packaging/0001-Fix-build-with-Asan-15372.patch b/packaging/0001-Fix-build-with-Asan-15372.patch
new file mode 100644 (file)
index 0000000..0163c78
--- /dev/null
@@ -0,0 +1,121 @@
+From 1cf30166f8b1489ff3c9958e7ad21f097aa5065e Mon Sep 17 00:00:00 2001
+From: Konstantin Baladurin <k.baladurin@partner.samsung.com>
+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 (file)
index 0000000..05b649c
--- /dev/null
@@ -0,0 +1,232 @@
+From 99bc9451f0dff634101734c53358f2bea88b2d83 Mon Sep 17 00:00:00 2001
+From: Konstantin Baladurin <k.baladurin@partner.samsung.com>
+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 (file)
index 0000000..058fe3f
--- /dev/null
@@ -0,0 +1,81 @@
+From b71438bf6607d6d35f3cfb1bbfe4a525c06cf656 Mon Sep 17 00:00:00 2001
+From: Konstantin Baladurin <k.baladurin@partner.samsung.com>
+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 (file)
index 0000000..6182066
--- /dev/null
@@ -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
+
index 194cf43..e902cdb 100644 (file)
@@ -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
 
@@ -206,6 +210,10 @@ cp %{SOURCE1001} .
 %patch39 -p1
 %patch40 -p1
 %patch41 -p1
+%patch42 -p1
+%patch43 -p1
+%patch44 -p1
+%patch45 -p1
 
 %if 0%{skipmscorlib}
 %else