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 <[email protected]>
* 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()));
}