[compiler-rt] r230288 - [ASan] Disable strict init-order checking if dlopen() is called.

Alexey Samsonov vonosmas at gmail.com
Mon Feb 23 16:37:34 PST 2015


Author: samsonov
Date: Mon Feb 23 18:37:27 2015
New Revision: 230288

URL: http://llvm.org/viewvc/llvm-project?rev=230288&view=rev
Log:
[ASan] Disable strict init-order checking if dlopen() is called.

Revise the fix to https://code.google.com/p/address-sanitizer/issues/detail?id=178:
always disable strict init-order checking the first time dlopen() is
called: at this point shared library is allowed to access globals
defined in the main executable, as they are guaranteed to be
initialized. Revise the test cases:
* simplify init-order-dlopen.cc test case: make it Linux-specific
  (there's no strict init-order checking on other platforms anyway),
  and single-threaded.
* reinforce init-order-pthread-create.cc test case: make sure that
  init-order checker would produce a false positive unless we
  turn it off at the moment we call pthread_create().

Added:
    compiler-rt/trunk/test/asan/TestCases/Linux/init-order-dlopen.cc
Removed:
    compiler-rt/trunk/test/asan/TestCases/Posix/init-order-dlopen.cc
Modified:
    compiler-rt/trunk/lib/asan/asan_interceptors.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
    compiler-rt/trunk/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc
    compiler-rt/trunk/test/asan/TestCases/init-order-pthread-create.cc

Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=230288&r1=230287&r2=230288&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Mon Feb 23 18:37:27 2015
@@ -171,6 +171,12 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free,
   do {                                                         \
   } while (false)
 #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
+// Strict init-order checking is dlopen-hostile:
+// https://code.google.com/p/address-sanitizer/issues/detail?id=178
+#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag)                           \
+  if (flags()->strict_init_order) {                                            \
+    StopInitOrderChecking();                                                   \
+  }
 #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
 #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) \
   CoverageUpdateMapping()

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=230288&r1=230287&r2=230288&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Mon Feb 23 18:37:27 2015
@@ -22,6 +22,7 @@
 //   COMMON_INTERCEPTOR_FD_RELEASE
 //   COMMON_INTERCEPTOR_FD_ACCESS
 //   COMMON_INTERCEPTOR_SET_THREAD_NAME
+//   COMMON_INTERCEPTOR_ON_DLOPEN
 //   COMMON_INTERCEPTOR_ON_EXIT
 //   COMMON_INTERCEPTOR_MUTEX_LOCK
 //   COMMON_INTERCEPTOR_MUTEX_UNLOCK
@@ -101,6 +102,10 @@
 #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0)
 #endif
 
+#ifndef COMMON_INTERCEPTOR_ON_DLOPEN
+#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) {}
+#endif
+
 struct FileMetadata {
   // For open_memstream().
   char **addr;
@@ -4688,6 +4693,7 @@ INTERCEPTOR(int, fclose, __sanitizer_FIL
 INTERCEPTOR(void*, dlopen, const char *filename, int flag) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);
+  COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag);
   void *res = REAL(dlopen)(filename, flag);
   COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);
   return res;

Modified: compiler-rt/trunk/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc?rev=230288&r1=230287&r2=230288&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc Mon Feb 23 18:37:27 2015
@@ -1,2 +1,2 @@
-void *bar(void *input);
-void *glob2 = bar((void*)0x2345);
+void *bar(void *input, bool sleep_before_init);
+void *glob2 = bar((void*)0x2345, true);

Added: compiler-rt/trunk/test/asan/TestCases/Linux/init-order-dlopen.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/init-order-dlopen.cc?rev=230288&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/init-order-dlopen.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/init-order-dlopen.cc Mon Feb 23 18:37:27 2015
@@ -0,0 +1,43 @@
+// Regression test for
+// https://code.google.com/p/address-sanitizer/issues/detail?id=178
+
+// RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
+// RUN: %clangxx_asan -O0 %s %libdl -Wl,--export-dynamic -o %t
+// RUN: env ASAN_OPTIONS=strict_init_order=true %run %t 2>&1
+
+#if defined(SHARED_LIB)
+#include <stdio.h>
+
+struct Bar {
+  Bar(int val) : val(val) { printf("Bar::Bar(%d)\n", val); }
+  int val;
+};
+
+int get_foo_val();
+Bar global_bar(get_foo_val());
+#else  // SHARED LIB
+#include <dlfcn.h>
+#include <stdio.h>
+#include <string>
+struct Foo {
+  Foo() : val(42) { printf("Foo::Foo()\n"); }
+  int val;
+};
+
+Foo global_foo;
+
+int get_foo_val() {
+  return global_foo.val;
+}
+
+int main(int argc, char *argv[]) {
+  std::string path = std::string(argv[0]) + "-so.so";
+  void *handle = dlopen(path.c_str(), RTLD_NOW);
+  if (!handle) {
+    printf("error in dlopen(): %s\n", dlerror());
+    return 1;
+  }
+  printf("%d\n", get_foo_val());
+  return 0;
+}
+#endif  // SHARED_LIB

