[compiler-rt] r297370 - [sanitizer] Bail out with warning if user dlopens shared library with RTLD_DEEPBIND flag

Maxim Ostapenko via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 9 02:47:38 PST 2017


Author: chefmax
Date: Thu Mar  9 04:47:38 2017
New Revision: 297370

URL: http://llvm.org/viewvc/llvm-project?rev=297370&view=rev
Log:
[sanitizer] Bail out with warning if user dlopens shared library with RTLD_DEEPBIND flag

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.

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

Added:
    compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/deepbind.cc
Modified:
    compiler-rt/trunk/lib/asan/asan_interceptors.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.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=297370&r1=297369&r2=297370&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Thu Mar  9 04:47:38 2017
@@ -228,9 +228,11 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free,
 // 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(filename, flag);                                           \
+  } while (false)
 #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
 #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) \
   CoverageUpdateMapping()

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=297370&r1=297369&r2=297370&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Thu Mar  9 04:47:38 2017
@@ -911,6 +911,8 @@ struct StackDepotStats {
 // indicate that sanitizer allocator should not attempt to release memory to OS.
 const s32 kReleaseToOSIntervalNever = -1;
 
+void CheckNoDeepBind(const char *filename, int flag);
+
 }  // namespace __sanitizer
 
 inline void *operator new(__sanitizer::operator_new_size_type size,

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=297370&r1=297369&r2=297370&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Thu Mar  9 04:47:38 2017
@@ -142,7 +142,8 @@ bool PlatformHasDifferentMemcpyAndMemmov
     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(filename, flag);
 #endif
 
 #ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc?rev=297370&r1=297369&r2=297370&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Thu Mar  9 04:47:38 2017
@@ -1460,6 +1460,19 @@ void MaybeReexec() {
 
 void PrintModuleMap() { }
 
+void CheckNoDeepBind(const char *filename, int flag) {
+  if (flag & RTLD_DEEPBIND) {
+    Report(
+        "You are trying to dlopen a %s 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 %s library under sanitizers please remove "
+        "RTLD_DEEPBIND from dlopen flags.\n",
+        filename, filename);
+    Die();
+  }
+}
+
 uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding) {
   UNREACHABLE("FindAvailableMemoryRange is not available");
   return 0;

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc?rev=297370&r1=297369&r2=297370&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc Thu Mar  9 04:47:38 2017
@@ -886,6 +886,10 @@ void PrintModuleMap() {
   Printf("End of module map.\n");
 }
 
+void CheckNoDeepBind(const char *filename, int flag) {
+  // Do nothing.
+}
+
 }  // namespace __sanitizer
 
 #endif  // SANITIZER_MAC

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc?rev=297370&r1=297369&r2=297370&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc Thu Mar  9 04:47:38 2017
@@ -990,6 +990,9 @@ int WaitForProcess(pid_t pid) { return -
 // FIXME implement on this platform.
 void GetMemoryProfile(fill_profile_f cb, uptr *stats, uptr stats_size) { }
 
+void CheckNoDeepBind(const char *filename, int flag) {
+  // Do nothing.
+}
 
 }  // namespace __sanitizer
 

Added: compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/deepbind.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/deepbind.cc?rev=297370&view=auto
==============================================================================
--- compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/deepbind.cc (added)
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/deepbind.cc Thu Mar  9 04:47:38 2017
@@ -0,0 +1,12 @@
+// RUN: %clangxx %s -o %t && %run not %t 1 2>&1 | FileCheck %s
+// UNSUPPORTED: lsan, android
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <string>
+
+int main (int argc, char *argv[]) {
+  // CHECK: You are trying to dlopen a <arbitrary path> shared library with RTLD_DEEPBIND flag
+  void *lib = dlopen("<arbitrary path>", RTLD_NOW | RTLD_DEEPBIND);
+  return 0;
+}




More information about the llvm-commits mailing list