[compiler-rt] r326025 - [cfi] Lazy initialization of CFI interceptors

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 23 22:58:56 PST 2018


Author: vitalybuka
Date: Fri Feb 23 22:58:56 2018
New Revision: 326025

URL: http://llvm.org/viewvc/llvm-project?rev=326025&view=rev
Log:
[cfi] Lazy initialization of CFI interceptors

Summary:
Interceptors initialization may need to allocate memory. So if we initialize too
early we can crash in non initialized allocator.

Reviewers: pcc, eugenis

Subscribers: llvm-commits

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

Modified:
    compiler-rt/trunk/lib/cfi/cfi.cc

Modified: compiler-rt/trunk/lib/cfi/cfi.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/cfi/cfi.cc?rev=326025&r1=326024&r2=326025&view=diff
==============================================================================
--- compiler-rt/trunk/lib/cfi/cfi.cc (original)
+++ compiler-rt/trunk/lib/cfi/cfi.cc Fri Feb 23 22:58:56 2018
@@ -379,6 +379,8 @@ __cfi_slowpath_diag(u64 CallSiteTypeId,
 }
 #endif
 
+static void EnsureInterceptorsInitialized();
+
 // Setup shadow for dlopen()ed libraries.
 // The actual shadow setup happens after dlopen() returns, which means that
 // a library can not be a target of any CFI checks while its constructors are
@@ -388,6 +390,7 @@ __cfi_slowpath_diag(u64 CallSiteTypeId,
 // We could insert a high-priority constructor into the library, but that would
 // not help with the uninstrumented libraries.
 INTERCEPTOR(void*, dlopen, const char *filename, int flag) {
+  EnsureInterceptorsInitialized();
   EnterLoader();
   void *handle = REAL(dlopen)(filename, flag);
   ExitLoader();
@@ -395,12 +398,27 @@ INTERCEPTOR(void*, dlopen, const char *f
 }
 
 INTERCEPTOR(int, dlclose, void *handle) {
+  EnsureInterceptorsInitialized();
   EnterLoader();
   int res = REAL(dlclose)(handle);
   ExitLoader();
   return res;
 }
 
+static BlockingMutex interceptor_init_lock(LINKER_INITIALIZED);
+static bool interceptors_inited = false;
+
+static void EnsureInterceptorsInitialized() {
+  BlockingMutexLock lock(&interceptor_init_lock);
+  if (interceptors_inited)
+    return;
+
+  INTERCEPT_FUNCTION(dlopen);
+  INTERCEPT_FUNCTION(dlclose);
+
+  interceptors_inited = true;
+}
+
 extern "C" SANITIZER_INTERFACE_ATTRIBUTE
 #if !SANITIZER_CAN_USE_PREINIT_ARRAY
 // On ELF platforms, the constructor is invoked using .preinit_array (see below)
@@ -411,9 +429,6 @@ void __cfi_init() {
   InitializeFlags();
   InitShadow();
 
-  INTERCEPT_FUNCTION(dlopen);
-  INTERCEPT_FUNCTION(dlclose);
-
 #ifdef CFI_ENABLE_DIAG
   __ubsan::InitAsPlugin();
 #endif




More information about the llvm-commits mailing list