diff options
-rw-r--r-- | compiler-rt/lib/msan/msan.cc | 1 | ||||
-rw-r--r-- | compiler-rt/lib/msan/msan_interceptors.cc | 11 | ||||
-rw-r--r-- | compiler-rt/lib/msan/msan_thread.cc | 6 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc | 6 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.cc | 10 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.h | 4 | ||||
-rw-r--r-- | compiler-rt/test/msan/dtls_test.c | 10 |
7 files changed, 34 insertions, 14 deletions
diff --git a/compiler-rt/lib/msan/msan.cc b/compiler-rt/lib/msan/msan.cc index bd5545fb46d..84f1bc6ff39 100644 --- a/compiler-rt/lib/msan/msan.cc +++ b/compiler-rt/lib/msan/msan.cc @@ -162,6 +162,7 @@ static void InitializeFlags(Flags *f, const char *options) { cf->handle_ioctl = true; // FIXME: test and enable. cf->check_printf = false; + cf->intercept_tls_get_addr = true; internal_memset(f, 0, sizeof(*f)); f->poison_heap_with_zeroes = false; diff --git a/compiler-rt/lib/msan/msan_interceptors.cc b/compiler-rt/lib/msan/msan_interceptors.cc index c7f41248427..7525818caec 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cc +++ b/compiler-rt/lib/msan/msan_interceptors.cc @@ -28,6 +28,7 @@ #include "sanitizer_common/sanitizer_stackdepot.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_linux.h" +#include "sanitizer_common/sanitizer_tls_get_addr.h" #include <stdarg.h> // ACHTUNG! No other system header includes in this file. @@ -161,8 +162,13 @@ INTERCEPTOR(void *, memalign, SIZE_T boundary, SIZE_T size) { return ptr; } -INTERCEPTOR(void *, __libc_memalign, uptr align, uptr s) - ALIAS(WRAPPER_NAME(memalign)); +INTERCEPTOR(void *, __libc_memalign, SIZE_T boundary, SIZE_T size) { + GET_MALLOC_STACK_TRACE; + CHECK_EQ(boundary & (boundary - 1), 0); + void *ptr = MsanReallocate(&stack, 0, size, boundary, false); + DTLS_on_libc_memalign(ptr, size * boundary); + return ptr; +} INTERCEPTOR(void *, valloc, SIZE_T size) { GET_MALLOC_STACK_TRACE; @@ -1459,6 +1465,7 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(mmap64); INTERCEPT_FUNCTION(posix_memalign); INTERCEPT_FUNCTION(memalign); + INTERCEPT_FUNCTION(__libc_memalign); INTERCEPT_FUNCTION(valloc); INTERCEPT_FUNCTION(pvalloc); INTERCEPT_FUNCTION(malloc); diff --git a/compiler-rt/lib/msan/msan_thread.cc b/compiler-rt/lib/msan/msan_thread.cc index 2289be3189d..5fe99f68b79 100644 --- a/compiler-rt/lib/msan/msan_thread.cc +++ b/compiler-rt/lib/msan/msan_thread.cc @@ -3,6 +3,8 @@ #include "msan_thread.h" #include "msan_interface_internal.h" +#include "sanitizer_common/sanitizer_tls_get_addr.h" + namespace __msan { MsanThread *MsanThread::Create(thread_callback_t start_routine, @@ -33,6 +35,9 @@ void MsanThread::ClearShadowForThreadStackAndTLS() { __msan_unpoison((void *)stack_bottom_, stack_top_ - stack_bottom_); if (tls_begin_ != tls_end_) __msan_unpoison((void *)tls_begin_, tls_end_ - tls_begin_); + DTLS *dtls = DTLS_Get(); + for (uptr i = 0; i < dtls->dtv_size; ++i) + __msan_unpoison((void *)(dtls->dtv[i].beg), dtls->dtv[i].size); } void MsanThread::Init() { @@ -55,6 +60,7 @@ void MsanThread::Destroy() { ClearShadowForThreadStackAndTLS(); uptr size = RoundUpTo(sizeof(MsanThread), GetPageSizeCached()); UnmapOrDie(this, size); + DTLS_Destroy(); } thread_return_t MsanThread::ThreadStart() { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 8fe77790079..9614345571a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -3827,7 +3827,11 @@ INTERCEPTOR(void *, __tls_get_addr, void *arg) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg); void *res = REAL(__tls_get_addr)(arg); - DTLS_on_tls_get_addr(arg, res); + DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res); + if (dtv) { + // New DTLS block has been allocated. + COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size); + } return res; } #else diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.cc b/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.cc index 42d7d1a8d15..993fdc65878 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.cc @@ -78,14 +78,13 @@ void DTLS_Destroy() { DTLS_Deallocate(dtls.dtv, s); } -void DTLS_on_tls_get_addr(void *arg_void, void *res) { - if (!common_flags()->intercept_tls_get_addr) return; +DTLS::DTV *DTLS_on_tls_get_addr(void *arg_void, void *res) { + if (!common_flags()->intercept_tls_get_addr) return 0; TlsGetAddrParam *arg = reinterpret_cast<TlsGetAddrParam *>(arg_void); uptr dso_id = arg->dso_id; - if (dtls.dtv_size == kDestroyedThread) return; + if (dtls.dtv_size == kDestroyedThread) return 0; DTLS_Resize(dso_id + 1); - if (dtls.dtv[dso_id].beg) - return; + if (dtls.dtv[dso_id].beg) return 0; uptr tls_size = 0; uptr tls_beg = reinterpret_cast<uptr>(res) - arg->offset; VPrintf(2, "__tls_get_addr: %p {%p,%p} => %p; tls_beg: %p; sp: %p " @@ -110,6 +109,7 @@ void DTLS_on_tls_get_addr(void *arg_void, void *res) { } dtls.dtv[dso_id].beg = tls_beg; dtls.dtv[dso_id].size = tls_size; + return dtls.dtv + dso_id; } void DTLS_on_libc_memalign(void *ptr, uptr size) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.h b/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.h index a64f11e0b96..0fc9a2257c6 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.h @@ -48,7 +48,9 @@ struct DTLS { uptr last_memalign_ptr; }; -void DTLS_on_tls_get_addr(void *arg, void *res); +// Returns pointer and size of a linker-allocated TLS block. +// Each block is returned exactly once. +DTLS::DTV *DTLS_on_tls_get_addr(void *arg, void *res); void DTLS_on_libc_memalign(void *ptr, uptr size); DTLS *DTLS_Get(); void DTLS_Destroy(); // Make sure to call this before the thread is destroyed. diff --git a/compiler-rt/test/msan/dtls_test.c b/compiler-rt/test/msan/dtls_test.c index 5086389f693..cb88ede2f0a 100644 --- a/compiler-rt/test/msan/dtls_test.c +++ b/compiler-rt/test/msan/dtls_test.c @@ -1,10 +1,10 @@ -/* RUN: %clang_msan -m64 %s -o %t - RUN: %clang_msan -m64 %s -DBUILD_SO -fPIC -o %t-so.so -shared - RUN: not %run %t 2>&1 | FileCheck %s - CHECK: MemorySanitizer: use-of-uninitialized-value +/* RUN: %clang_msan -g -m64 %s -o %t + RUN: %clang_msan -g -m64 %s -DBUILD_SO -fPIC -o %t-so.so -shared + RUN: %run %t 2>&1 - This is an actual bug in msan/glibc integration, + Regression test for a bug in msan/glibc integration, see https://sourceware.org/bugzilla/show_bug.cgi?id=16291 + and https://code.google.com/p/memory-sanitizer/issues/detail?id=44 */ #ifndef BUILD_SO |