[compiler-rt] r341111 - [hwasan] simplify the thread hangling: instead of the ThreadRegistry (too heavy) simply maintain a linked list of Threads
Kostya Serebryany via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 30 13:15:40 PDT 2018
Author: kcc
Date: Thu Aug 30 13:15:39 2018
New Revision: 341111
URL: http://llvm.org/viewvc/llvm-project?rev=341111&view=rev
Log:
[hwasan] simplify the thread hangling: instead of the ThreadRegistry (too heavy) simply maintain a linked list of Threads
Added:
compiler-rt/trunk/test/hwasan/TestCases/many-threads-uaf.c
Modified:
compiler-rt/trunk/lib/hwasan/hwasan.cc
compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc
compiler-rt/trunk/lib/hwasan/hwasan_linux.cc
compiler-rt/trunk/lib/hwasan/hwasan_report.cc
compiler-rt/trunk/lib/hwasan/hwasan_thread.cc
compiler-rt/trunk/lib/hwasan/hwasan_thread.h
Modified: compiler-rt/trunk/lib/hwasan/hwasan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan.cc?rev=341111&r1=341110&r2=341111&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan.cc Thu Aug 30 13:15:39 2018
@@ -183,7 +183,6 @@ void __hwasan_init() {
if (hwasan_inited) return;
hwasan_init_is_running = 1;
SanitizerToolName = "HWAddressSanitizer";
- GetThreadRegistry();
InitTlsSize();
Modified: compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc?rev=341111&r1=341110&r2=341111&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc Thu Aug 30 13:15:39 2018
@@ -292,29 +292,28 @@ INTERCEPTOR(void *, malloc, SIZE_T size)
extern "C" int pthread_attr_init(void *attr);
extern "C" int pthread_attr_destroy(void *attr);
+struct ThreadStartArg {
+ thread_callback_t callback;
+ void *param;
+ // TODO: something crazy is going on with pthread_create overwriting parts
+ // of the stack, hense the padding.
+ char padding[1000];
+};
+
static void *HwasanThreadStartFunc(void *arg) {
__hwasan_thread_enter();
- return ((Thread *)arg)->ThreadStart();
+ ThreadStartArg *A = reinterpret_cast<ThreadStartArg*>(arg);
+ return A->callback(A->param);
}
INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
void * param) {
- ENSURE_HWASAN_INITED(); // for GetTlsSize()
- __sanitizer_pthread_attr_t myattr;
ScopedTaggingDisabler disabler;
- if (!attr) {
- pthread_attr_init(&myattr);
- attr = &myattr;
- }
-
- AdjustStackSize(attr);
-
- Thread *t = Thread::Create(callback, param);
+ ThreadStartArg A;
+ A.callback = callback;
+ A.param = param;
int res = REAL(pthread_create)(UntagPtr(th), UntagPtr(attr),
- HwasanThreadStartFunc, UntagPtr(t));
-
- if (attr == &myattr)
- pthread_attr_destroy(&myattr);
+ &HwasanThreadStartFunc, &A);
return res;
}
#endif // HWASAN_WITH_INTERCEPTORS
Modified: compiler-rt/trunk/lib/hwasan/hwasan_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_linux.cc?rev=341111&r1=341110&r2=341111&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_linux.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_linux.cc Thu Aug 30 13:15:39 2018
@@ -238,6 +238,7 @@ void HwasanTSDDtor(void *tsd) {
CHECK_EQ(0, pthread_setspecific(tsd_key, tsd));
return;
}
+ t->Destroy();
__hwasan_thread_exit();
}
Modified: compiler-rt/trunk/lib/hwasan/hwasan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_report.cc?rev=341111&r1=341110&r2=341111&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_report.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_report.cc Thu Aug 30 13:15:39 2018
@@ -210,7 +210,6 @@ void ReportTagMismatch(StackTrace *stack
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);
Modified: compiler-rt/trunk/lib/hwasan/hwasan_thread.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_thread.cc?rev=341111&r1=341110&r2=341111&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_thread.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_thread.cc Thu Aug 30 13:15:39 2018
@@ -24,6 +24,39 @@ static u32 RandomSeed() {
return seed;
}
+static Thread *main_thread;
+static SpinMutex thread_list_mutex;
+
+void Thread::InsertIntoThreadList(Thread *t) {
+ CHECK(!t->next_);
+ if (!main_thread) {
+ main_thread = t;
+ return;
+ }
+ SpinMutexLock l(&thread_list_mutex);
+ Thread *last = main_thread;
+ while (last->next_)
+ last = last->next_;
+ last->next_ = t;
+}
+
+void Thread::RemoveFromThreadList(Thread *t) {
+ CHECK_NE(t, main_thread);
+ SpinMutexLock l(&thread_list_mutex);
+ Thread *prev = main_thread;
+ Thread *cur = prev->next_;
+ CHECK(cur);
+ while (cur) {
+ if (cur == t) {
+ prev->next_ = cur->next_;
+ return;
+ }
+ prev = cur;
+ cur = cur->next_;
+ }
+ CHECK(0 && "RemoveFromThreadList: thread not found");
+}
+
Thread *Thread::Create(thread_callback_t start_routine,
void *arg) {
uptr PageSize = GetPageSizeCached();
@@ -33,11 +66,9 @@ Thread *Thread::Create(thread_callback_t
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);
+ InsertIntoThreadList(thread);
return thread;
}
@@ -80,6 +111,7 @@ void Thread::ClearShadowForThreadStackAn
void Thread::Destroy() {
malloc_storage().CommitBack();
ClearShadowForThreadStackAndTLS();
+ RemoveFromThreadList(this);
uptr size = RoundUpTo(sizeof(Thread), GetPageSizeCached());
if (heap_allocations_)
heap_allocations_->Delete();
@@ -87,10 +119,6 @@ void Thread::Destroy() {
DTLS_Destroy();
}
-thread_return_t Thread::ThreadStart() {
- return start_routine_(arg_);
-}
-
static u32 xorshift(u32 state) {
state ^= state << 13;
state ^= state >> 17;
@@ -115,32 +143,4 @@ tag_t Thread::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
Modified: compiler-rt/trunk/lib/hwasan/hwasan_thread.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_thread.h?rev=341111&r1=341110&r2=341111&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_thread.h (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_thread.h Thu Aug 30 13:15:39 2018
@@ -16,37 +16,15 @@
#include "hwasan_allocator.h"
#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_thread_registry.h"
namespace __hwasan {
-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 Thread *Create(thread_callback_t start_routine, void *arg);
void Destroy();
void Init();
- thread_return_t ThreadStart();
uptr stack_top() { return stack_top_; }
uptr stack_bottom() { return stack_bottom_; }
@@ -75,9 +53,6 @@ class Thread {
return heap_allocations_;
}
- void set_context(ThreadContext *context) { context_ = context; }
- const ThreadContext *context() const { return context_; }
-
tag_t GenerateRandomTag();
int destructor_iterations_;
@@ -107,8 +82,9 @@ class Thread {
HwasanThreadLocalMallocStorage malloc_storage_;
HeapAllocationsRingBuffer *heap_allocations_;
- u32 tid_;
- ThreadContext *context_;
+ static void InsertIntoThreadList(Thread *t);
+ static void RemoveFromThreadList(Thread *t);
+ Thread *next_; // All live threads form a linked list.
u32 tagging_disabled_; // if non-zero, malloc uses zero tag in this thread.
};
@@ -116,16 +92,11 @@ class Thread {
Thread *GetCurrentThread();
void SetCurrentThread(Thread *t);
-// Returns the ThreadRegistry singleton.
-ThreadRegistry &GetThreadRegistry();
-
struct ScopedTaggingDisabler {
ScopedTaggingDisabler() { GetCurrentThread()->DisableTagging(); }
~ScopedTaggingDisabler() { GetCurrentThread()->EnableTagging(); }
};
-// Returns the ThreadRegistry singleton.
-
} // namespace __hwasan
#endif // HWASAN_THREAD_H
Added: compiler-rt/trunk/test/hwasan/TestCases/many-threads-uaf.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/hwasan/TestCases/many-threads-uaf.c?rev=341111&view=auto
==============================================================================
--- compiler-rt/trunk/test/hwasan/TestCases/many-threads-uaf.c (added)
+++ compiler-rt/trunk/test/hwasan/TestCases/many-threads-uaf.c Thu Aug 30 13:15:39 2018
@@ -0,0 +1,37 @@
+// RUN: %clang_hwasan %s -o %t && not %run %t 2>&1 | FileCheck %s
+// REQUIRES: stable-runtime
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <sanitizer/hwasan_interface.h>
+
+void *BoringThread(void *arg) {
+ char * volatile x = (char*)malloc(10);
+ x[5] = 0;
+ free(x);
+ return NULL;
+}
+
+void *UAFThread(void *arg) {
+ char * volatile x = (char*)malloc(10);
+ fprintf(stderr, "ZZZ %p\n", x);
+ free(x);
+ x[5] = 42;
+ // CHECK: ERROR: HWAddressSanitizer: tag-mismatch on address
+ // CHECK: WRITE of size 1
+ // CHECK: many-threads-uaf.c:[[@LINE-3]]
+ return NULL;
+}
+
+int main() {
+ __hwasan_enable_allocator_tagging();
+ pthread_t t;
+ for (int i = 0; i < 1100; i++) {
+ pthread_create(&t, NULL, BoringThread, NULL);
+ pthread_join(t, NULL);
+ }
+ pthread_create(&t, NULL, UAFThread, NULL);
+ pthread_join(t, NULL);
+}
More information about the llvm-commits
mailing list