diff options
author | Vitaly Buka <vitalybuka@google.com> | 2018-02-24 06:58:56 +0000 |
---|---|---|
committer | Vitaly Buka <vitalybuka@google.com> | 2018-02-24 06:58:56 +0000 |
commit | 1aa98f4294861f3021f52c00ca4cc57403410de9 (patch) | |
tree | dcbd9fb19bd17cbfd853cfd8f27902d97e762ebe | |
parent | d8cea35360fcc9cc7566b15c92665e933ea43775 (diff) | |
download | bcm5719-llvm-1aa98f4294861f3021f52c00ca4cc57403410de9.tar.gz bcm5719-llvm-1aa98f4294861f3021f52c00ca4cc57403410de9.zip |
[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
llvm-svn: 326025
-rw-r--r-- | compiler-rt/lib/cfi/cfi.cc | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/compiler-rt/lib/cfi/cfi.cc b/compiler-rt/lib/cfi/cfi.cc index f7693b37d29..52f504bd281 100644 --- a/compiler-rt/lib/cfi/cfi.cc +++ b/compiler-rt/lib/cfi/cfi.cc @@ -379,6 +379,8 @@ __cfi_slowpath_diag(u64 CallSiteTypeId, void *Ptr, void *DiagData) { } #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, void *Ptr, void *DiagData) { // 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 *filename, int flag) { } 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 |