[PATCH] D30504: [sanitizer] Bail out with warning if user dlopens shared library with RTLD_DEEPBIND flag

Maxim Ostapenko via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 1 09:50:26 PST 2017


m.ostapenko created this revision.
m.ostapenko added a project: Sanitizers.
Herald added subscribers: kubamracek, srhines, danalbert.

People keep hitting on spurious failures in malloc/free routines when using sanitizers with shared libraries dlopened with RTLD_DEEPBIND (see https://github.com/google/sanitizers/issues/611 for details).
Let's check for this flag and bail out with warning message instead of failing in random places.


Repository:
  rL LLVM

https://reviews.llvm.org/D30504

Files:
  lib/asan/asan_interceptors.cc
  lib/sanitizer_common/sanitizer_common.cc
  lib/sanitizer_common/sanitizer_common_interceptors.inc
  test/sanitizer_common/TestCases/Posix/deepbind.cc


Index: test/sanitizer_common/TestCases/Posix/deepbind.cc
===================================================================
--- /dev/null
+++ test/sanitizer_common/TestCases/Posix/deepbind.cc
@@ -0,0 +1,33 @@
+// RUN: %clangxx -DSHARED_LIB %s -fPIC -shared -o %t-so.so
+// RUN: %clangxx %s -o %t && %run %t 2>&1
+// RUN: %run not %t 1 2>&1 | FileCheck %s --check-prefix CHECK-DEEPBIND
+// UNSUPPORTED: lsan, android
+
+#if !defined(SHARED_LIB)
+#include <dlfcn.h>
+#include <stdio.h>
+#include <string>
+
+using std::string;
+
+int main (int argc, char *argv[]) {
+  int flag = argc > 1 ? RTLD_NOW | RTLD_DEEPBIND : RTLD_NOW;
+  string path = string(argv[0]) + "-so.so";
+  printf("opening %s ... \n", path.c_str());
+  // CHECK-DEEPBIND: You are trying to dlopen a shared library with RTLD_DEEPBIND flag
+  void *lib = dlopen(path.c_str(), flag);
+  if (!lib) {
+    printf("error in dlopen(): %s\n", dlerror());
+    return 1;
+  }
+  dlclose(lib);
+  return 0;
+}
+#else  // SHARED_LIB
+#include <stdio.h>
+
+__attribute__((constructor))
+void at_dlopen() {
+  printf("%s: I am being dlopened\n", __FILE__);
+}
+#endif
Index: lib/sanitizer_common/sanitizer_common_interceptors.inc
===================================================================
--- lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -142,7 +142,7 @@
     COMMON_INTERCEPTOR_READ_STRING_OF_LEN((ctx), (s), REAL(strlen)(s), (n))
 
 #ifndef COMMON_INTERCEPTOR_ON_DLOPEN
-#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) {}
+#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) { CheckNoDeepBind(flag); }
 #endif
 
 #ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE
Index: lib/sanitizer_common/sanitizer_common.cc
===================================================================
--- lib/sanitizer_common/sanitizer_common.cc
+++ lib/sanitizer_common/sanitizer_common.cc
@@ -19,6 +19,7 @@
 #include "sanitizer_placement_new.h"
 #include "sanitizer_stacktrace_printer.h"
 #include "sanitizer_symbolizer.h"
+#include <dlfcn.h> // For RTLD_DEEPBIND
 
 namespace __sanitizer {
 
@@ -475,6 +476,17 @@
   return 0;
 }
 
+void CheckNoDeepBind(int flag) {
+  if (flag & RTLD_DEEPBIND) {
+    Report("You are trying to dlopen a shared library with RTLD_DEEPBIND flag"
+           " which is incompatibe with sanitizer runtime "
+           "(see https://github.com/google/sanitizers/issues/611 for details"
+           "). If you want to run your library under sanitizers please remove "
+           "RTLD_DEEPBIND from dlopen flags.\n");
+    Die();
+  }
+}
+
 } // namespace __sanitizer
 
 using namespace __sanitizer;  // NOLINT
Index: lib/asan/asan_interceptors.cc
===================================================================
--- lib/asan/asan_interceptors.cc
+++ lib/asan/asan_interceptors.cc
@@ -228,9 +228,11 @@
 // Strict init-order checking is dlopen-hostile:
 // https://github.com/google/sanitizers/issues/178
 #define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag)                           \
-  if (flags()->strict_init_order) {                                            \
-    StopInitOrderChecking();                                                   \
-  }
+  do {                                                                         \
+    if (flags()->strict_init_order)                                            \
+      StopInitOrderChecking();                                                 \
+    CheckNoDeepBind(flag);                                                     \
+  } while (false)
 #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
 #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) \
   CoverageUpdateMapping()


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D30504.90200.patch
Type: text/x-patch
Size: 3690 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170301/8bb7eb76/attachment.bin>


More information about the llvm-commits mailing list