diff options
-rw-r--r-- | compiler-rt/lib/hwasan/hwasan.cc | 13 | ||||
-rw-r--r-- | compiler-rt/lib/hwasan/hwasan_allocator.cc | 4 | ||||
-rw-r--r-- | compiler-rt/lib/hwasan/hwasan_interceptors.cc | 10 | ||||
-rw-r--r-- | compiler-rt/lib/hwasan/hwasan_linux.cc | 20 | ||||
-rw-r--r-- | compiler-rt/lib/hwasan/hwasan_report.cc | 6 | ||||
-rw-r--r-- | compiler-rt/lib/hwasan/hwasan_thread.cc | 52 | ||||
-rw-r--r-- | compiler-rt/lib/hwasan/hwasan_thread.h | 42 |
7 files changed, 107 insertions, 40 deletions
diff --git a/compiler-rt/lib/hwasan/hwasan.cc b/compiler-rt/lib/hwasan/hwasan.cc index d6996678511..2bf304be105 100644 --- a/compiler-rt/lib/hwasan/hwasan.cc +++ b/compiler-rt/lib/hwasan/hwasan.cc @@ -36,17 +36,17 @@ using namespace __sanitizer; namespace __hwasan { void EnterSymbolizer() { - HwasanThread *t = GetCurrentThread(); + Thread *t = GetCurrentThread(); CHECK(t); t->EnterSymbolizer(); } void ExitSymbolizer() { - HwasanThread *t = GetCurrentThread(); + Thread *t = GetCurrentThread(); CHECK(t); t->LeaveSymbolizer(); } bool IsInSymbolizer() { - HwasanThread *t = GetCurrentThread(); + Thread *t = GetCurrentThread(); return t && t->InSymbolizer(); } @@ -132,7 +132,7 @@ static void InitializeFlags() { void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp, void *context, bool request_fast_unwind) { - HwasanThread *t = GetCurrentThread(); + Thread *t = GetCurrentThread(); if (!t || !StackTrace::WillUseFastUnwind(request_fast_unwind)) { // Block reports from our interceptors during _Unwind_Backtrace. SymbolizerScope sym_scope; @@ -178,6 +178,7 @@ void __hwasan_init() { if (hwasan_inited) return; hwasan_init_is_running = 1; SanitizerToolName = "HWAddressSanitizer"; + GetThreadRegistry(); InitTlsSize(); @@ -208,7 +209,7 @@ void __hwasan_init() { HwasanAllocatorInit(); - HwasanThread *main_thread = HwasanThread::Create(nullptr, nullptr); + Thread *main_thread = Thread::Create(nullptr, nullptr); SetCurrentThread(main_thread); main_thread->Init(); @@ -428,7 +429,7 @@ void __hwasan_handle_longjmp(const void *sp_dst) { static const u8 kFallbackTag = 0xBB; u8 __hwasan_generate_tag() { - HwasanThread *t = GetCurrentThread(); + Thread *t = GetCurrentThread(); if (!t) return kFallbackTag; return t->GenerateRandomTag(); } diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.cc b/compiler-rt/lib/hwasan/hwasan_allocator.cc index 5632d9829f1..ee71e7ba4cc 100644 --- a/compiler-rt/lib/hwasan/hwasan_allocator.cc +++ b/compiler-rt/lib/hwasan/hwasan_allocator.cc @@ -136,7 +136,7 @@ static void *HwasanAllocate(StackTrace *stack, uptr size, uptr alignment, } ReportAllocationSizeTooBig(size, kMaxAllowedMallocSize, stack); } - HwasanThread *t = GetCurrentThread(); + Thread *t = GetCurrentThread(); void *allocated; if (t) { AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage()); @@ -199,7 +199,7 @@ void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) { meta->free_context_id = free_context_id; // This memory will not be reused by anyone else, so we are free to keep it // poisoned. - HwasanThread *t = GetCurrentThread(); + Thread *t = GetCurrentThread(); if (flags()->max_free_fill_size > 0) { uptr fill_size = Min(size, (uptr)flags()->max_free_fill_size); internal_memset(untagged_ptr, flags()->free_fill_byte, fill_size); diff --git a/compiler-rt/lib/hwasan/hwasan_interceptors.cc b/compiler-rt/lib/hwasan/hwasan_interceptors.cc index 7d083a942db..4f2ab7037e9 100644 --- a/compiler-rt/lib/hwasan/hwasan_interceptors.cc +++ b/compiler-rt/lib/hwasan/hwasan_interceptors.cc @@ -50,18 +50,18 @@ DECLARE_REAL(void *, memcpy, void *dest, const void *src, uptr n) DECLARE_REAL(void *, memset, void *dest, int c, uptr n) bool IsInInterceptorScope() { - HwasanThread *t = GetCurrentThread(); + Thread *t = GetCurrentThread(); return t && t->InInterceptorScope(); } struct InterceptorScope { InterceptorScope() { - HwasanThread *t = GetCurrentThread(); + Thread *t = GetCurrentThread(); if (t) t->EnterInterceptorScope(); } ~InterceptorScope() { - HwasanThread *t = GetCurrentThread(); + Thread *t = GetCurrentThread(); if (t) t->LeaveInterceptorScope(); } @@ -294,7 +294,7 @@ extern "C" int pthread_attr_destroy(void *attr); static void *HwasanThreadStartFunc(void *arg) { __hwasan_thread_enter(); - return ((HwasanThread *)arg)->ThreadStart(); + return ((Thread *)arg)->ThreadStart(); } INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), @@ -308,7 +308,7 @@ INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), AdjustStackSize(attr); - HwasanThread *t = HwasanThread::Create(callback, param); + Thread *t = Thread::Create(callback, param); int res = REAL(pthread_create)(th, attr, HwasanThreadStartFunc, t); diff --git a/compiler-rt/lib/hwasan/hwasan_linux.cc b/compiler-rt/lib/hwasan/hwasan_linux.cc index d362b0cb460..80c95f0c3f0 100644 --- a/compiler-rt/lib/hwasan/hwasan_linux.cc +++ b/compiler-rt/lib/hwasan/hwasan_linux.cc @@ -214,13 +214,13 @@ void InstallAtExitHandler() { // ---------------------- TSD ---------------- {{{1 extern "C" void __hwasan_thread_enter() { - HwasanThread *t = HwasanThread::Create(nullptr, nullptr); + Thread *t = Thread::Create(nullptr, nullptr); SetCurrentThread(t); t->Init(); } extern "C" void __hwasan_thread_exit() { - HwasanThread *t = GetCurrentThread(); + Thread *t = GetCurrentThread(); // Make sure that signal handler can not see a stale current thread pointer. atomic_signal_fence(memory_order_seq_cst); if (t) @@ -232,7 +232,7 @@ static pthread_key_t tsd_key; static bool tsd_key_inited = false; void HwasanTSDDtor(void *tsd) { - HwasanThread *t = (HwasanThread*)tsd; + Thread *t = (Thread*)tsd; if (t->destructor_iterations_ > 1) { t->destructor_iterations_--; CHECK_EQ(0, pthread_setspecific(tsd_key, tsd)); @@ -247,24 +247,24 @@ void HwasanTSDInit() { CHECK_EQ(0, pthread_key_create(&tsd_key, HwasanTSDDtor)); } -HwasanThread *GetCurrentThread() { - return (HwasanThread *)pthread_getspecific(tsd_key); +Thread *GetCurrentThread() { + return (Thread *)pthread_getspecific(tsd_key); } -void SetCurrentThread(HwasanThread *t) { +void SetCurrentThread(Thread *t) { // Make sure that HwasanTSDDtor gets called at the end. CHECK(tsd_key_inited); - // Make sure we do not reset the current HwasanThread. + // Make sure we do not reset the current Thread. CHECK_EQ(0, pthread_getspecific(tsd_key)); pthread_setspecific(tsd_key, (void *)t); } #elif SANITIZER_ANDROID void HwasanTSDInit() {} -HwasanThread *GetCurrentThread() { - return (HwasanThread*)*get_android_tls_ptr(); +Thread *GetCurrentThread() { + return (Thread*)*get_android_tls_ptr(); } -void SetCurrentThread(HwasanThread *t) { +void SetCurrentThread(Thread *t) { *get_android_tls_ptr() = (uptr)t; } #else diff --git a/compiler-rt/lib/hwasan/hwasan_report.cc b/compiler-rt/lib/hwasan/hwasan_report.cc index 516c030161c..47073e00c27 100644 --- a/compiler-rt/lib/hwasan/hwasan_report.cc +++ b/compiler-rt/lib/hwasan/hwasan_report.cc @@ -206,10 +206,12 @@ void ReportTagMismatch(StackTrace *stack, uptr tagged_addr, uptr access_size, // * remove reduntant fields from the allocator metadata // * use the allocations found in the ring buffer for the main report. HeapAllocationRecord har; - HwasanThread *t = GetCurrentThread(); - if (t && FindHeapAllocation(t->heap_allocations(), tagged_addr, &har)) + Thread *t = GetCurrentThread(); + if (FindHeapAllocation(t->heap_allocations(), tagged_addr, &har)) Printf("Address found in the ring buffer: %p %u %u\n", har.tagged_addr, har.free_context_id, har.requested_size); + Printf("Current thread: tid: %d\n", t->context()->tid); + PrintTagsAroundAddr(tag_ptr); diff --git a/compiler-rt/lib/hwasan/hwasan_thread.cc b/compiler-rt/lib/hwasan/hwasan_thread.cc index 14ecb3ec96a..af137c05379 100644 --- a/compiler-rt/lib/hwasan/hwasan_thread.cc +++ b/compiler-rt/lib/hwasan/hwasan_thread.cc @@ -6,6 +6,7 @@ #include "hwasan_interface_internal.h" #include "sanitizer_common/sanitizer_file.h" +#include "sanitizer_common/sanitizer_placement_new.h" #include "sanitizer_common/sanitizer_tls_get_addr.h" namespace __hwasan { @@ -23,21 +24,24 @@ static u32 RandomSeed() { return seed; } -HwasanThread *HwasanThread::Create(thread_callback_t start_routine, +Thread *Thread::Create(thread_callback_t start_routine, void *arg) { uptr PageSize = GetPageSizeCached(); - uptr size = RoundUpTo(sizeof(HwasanThread), PageSize); - HwasanThread *thread = (HwasanThread*)MmapOrDie(size, __func__); + uptr size = RoundUpTo(sizeof(Thread), PageSize); + Thread *thread = (Thread*)MmapOrDie(size, __func__); thread->start_routine_ = start_routine; thread->arg_ = arg; thread->destructor_iterations_ = GetPthreadDestructorIterations(); thread->random_state_ = flags()->random_tags ? RandomSeed() : 0; + thread->context_ = nullptr; + ThreadContext::Args args = {thread}; + thread->tid_ = GetThreadRegistry().CreateThread(0, false, 0, &args); if (auto sz = flags()->heap_history_size) thread->heap_allocations_ = RingBuffer<HeapAllocationRecord>::New(sz); return thread; } -void HwasanThread::SetThreadStackAndTls() { +void Thread::SetThreadStackAndTls() { // If this process is "init" (pid 1), /proc may not be mounted yet. if (IsMainThread() && !FileExists("/proc/self/maps")) { stack_top_ = stack_bottom_ = 0; @@ -58,7 +62,7 @@ void HwasanThread::SetThreadStackAndTls() { CHECK(MemIsApp(stack_top_ - 1)); } -void HwasanThread::Init() { +void Thread::Init() { SetThreadStackAndTls(); if (stack_bottom_) { CHECK(MemIsApp(stack_bottom_)); @@ -66,24 +70,24 @@ void HwasanThread::Init() { } } -void HwasanThread::ClearShadowForThreadStackAndTLS() { +void Thread::ClearShadowForThreadStackAndTLS() { if (stack_top_ != stack_bottom_) TagMemory(stack_bottom_, stack_top_ - stack_bottom_, 0); if (tls_begin_ != tls_end_) TagMemory(tls_begin_, tls_end_ - tls_begin_, 0); } -void HwasanThread::Destroy() { +void Thread::Destroy() { malloc_storage().CommitBack(); ClearShadowForThreadStackAndTLS(); - uptr size = RoundUpTo(sizeof(HwasanThread), GetPageSizeCached()); + uptr size = RoundUpTo(sizeof(Thread), GetPageSizeCached()); if (heap_allocations_) heap_allocations_->Delete(); UnmapOrDie(this, size); DTLS_Destroy(); } -thread_return_t HwasanThread::ThreadStart() { +thread_return_t Thread::ThreadStart() { return start_routine_(arg_); } @@ -95,7 +99,7 @@ static u32 xorshift(u32 state) { } // Generate a (pseudo-)random non-zero tag. -tag_t HwasanThread::GenerateRandomTag() { +tag_t Thread::GenerateRandomTag() { tag_t tag; do { if (flags()->random_tags) { @@ -111,4 +115,32 @@ tag_t HwasanThread::GenerateRandomTag() { return tag; } +void ThreadContext::OnCreated(void *arg) { + Args *args = static_cast<Args*>(arg); + thread = args->thread; + thread->set_context(this); +} + +void ThreadContext::OnFinished() { + thread = nullptr; +} + +static const u32 kMaxLiveThreads = 1024; + +static ThreadContextBase *ThreadContextFactory(u32 tid) { + static ALIGNED(16) char placeholder[sizeof(ThreadContext) * kMaxLiveThreads]; + void *mem = &placeholder[0] + tid * sizeof(ThreadContext); + CHECK_LT(tid, kMaxLiveThreads); + return new (mem) ThreadContext(tid); +} + +ThreadRegistry &GetThreadRegistry() { + static ALIGNED(16) char placeholder[sizeof(ThreadRegistry)]; + static ThreadRegistry *registry; + if (!registry) + registry = new (placeholder) + ThreadRegistry(ThreadContextFactory, kMaxLiveThreads, kMaxLiveThreads); + return *registry; +} + } // namespace __hwasan diff --git a/compiler-rt/lib/hwasan/hwasan_thread.h b/compiler-rt/lib/hwasan/hwasan_thread.h index d21151b3a5f..e4f46b1085a 100644 --- a/compiler-rt/lib/hwasan/hwasan_thread.h +++ b/compiler-rt/lib/hwasan/hwasan_thread.h @@ -16,12 +16,33 @@ #include "hwasan_allocator.h" #include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_thread_registry.h" namespace __hwasan { -class HwasanThread { +class Thread; + +class ThreadContext : public ThreadContextBase { + public: + explicit ThreadContext(int tid) + : ThreadContextBase(tid), thread(nullptr){} + + Thread *thread; + + void OnCreated(void *arg) override; + void OnFinished() override; + + struct Args { + Thread *thread; + }; +}; + +// We want this to be small. +COMPILER_CHECK(sizeof(ThreadContext) <= 256); + +class Thread { public: - static HwasanThread *Create(thread_callback_t start_routine, void *arg); + static Thread *Create(thread_callback_t start_routine, void *arg); void Destroy(); void Init(); @@ -54,12 +75,15 @@ class HwasanThread { return heap_allocations_; } + void set_context(ThreadContext *context) { context_ = context; } + const ThreadContext *context() const { return context_; } + tag_t GenerateRandomTag(); int destructor_iterations_; private: - // NOTE: There is no HwasanThread constructor. It is allocated + // NOTE: There is no Thread constructor. It is allocated // via mmap() and *must* be valid in zero-initialized state. void SetThreadStackAndTls(); void ClearShadowForThreadStackAndTLS(); @@ -79,10 +103,18 @@ class HwasanThread { HwasanThreadLocalMallocStorage malloc_storage_; HeapAllocationsRingBuffer *heap_allocations_; + + u32 tid_; + ThreadContext *context_; }; -HwasanThread *GetCurrentThread(); -void SetCurrentThread(HwasanThread *t); +Thread *GetCurrentThread(); +void SetCurrentThread(Thread *t); + +// Returns the ThreadRegistry singleton. +ThreadRegistry &GetThreadRegistry(); + +// Returns the ThreadRegistry singleton. } // namespace __hwasan |