[compiler-rt] r354005 - [msan] Don't delete MSanAtExitRecord

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 13 18:51:55 PST 2019


Author: vitalybuka
Date: Wed Feb 13 18:51:55 2019
New Revision: 354005

URL: http://llvm.org/viewvc/llvm-project?rev=354005&view=rev
Log:
[msan] Don't delete MSanAtExitRecord

Summary:
Pre 2.27 libc can run same atexit handler twice
We will keep MSanAtExitRecord and reset fun to mark it as executed.

Fix PR40162

Reviewers: eugenis

Subscribers: jfb, jdoerfert, #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

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

Added:
    compiler-rt/trunk/test/msan/cxa_atexit_race.cc
Modified:
    compiler-rt/trunk/lib/msan/msan_interceptors.cc

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=354005&r1=354004&r2=354005&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Wed Feb 13 18:51:55 2019
@@ -1118,8 +1118,12 @@ void MSanAtExitWrapper() {
 void MSanCxaAtExitWrapper(void *arg) {
   UnpoisonParam(1);
   MSanAtExitRecord *r = (MSanAtExitRecord *)arg;
+  // libc before 2.27 had race which caused occasional double handler execution
+  // https://sourceware.org/ml/libc-alpha/2017-08/msg01204.html
+  if (!r->func)
+    return;
   r->func(r->arg);
-  InternalFree(r);
+  r->func = nullptr;
 }
 
 static int setup_at_exit_wrapper(void(*f)(), void *arg, void *dso);

Added: compiler-rt/trunk/test/msan/cxa_atexit_race.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/msan/cxa_atexit_race.cc?rev=354005&view=auto
==============================================================================
--- compiler-rt/trunk/test/msan/cxa_atexit_race.cc (added)
+++ compiler-rt/trunk/test/msan/cxa_atexit_race.cc Wed Feb 13 18:51:55 2019
@@ -0,0 +1,35 @@
+// RUN: %clangxx_msan %s -o %t && %run %t 2>&1 | FileCheck %s
+
+#include <atomic>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+extern "C" int
+__cxa_atexit(void (*func)(void *), void *arg, void *d);
+
+void handler(void *) {
+}
+
+std::atomic_int counter;
+
+void *thread(void *) {
+  for (int i = 0; i < 10000; ++i) {
+    __cxa_atexit(&handler, 0, (void *)&handler);
+    ++counter;
+  }
+  return 0;
+}
+
+int main(void) {
+  printf("TEST_MAIN\n");
+  pthread_t pt;
+  for (int i = 0; i < 2; ++i)
+    pthread_create(&pt, 0, &thread, 0);
+  while (counter < 1000) {
+  };
+  return 0;
+}
+// CHECK: TEST_MAIN
+// CHECK-NOT: MemorySanitizer




More information about the llvm-commits mailing list