Removed: compiler-rt/trunk/test/asan/TestCases/Posix/init-order-dlopen.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Posix/init-order-dlopen.cc?rev=230287&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Posix/init-order-dlopen.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/Posix/init-order-dlopen.cc (removed)
@@ -1,72 +0,0 @@
-// Regression test for
-// https://code.google.com/p/address-sanitizer/issues/detail?id=178
-
-// Assume we're on Darwin and try to pass -U to the linker. If this flag is
-// unsupported, don't use it.
-// RUN: %clangxx_asan -O0 -DSHARED_LIB %s \
-// RUN:     -fPIC -shared -o %t-so.so -Wl,-U,_inc_global || \
-// RUN:     %clangxx_asan -O0 -DSHARED_LIB %s \
-// RUN:         -fPIC -shared -o %t-so.so
-// If the linker doesn't support --export-dynamic (which is ELF-specific),
-// try to link without that option.
-// FIXME: find a better solution.
-// RUN: %clangxx_asan -O0 %s -pthread %libdl -o %t -Wl,--export-dynamic || \
-// RUN:     %clangxx_asan -O0 %s -pthread %libdl -o %t
-// RUN: ASAN_OPTIONS=strict_init_order=true %run %t 2>&1 | FileCheck %s
-#if !defined(SHARED_LIB)
-#include <dlfcn.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <string>
-
-using std::string;
-
-int foo() {
-  return 42;
-}
-int global = foo();
-
-__attribute__((visibility("default")))
-extern "C"
-void inc_global() {
-  global++;
-}
-
-void *global_poller(void *arg) {
-  while (true) {
-    if (global != 42)
-      break;
-    usleep(100);
-  }
-  return 0;
-}
-
-int main(int argc, char *argv[]) {
-  pthread_t p;
-  pthread_create(&p, 0, global_poller, 0);
-  string path = string(argv[0]) + "-so.so";
-  if (0 == dlopen(path.c_str(), RTLD_NOW)) {
-    fprintf(stderr, "dlerror: %s\n", dlerror());
-    return 1;
-  }
-  pthread_join(p, 0);
-  printf("PASSED\n");
-  // CHECK: PASSED
-  return 0;
-}
-#else  // SHARED_LIB
-#include <stdio.h>
-#include <unistd.h>
-
-extern "C" void inc_global();
-
-int slow_init() {
-  sleep(1);
-  inc_global();
-  return 42;
-}
-
-int slowly_init_glob = slow_init();
-#endif  // SHARED_LIB

Modified: compiler-rt/trunk/test/asan/TestCases/init-order-pthread-create.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/init-order-pthread-create.cc?rev=230288&r1=230287&r2=230288&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/init-order-pthread-create.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/init-order-pthread-create.cc Mon Feb 23 18:37:27 2015
@@ -6,25 +6,36 @@
 
 #include <stdio.h>
 #include <pthread.h>
+#include <unistd.h>
 
-void *run(void *arg) {
-  return arg;
+void *bar(void *input, bool sleep_before_init) {
+  if (sleep_before_init)
+    usleep(500000);
+  return input;
 }
 
-void *foo(void *input) {
-  pthread_t t;
-  pthread_create(&t, 0, run, input);
-  void *res;
-  pthread_join(t, &res);
-  return res;
-}
+void *glob = bar((void*)0x1234, false);
+extern void *glob2;
 
-void *bar(void *input) {
-  return input;
+void *poll(void *arg) {
+  void **glob = (void**)arg;
+  while (true) {
+    usleep(100000);
+    printf("glob is now: %p\n", *glob);
+  }
 }
 
-void *glob = foo((void*)0x1234);
-extern void *glob2;
+struct GlobalPollerStarter {
+  GlobalPollerStarter() {
+    pthread_t p;
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+    pthread_create(&p, 0, poll, &glob);
+    pthread_attr_destroy(&attr);
+    printf("glob poller is started");
+  }
+} global_poller;
 
 int main() {
   printf("%p %p\n", glob, glob2);





More information about the llvm-commits mailing list