[compiler-rt] 387e94c - [asan] Refactor stack unpoisoning.

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 16 01:52:54 PDT 2020


Author: Robert Schneider
Date: 2020-06-16T01:52:44-07:00
New Revision: 387e94ca920743e8a5c4591ef9147a22dc860dca

URL: https://github.com/llvm/llvm-project/commit/387e94ca920743e8a5c4591ef9147a22dc860dca
DIFF: https://github.com/llvm/llvm-project/commit/387e94ca920743e8a5c4591ef9147a22dc860dca.diff

LOG: [asan] Refactor stack unpoisoning.

Summary: This adds a customization point to support unpoisoning of signal alternate stacks on POSIX.

Reviewers: vitalybuka

Reviewed By: vitalybuka

Subscribers: #sanitizers

Tags: #sanitizers

Differential Revision: https://reviews.llvm.org/D81577

Added: 
    

Modified: 
    compiler-rt/lib/asan/asan_fuchsia.cpp
    compiler-rt/lib/asan/asan_internal.h
    compiler-rt/lib/asan/asan_posix.cpp
    compiler-rt/lib/asan/asan_rtems.cpp
    compiler-rt/lib/asan/asan_rtl.cpp
    compiler-rt/lib/asan/asan_win.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/asan/asan_fuchsia.cpp b/compiler-rt/lib/asan/asan_fuchsia.cpp
index f8b2d5f26979..64f6dcbcefeb 100644
--- a/compiler-rt/lib/asan/asan_fuchsia.cpp
+++ b/compiler-rt/lib/asan/asan_fuchsia.cpp
@@ -62,6 +62,8 @@ void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
   UNIMPLEMENTED();
 }
 
+bool PlatformUnpoisonStacks() { return false; }
+
 // We can use a plain thread_local variable for TSD.
 static thread_local void *per_thread;
 

diff  --git a/compiler-rt/lib/asan/asan_internal.h b/compiler-rt/lib/asan/asan_internal.h
index 72a4c3f22ff1..d4bfe996b664 100644
--- a/compiler-rt/lib/asan/asan_internal.h
+++ b/compiler-rt/lib/asan/asan_internal.h
@@ -83,6 +83,16 @@ void *AsanDoesNotSupportStaticLinkage();
 void AsanCheckDynamicRTPrereqs();
 void AsanCheckIncompatibleRT();
 
+// Unpoisons platform-specific stacks.
+// Returns true if all stacks have been unpoisoned.
+bool PlatformUnpoisonStacks();
+
+// asan_rtl.cpp
+// Unpoison a region containing a stack.
+// Performs a sanity check and warns if the bounds don't look right.
+// The warning contains the type string to identify the stack type.
+void UnpoisonStack(uptr bottom, uptr top, const char *type);
+
 // asan_thread.cpp
 AsanThread *CreateMainThread();
 

diff  --git a/compiler-rt/lib/asan/asan_posix.cpp b/compiler-rt/lib/asan/asan_posix.cpp
index 920d216624a3..30559798c5c5 100644
--- a/compiler-rt/lib/asan/asan_posix.cpp
+++ b/compiler-rt/lib/asan/asan_posix.cpp
@@ -37,6 +37,8 @@ void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
   ReportDeadlySignal(sig);
 }
 
+bool PlatformUnpoisonStacks() { return false; }
+
 // ---------------------- TSD ---------------- {{{1
 
 #if SANITIZER_NETBSD && !ASAN_DYNAMIC

diff  --git a/compiler-rt/lib/asan/asan_rtems.cpp b/compiler-rt/lib/asan/asan_rtems.cpp
index ecd568c5981b..2e5b2f0a3b21 100644
--- a/compiler-rt/lib/asan/asan_rtems.cpp
+++ b/compiler-rt/lib/asan/asan_rtems.cpp
@@ -64,6 +64,8 @@ void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
   UNIMPLEMENTED();
 }
 
