Backport from llvm upstream (monorepo revision 91167e2). This was an experiment made possible by a non-standard feature of the Android dynamic loader.
libsanitizer/ChangeLog: 2019-11-05 Matthew Malcomson <matthew.malcom...@arm.com> * hwasan/hwasan_interceptors.cpp (HwasanThreadStartFunc): Re-introduce. (pthread_create): Use HwasanThreadStartFunc to initialise the sanitizer for each thread as it starts. * hwasan/hwasan_linux.cpp (GetCurrentThread): Assume thread is initialised. ############### Attachment also inlined for ease of reply ############### diff --git a/libsanitizer/hwasan/hwasan_interceptors.cpp b/libsanitizer/hwasan/hwasan_interceptors.cpp index 4f9bd3469eb10ca2cf3108326308e45e7a9d38b6..44e569ee6d721a99a3333a21ebf1a51fb33b6e7a 100644 --- a/libsanitizer/hwasan/hwasan_interceptors.cpp +++ b/libsanitizer/hwasan/hwasan_interceptors.cpp @@ -202,23 +202,33 @@ INTERCEPTOR_ALIAS(__sanitizer_struct_mallinfo, mallinfo); INTERCEPTOR_ALIAS(int, mallopt, int cmd, int value); INTERCEPTOR_ALIAS(void, malloc_stats, void); #endif -#endif // HWASAN_WITH_INTERCEPTORS +struct ThreadStartArg { + thread_callback_t callback; + void *param; +}; + +static void *HwasanThreadStartFunc(void *arg) { + __hwasan_thread_enter(); + ThreadStartArg A = *reinterpret_cast<ThreadStartArg*>(arg); + UnmapOrDie(arg, GetPageSizeCached()); + return A.callback(A.param); +} -#if HWASAN_WITH_INTERCEPTORS && !defined(__aarch64__) -INTERCEPTOR(int, pthread_create, void *th, void *attr, - void *(*callback)(void *), void *param) { +INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), + void * param) { ScopedTaggingDisabler disabler; + ThreadStartArg *A = reinterpret_cast<ThreadStartArg *> (MmapOrDie( + GetPageSizeCached(), "pthread_create")); + *A = {callback, param}; int res = REAL(pthread_create)(UntagPtr(th), UntagPtr(attr), - callback, param); + &HwasanThreadStartFunc, A); return res; } -#endif -#if HWASAN_WITH_INTERCEPTORS DEFINE_REAL(int, vfork) DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(int, vfork) -#endif +#endif // HWASAN_WITH_INTERCEPTORS #if HWASAN_WITH_INTERCEPTORS && defined(__aarch64__) // Get and/or change the set of blocked signals. @@ -331,9 +341,7 @@ void InitializeInterceptors() { #if defined(__linux__) INTERCEPT_FUNCTION(vfork); #endif // __linux__ -#if !defined(__aarch64__) INTERCEPT_FUNCTION(pthread_create); -#endif // __aarch64__ #endif inited = 1; diff --git a/libsanitizer/hwasan/hwasan_linux.cpp b/libsanitizer/hwasan/hwasan_linux.cpp index dfef11883a284dae0c96cfcc6a8fd1cc06c24d71..ed0f30161b023bf5927aa4a471f6a7c3edc8edf6 100644 --- a/libsanitizer/hwasan/hwasan_linux.cpp +++ b/libsanitizer/hwasan/hwasan_linux.cpp @@ -354,12 +354,7 @@ void AndroidTestTlsSlot() {} #endif Thread *GetCurrentThread() { - uptr *ThreadLong = GetCurrentThreadLongPtr(); -#if HWASAN_WITH_INTERCEPTORS - if (!*ThreadLong) - __hwasan_thread_enter(); -#endif - auto *R = (StackAllocationsRingBuffer *)ThreadLong; + auto *R = (StackAllocationsRingBuffer *)GetCurrentThreadLongPtr(); return hwasanThreadList().GetThreadByBufferAddress((uptr)(R->Next())); }
diff --git a/libsanitizer/hwasan/hwasan_interceptors.cpp b/libsanitizer/hwasan/hwasan_interceptors.cpp index 4f9bd3469eb10ca2cf3108326308e45e7a9d38b6..44e569ee6d721a99a3333a21ebf1a51fb33b6e7a 100644 --- a/libsanitizer/hwasan/hwasan_interceptors.cpp +++ b/libsanitizer/hwasan/hwasan_interceptors.cpp @@ -202,23 +202,33 @@ INTERCEPTOR_ALIAS(__sanitizer_struct_mallinfo, mallinfo); INTERCEPTOR_ALIAS(int, mallopt, int cmd, int value); INTERCEPTOR_ALIAS(void, malloc_stats, void); #endif -#endif // HWASAN_WITH_INTERCEPTORS +struct ThreadStartArg { + thread_callback_t callback; + void *param; +}; + +static void *HwasanThreadStartFunc(void *arg) { + __hwasan_thread_enter(); + ThreadStartArg A = *reinterpret_cast<ThreadStartArg*>(arg); + UnmapOrDie(arg, GetPageSizeCached()); + return A.callback(A.param); +} -#if HWASAN_WITH_INTERCEPTORS && !defined(__aarch64__) -INTERCEPTOR(int, pthread_create, void *th, void *attr, - void *(*callback)(void *), void *param) { +INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), + void * param) { ScopedTaggingDisabler disabler; + ThreadStartArg *A = reinterpret_cast<ThreadStartArg *> (MmapOrDie( + GetPageSizeCached(), "pthread_create")); + *A = {callback, param}; int res = REAL(pthread_create)(UntagPtr(th), UntagPtr(attr), - callback, param); + &HwasanThreadStartFunc, A); return res; } -#endif -#if HWASAN_WITH_INTERCEPTORS DEFINE_REAL(int, vfork) DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(int, vfork) -#endif +#endif // HWASAN_WITH_INTERCEPTORS #if HWASAN_WITH_INTERCEPTORS && defined(__aarch64__) // Get and/or change the set of blocked signals. @@ -331,9 +341,7 @@ void InitializeInterceptors() { #if defined(__linux__) INTERCEPT_FUNCTION(vfork); #endif // __linux__ -#if !defined(__aarch64__) INTERCEPT_FUNCTION(pthread_create); -#endif // __aarch64__ #endif inited = 1; diff --git a/libsanitizer/hwasan/hwasan_linux.cpp b/libsanitizer/hwasan/hwasan_linux.cpp index dfef11883a284dae0c96cfcc6a8fd1cc06c24d71..ed0f30161b023bf5927aa4a471f6a7c3edc8edf6 100644 --- a/libsanitizer/hwasan/hwasan_linux.cpp +++ b/libsanitizer/hwasan/hwasan_linux.cpp @@ -354,12 +354,7 @@ void AndroidTestTlsSlot() {} #endif Thread *GetCurrentThread() { - uptr *ThreadLong = GetCurrentThreadLongPtr(); -#if HWASAN_WITH_INTERCEPTORS - if (!*ThreadLong) - __hwasan_thread_enter(); -#endif - auto *R = (StackAllocationsRingBuffer *)ThreadLong; + auto *R = (StackAllocationsRingBuffer *)GetCurrentThreadLongPtr(); return hwasanThreadList().GetThreadByBufferAddress((uptr)(R->Next())); }