mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-03 19:32:35 +00:00
[hwasan] Reset current thread pointer on thread exit.
Summary: This is necessary to handle calls to free() after __hwasan_thread_exit, which is possible in glibc. Also, add a null check to GetCurrentThread, otherwise the logic in GetThreadByBufferAddress turns it into a non-null value. This means that all of the checks for GetCurrentThread() != nullptr do not have any effect at all right now! Reviewers: pcc, hctim Subscribers: #sanitizers, llvm-commits Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D79608
This commit is contained in:
parent
fcf10d1908
commit
eaea9ed835
@ -186,7 +186,7 @@ void __sanitizer::BufferedStackTrace::UnwindImpl(
|
||||
uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
|
||||
Thread *t = GetCurrentThread();
|
||||
if (!t) {
|
||||
// the thread is still being created.
|
||||
// The thread is still being created, or has already been destroyed.
|
||||
size = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -354,8 +354,11 @@ void AndroidTestTlsSlot() {}
|
||||
#endif
|
||||
|
||||
Thread *GetCurrentThread() {
|
||||
auto *R = (StackAllocationsRingBuffer *)GetCurrentThreadLongPtr();
|
||||
return hwasanThreadList().GetThreadByBufferAddress((uptr)(R->Next()));
|
||||
uptr *ThreadLongPtr = GetCurrentThreadLongPtr();
|
||||
if (UNLIKELY(*ThreadLongPtr == 0))
|
||||
return nullptr;
|
||||
auto *R = (StackAllocationsRingBuffer *)ThreadLongPtr;
|
||||
return hwasanThreadList().GetThreadByBufferAddress((uptr)R->Next());
|
||||
}
|
||||
|
||||
struct AccessInfo {
|
||||
|
@ -90,6 +90,12 @@ void Thread::Destroy() {
|
||||
if (heap_allocations_)
|
||||
heap_allocations_->Delete();
|
||||
DTLS_Destroy();
|
||||
// Unregister this as the current thread.
|
||||
// Instrumented code can not run on this thread from this point onwards, but
|
||||
// malloc/free can still be served. Glibc may call free() very late, after all
|
||||
// TSD destructors are done.
|
||||
CHECK_EQ(GetCurrentThread(), this);
|
||||
*GetCurrentThreadLongPtr() = 0;
|
||||
}
|
||||
|
||||
void Thread::Print(const char *Prefix) {
|
||||
|
22
compiler-rt/test/hwasan/TestCases/libc_thread_freeres.c
Normal file
22
compiler-rt/test/hwasan/TestCases/libc_thread_freeres.c
Normal file
@ -0,0 +1,22 @@
|
||||
// RUN: %clang_hwasan %s -o %t && %env_hwasan_opts=random_tags=1 %run %t
|
||||
// REQUIRES: stable-runtime
|
||||
|
||||
#include <pthread.h>
|
||||
#include <sanitizer/hwasan_interface.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void *ThreadFn(void *) {
|
||||
strerror_l(-1, 0);
|
||||
__hwasan_enable_allocator_tagging();
|
||||
// This will trigger memory deallocation in __strerror_thread_freeres,
|
||||
// at a point when HwasanThread is already gone.
|
||||
}
|
||||
|
||||
int main() {
|
||||
pthread_t t;
|
||||
pthread_create(&t, NULL, ThreadFn, NULL);
|
||||
pthread_join(t, NULL);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user