+bool PlatformUnpoisonStacks() { return false; }
+
 void EarlyInit() {
   // Provide early initialization of shadow memory so that
   // instrumented code running before full initialzation will not

diff  --git a/compiler-rt/lib/asan/asan_rtl.cpp b/compiler-rt/lib/asan/asan_rtl.cpp
index 594d7752eea6..463bfa02f9f1 100644
--- a/compiler-rt/lib/asan/asan_rtl.cpp
+++ b/compiler-rt/lib/asan/asan_rtl.cpp
@@ -551,22 +551,33 @@ class AsanInitializer {
 static AsanInitializer asan_initializer;
 #endif  // ASAN_DYNAMIC
 
-} // namespace __asan
-
-// ---------------------- Interface ---------------- {{{1
-using namespace __asan;
-
-void NOINLINE __asan_handle_no_return() {
-  if (asan_init_is_running)
+void UnpoisonStack(uptr bottom, uptr top, const char *type) {
+  static const uptr kMaxExpectedCleanupSize = 64 << 20;  // 64M
+  if (top - bottom > kMaxExpectedCleanupSize) {
+    static bool reported_warning = false;
+    if (reported_warning)
+      return;
+    reported_warning = true;
+    Report(
+        "WARNING: ASan is ignoring requested __asan_handle_no_return: "
+        "stack type: %s top: %p; bottom %p; size: %p (%zd)\n"
+        "False positive error reports may follow\n"
+        "For details see "
+        "https://github.com/google/sanitizers/issues/189\n",
+        type, top, bottom, top - bottom, top - bottom);
     return;
+  }
+  PoisonShadow(bottom, top - bottom, 0);
+}
 
-  int local_stack;
-  AsanThread *curr_thread = GetCurrentThread();
-  uptr PageSize = GetPageSizeCached();
-  uptr top, bottom;
-  if (curr_thread) {
+static void UnpoisonDefaultStack() {
+  uptr bottom, top;
+
+  if (AsanThread *curr_thread = GetCurrentThread()) {
+    int local_stack;
+    const uptr page_size = GetPageSizeCached();
     top = curr_thread->stack_top();
-    bottom = ((uptr)&local_stack - PageSize) & ~(PageSize - 1);
+    bottom = ((uptr)&local_stack - page_size) & ~(page_size - 1);
   } else if (SANITIZER_RTEMS) {
     // Give up On RTEMS.
     return;
@@ -578,25 +589,31 @@ void NOINLINE __asan_handle_no_return() {
                          &tls_size);
     top = bottom + stack_size;
   }
-  static const uptr kMaxExpectedCleanupSize = 64 << 20;  // 64M
-  if (top - bottom > kMaxExpectedCleanupSize) {
-    static bool reported_warning = false;
-    if (reported_warning)
-      return;
-    reported_warning = true;
-    Report("WARNING: ASan is ignoring requested __asan_handle_no_return: "
-           "stack top: %p; bottom %p; size: %p (%zd)\n"
-           "False positive error reports may follow\n"
-           "For details see "
-           "https://github.com/google/sanitizers/issues/189\n",
-           top, bottom, top - bottom, top - bottom);
-    return;
-  }
-  PoisonShadow(bottom, top - bottom, 0);
+
+  UnpoisonStack(bottom, top, "default");
+}
+
+static void UnpoisonFakeStack() {
+  AsanThread *curr_thread = GetCurrentThread();
   if (curr_thread && curr_thread->has_fake_stack())
     curr_thread->fake_stack()->HandleNoReturn();
 }
 
+}  // namespace __asan
+
+// ---------------------- Interface ---------------- {{{1
+using namespace __asan;
+
+void NOINLINE __asan_handle_no_return() {
+  if (asan_init_is_running)
+    return;
+
+  if (!PlatformUnpoisonStacks())
+    UnpoisonDefaultStack();
+
+  UnpoisonFakeStack();
+}
+
 extern "C" void *__asan_extra_spill_area() {
   AsanThread *t = GetCurrentThread();
   CHECK(t);

diff  --git a/compiler-rt/lib/asan/asan_win.cpp b/compiler-rt/lib/asan/asan_win.cpp
index 417892aaedd8..03feddbe86b4 100644
--- a/compiler-rt/lib/asan/asan_win.cpp
+++ b/compiler-rt/lib/asan/asan_win.cpp
@@ -268,6 +268,8 @@ void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
 
 void AsanOnDeadlySignal(int, void *siginfo, void *context) { UNIMPLEMENTED(); }
 
+bool PlatformUnpoisonStacks() { return false; }
+
 #if SANITIZER_WINDOWS64
 // Exception handler for dealing with shadow memory.
 static LONG CALLBACK


        


More information about the llvm-commits mailing list