1 2 #include "msan.h" 3 #include "msan_thread.h" 4 #include "msan_interface_internal.h" 5 6 #include "sanitizer_common/sanitizer_tls_get_addr.h" 7 8 namespace __msan { 9 10 MsanThread *MsanThread::Create(thread_callback_t start_routine, 11 void *arg) { 12 uptr PageSize = GetPageSizeCached(); 13 uptr size = RoundUpTo(sizeof(MsanThread), PageSize); 14 MsanThread *thread = (MsanThread*)MmapOrDie(size, __func__); 15 thread->start_routine_ = start_routine; 16 thread->arg_ = arg; 17 thread->destructor_iterations_ = GetPthreadDestructorIterations(); 18 19 return thread; 20 } 21 22 void MsanThread::SetThreadStackAndTls() { 23 uptr tls_size = 0; 24 uptr stack_size = 0; 25 GetThreadStackAndTls(IsMainThread(), &stack_bottom_, &stack_size, 26 &tls_begin_, &tls_size); 27 stack_top_ = stack_bottom_ + stack_size; 28 tls_end_ = tls_begin_ + tls_size; 29 30 int local; 31 CHECK(AddrIsInStack((uptr)&local)); 32 } 33 34 void MsanThread::ClearShadowForThreadStackAndTLS() { 35 __msan_unpoison((void *)stack_bottom_, stack_top_ - stack_bottom_); 36 if (tls_begin_ != tls_end_) 37 __msan_unpoison((void *)tls_begin_, tls_end_ - tls_begin_); 38 DTLS *dtls = DTLS_Get(); 39 CHECK_NE(dtls, 0); 40 for (uptr i = 0; i < dtls->dtv_size; ++i) 41 __msan_unpoison((void *)(dtls->dtv[i].beg), dtls->dtv[i].size); 42 } 43 44 void MsanThread::Init() { 45 SetThreadStackAndTls(); 46 CHECK(MEM_IS_APP(stack_bottom_)); 47 CHECK(MEM_IS_APP(stack_top_ - 1)); 48 ClearShadowForThreadStackAndTLS(); 49 } 50 51 void MsanThread::TSDDtor(void *tsd) { 52 MsanThread *t = (MsanThread*)tsd; 53 t->Destroy(); 54 } 55 56 void MsanThread::Destroy() { 57 malloc_storage().CommitBack(); 58 // We also clear the shadow on thread destruction because 59 // some code may still be executing in later TSD destructors 60 // and we don't want it to have any poisoned stack. 61 ClearShadowForThreadStackAndTLS(); 62 uptr size = RoundUpTo(sizeof(MsanThread), GetPageSizeCached()); 63 UnmapOrDie(this, size); 64 DTLS_Destroy(); 65 } 66 67 thread_return_t MsanThread::ThreadStart() { 68 Init(); 69 70 if (!start_routine_) { 71 // start_routine_ == 0 if we're on the main thread or on one of the 72 // OS X libdispatch worker threads. But nobody is supposed to call 73 // ThreadStart() for the worker threads. 74 return 0; 75 } 76 77 thread_return_t res = start_routine_(arg_); 78 79 return res; 80 } 81 82 } // namespace __msan 83