[hwasan] Fix data race between ReleaseThread() and VisitAllLiveThreads()
authorEnna1 <xumingjie.enna1@bytedance.com>
Fri, 5 May 2023 10:38:19 +0000 (18:38 +0800)
committerEnna1 <xumingjie.enna1@bytedance.com>
Fri, 5 May 2023 10:39:00 +0000 (18:39 +0800)
Data race scenario:
```
Thread 1                                | Thread 2
ReportTagMismatch()                     |
Call VisitAllLiveThreads() to scan all  |
threads' ring buffers to find           |
if it's a heap-use-after-free.          |
Lock live_list_mutex_                   |
                                        | Thread 2 exit
                                        | ReleaseThread() calls Thread::Destroy() for Thread 2,
                                        | which frees heap alloctions ring buffer
                                        | RemoveThreadFromLiveList() tries to take live_list_mutex_ again
Iterate the heap alloctions ring buffer |
of Thread 2, which is already freed     |
```

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D148909

compiler-rt/lib/hwasan/hwasan_thread_list.h

index 99d2d46..52290b5 100644 (file)
@@ -131,9 +131,9 @@ class SANITIZER_MUTEX HwasanThreadList {
 
   void ReleaseThread(Thread *t) SANITIZER_EXCLUDES(free_list_mutex_) {
     RemoveThreadStats(t);
+    RemoveThreadFromLiveList(t);
     t->Destroy();
     DontNeedThread(t);
-    RemoveThreadFromLiveList(t);
     SpinMutexLock l(&free_list_mutex_);
     free_list_.push_back(t);
   }