[compiler-rt] r191508 - [msan] Unpoison argument shadow for C++ module destructors.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Fri Sep 27 04:32:21 PDT 2013


Author: eugenis
Date: Fri Sep 27 06:32:21 2013
New Revision: 191508

URL: http://llvm.org/viewvc/llvm-project?rev=191508&view=rev
Log:
[msan] Unpoison argument shadow for C++ module destructors.

Fixes PR17377.

Added:
    compiler-rt/trunk/lib/msan/lit_tests/cxa_atexit.cc   (with props)
Modified:
    compiler-rt/trunk/lib/msan/msan.cc
    compiler-rt/trunk/lib/msan/msan_interceptors.cc

Added: compiler-rt/trunk/lib/msan/lit_tests/cxa_atexit.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/lit_tests/cxa_atexit.cc?rev=191508&view=auto
==============================================================================
--- compiler-rt/trunk/lib/msan/lit_tests/cxa_atexit.cc (added)
+++ compiler-rt/trunk/lib/msan/lit_tests/cxa_atexit.cc Fri Sep 27 06:32:21 2013
@@ -0,0 +1,28 @@
+// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t %p
+
+// PR17377: C++ module destructors get stale argument shadow.
+
+#include <stdio.h>
+#include <stdlib.h>
+class A {
+public:
+  // This destructor get stale argument shadow left from the call to f().
+  ~A() {
+    if (this)
+      exit(0);
+  }
+};
+
+A a;
+
+__attribute__((noinline))
+void f(long x) {
+}
+
+int main(void) {
+  long  x;
+  long * volatile p = &x;
+  // This call poisons TLS shadow for the first function argument.
+  f(*p);
+  return 0;
+}

Propchange: compiler-rt/trunk/lib/msan/lit_tests/cxa_atexit.cc
------------------------------------------------------------------------------
    svn:eol-style = LF

Modified: compiler-rt/trunk/lib/msan/msan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.cc?rev=191508&r1=191507&r2=191508&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.cc (original)
+++ compiler-rt/trunk/lib/msan/msan.cc Fri Sep 27 06:32:21 2013
@@ -296,10 +296,10 @@ void __msan_init() {
   msan_init_is_running = 1;
   SanitizerToolName = "MemorySanitizer";
 
-  InstallAtExitHandler();
   SetDieCallback(MsanDie);
   InitTlsSize();
   InitializeInterceptors();
+  InstallAtExitHandler(); // Needs __cxa_atexit interceptor.
 
   if (MSAN_REPLACE_OPERATORS_NEW_AND_DELETE)
     ReplaceOperatorsNewAndDelete();

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=191508&r1=191507&r2=191508&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Fri Sep 27 06:32:21 2013
@@ -19,6 +19,7 @@
 #include "msan.h"
 #include "sanitizer_common/sanitizer_platform_limits_posix.h"
 #include "sanitizer_common/sanitizer_allocator.h"
+#include "sanitizer_common/sanitizer_allocator_internal.h"
 #include "sanitizer_common/sanitizer_atomic.h"
 #include "sanitizer_common/sanitizer_common.h"
 #include "sanitizer_common/sanitizer_stackdepot.h"
@@ -1083,6 +1084,30 @@ INTERCEPTOR(void, tzset) {
   return;
 }
 
+struct MSanAtExitRecord {
+  void (*func)(void *arg);
+  void *arg;
+};
+
+void MSanAtExitWrapper(void *arg) {
+  UnpoisonParam(1);
+  MSanAtExitRecord *r = (MSanAtExitRecord *)arg;
+  r->func(r->arg);
+  InternalFree(r);
+}
+
+// Unpoison argument shadow for C++ module destructors.
+INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
+            void *dso_handle) {
+  if (msan_init_is_running) return REAL(__cxa_atexit)(func, arg, dso_handle);
+  ENSURE_MSAN_INITED();
+  MSanAtExitRecord *r =
+      (MSanAtExitRecord *)InternalAlloc(sizeof(MSanAtExitRecord));
+  r->func = func;
+  r->arg = arg;
+  return REAL(__cxa_atexit)(MSanAtExitWrapper, r, dso_handle);
+}
+
 struct MSanInterceptorContext {
   bool in_interceptor_scope;
 };
@@ -1340,6 +1365,7 @@ void InitializeInterceptors() {
   INTERCEPT_FUNCTION(pthread_key_create);
   INTERCEPT_FUNCTION(pthread_join);
   INTERCEPT_FUNCTION(tzset);
+  INTERCEPT_FUNCTION(__cxa_atexit);
   inited = 1;
 }
 }  // namespace __msan





More information about the llvm-commits mailing list