diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /compiler-rt/lib/asan | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Notes
Diffstat (limited to 'compiler-rt/lib/asan')
-rw-r--r-- | compiler-rt/lib/asan/asan_allocator.cpp | 11 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_fuchsia.cpp | 2 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_internal.h | 10 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_posix.cpp | 28 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_report.cpp | 3 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_rtems.cpp | 2 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_rtl.cpp | 73 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_thread.cpp | 2 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_win.cpp | 2 |
9 files changed, 105 insertions, 28 deletions
diff --git a/compiler-rt/lib/asan/asan_allocator.cpp b/compiler-rt/lib/asan/asan_allocator.cpp index 65c51fbafdd0..126d26d0823b 100644 --- a/compiler-rt/lib/asan/asan_allocator.cpp +++ b/compiler-rt/lib/asan/asan_allocator.cpp @@ -1037,8 +1037,19 @@ uptr PointsIntoChunk(void* p) { return 0; } +// Debug code. Delete once issue #1193 is chased down. +extern "C" SANITIZER_WEAK_ATTRIBUTE const char *__lsan_current_stage; + uptr GetUserBegin(uptr chunk) { __asan::AsanChunk *m = __asan::instance.GetAsanChunkByAddrFastLocked(chunk); + if (!m) + Printf( + "ASAN is about to crash with a CHECK failure.\n" + "The ASAN developers are trying to chase down this bug,\n" + "so if you've encountered this bug please let us know.\n" + "See also: https://github.com/google/sanitizers/issues/1193\n" + "chunk: %p caller %p __lsan_current_stage %s\n", + chunk, GET_CALLER_PC(), __lsan_current_stage); CHECK(m); return m->Beg(); } 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..d7f19d846544 100644 --- a/compiler-rt/lib/asan/asan_posix.cpp +++ b/compiler-rt/lib/asan/asan_posix.cpp @@ -17,6 +17,7 @@ #include "asan_internal.h" #include "asan_interceptors.h" #include "asan_mapping.h" +#include "asan_poisoning.h" #include "asan_report.h" #include "asan_stack.h" #include "sanitizer_common/sanitizer_libc.h" @@ -24,6 +25,7 @@ #include "sanitizer_common/sanitizer_procmaps.h" #include <pthread.h> +#include <signal.h> #include <stdlib.h> #include <sys/time.h> #include <sys/resource.h> @@ -37,6 +39,32 @@ void AsanOnDeadlySignal(int signo, void *siginfo, void *context) { ReportDeadlySignal(sig); } +bool PlatformUnpoisonStacks() { + stack_t signal_stack; + CHECK_EQ(0, sigaltstack(nullptr, &signal_stack)); + uptr sigalt_bottom = (uptr)signal_stack.ss_sp; + uptr sigalt_top = (uptr)((char *)signal_stack.ss_sp + signal_stack.ss_size); + // If we're executing on the signal alternate stack AND the Linux flag + // SS_AUTODISARM was used, then we cannot get the signal alternate stack + // bounds from sigaltstack -- sigaltstack's output looks just as if no + // alternate stack has ever been set up. + // We're always unpoisoning the signal alternate stack to support jumping + // between the default stack and signal alternate stack. + if (signal_stack.ss_flags != SS_DISABLE) + UnpoisonStack(sigalt_bottom, sigalt_top, "sigalt"); + + if (signal_stack.ss_flags != SS_ONSTACK) + return false; + + // Since we're on the signal altnerate stack, we cannot find the DEFAULT + // stack bottom using a local variable. + uptr default_bottom, tls_addr, tls_size, stack_size; + GetThreadStackAndTls(/*main=*/false, &default_bottom, &stack_size, &tls_addr, + &tls_size); + UnpoisonStack(default_bottom, default_bottom + stack_size, "default"); + return true; +} + // ---------------------- TSD ---------------- {{{1 #if SANITIZER_NETBSD && !ASAN_DYNAMIC diff --git a/compiler-rt/lib/asan/asan_report.cpp b/compiler-rt/lib/asan/asan_report.cpp index 2e6ce436d030..99e8678aa785 100644 --- a/compiler-rt/lib/asan/asan_report.cpp +++ b/compiler-rt/lib/asan/asan_report.cpp @@ -160,6 +160,9 @@ class ScopedInErrorReport { BlockingMutexLock l(&error_message_buf_mutex); internal_memcpy(buffer_copy.data(), error_message_buffer, kErrorMessageBufferSize); + // Clear error_message_buffer so that if we find other errors + // we don't re-log this error. + error_message_buffer_pos = 0; } LogFullErrorReport(buffer_copy.data()); 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_thread.cpp b/compiler-rt/lib/asan/asan_thread.cpp index 6734d9a1668c..f0df8bd4b374 100644 --- a/compiler-rt/lib/asan/asan_thread.cpp +++ b/compiler-rt/lib/asan/asan_thread.cpp @@ -480,6 +480,8 @@ bool GetThreadRangesLocked(tid_t os_id, uptr *stack_begin, uptr *stack_end, return true; } +void GetAllThreadAllocatorCachesLocked(InternalMmapVector<uptr> *caches) {} + void ForEachExtraStackRange(tid_t os_id, RangeIteratorCallback callback, void *arg) { __asan::AsanThread *t = __asan::GetAsanThreadByOsIDLocked(os_id); 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 |