[compiler-rt] r211683 - [msan] Fix false positive on dynamic tls.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Wed Jun 25 04:30:36 PDT 2014


Author: eugenis
Date: Wed Jun 25 06:30:35 2014
New Revision: 211683

URL: http://llvm.org/viewvc/llvm-project?rev=211683&view=rev
Log:
[msan] Fix false positive on dynamic tls.

Use existing DTLS code in sanitizer_tls_get_addr.{h,cc} to unpoison DTLS
blocks both on allocation and deallocation.

https://code.google.com/p/memory-sanitizer/issues/detail?id=44

Modified:
    compiler-rt/trunk/lib/msan/msan.cc
    compiler-rt/trunk/lib/msan/msan_interceptors.cc
    compiler-rt/trunk/lib/msan/msan_thread.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_tls_get_addr.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_tls_get_addr.h
    compiler-rt/trunk/test/msan/dtls_test.c

Modified: compiler-rt/trunk/lib/msan/msan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.cc?rev=211683&r1=211682&r2=211683&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.cc (original)
+++ compiler-rt/trunk/lib/msan/msan.cc Wed Jun 25 06:30:35 2014
@@ -162,6 +162,7 @@ static void InitializeFlags(Flags *f, co
   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;

Modified: compiler-rt/trunk/lib/msan/msan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_interceptors.cc?rev=211683&r1=211682&r2=211683&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Wed Jun 25 06:30:35 2014
@@ -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 bou
   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);

Modified: compiler-rt/trunk/lib/msan/msan_thread.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_thread.cc?rev=211683&r1=211682&r2=211683&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_thread.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_thread.cc Wed Jun 25 06:30:35 2014
@@ -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::ClearShadowForThreadSta
   __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() {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=211683&r1=211682&r2=211683&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Wed Jun 25 06:30:35 2014
@@ -3827,7 +3827,11 @@ INTERCEPTOR(void *, __tls_get_addr, void
   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

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_tls_get_addr.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_tls_get_addr.cc?rev=211683&r1=211682&r2=211683&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_tls_get_addr.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_tls_get_addr.cc Wed Jun 25 06:30:35 2014
@@ -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
   }
   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) {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_tls_get_addr.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_tls_get_addr.h?rev=211683&r1=211682&r2=211683&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_tls_get_addr.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_tls_get_addr.h Wed Jun 25 06:30:35 2014
@@ -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.

Modified: compiler-rt/trunk/test/msan/dtls_test.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/msan/dtls_test.c?rev=211683&r1=211682&r2=211683&view=diff
==============================================================================
--- compiler-rt/trunk/test/msan/dtls_test.c (original)
+++ compiler-rt/trunk/test/msan/dtls_test.c Wed Jun 25 06:30:35 2014
@@ -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





More information about the llvm-commits mailing list