summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVitaly Buka <vitalybuka@google.com>2018-02-24 06:58:56 +0000
committerVitaly Buka <vitalybuka@google.com>2018-02-24 06:58:56 +0000
commit1aa98f4294861f3021f52c00ca4cc57403410de9 (patch)
treedcbd9fb19bd17cbfd853cfd8f27902d97e762ebe
parentd8cea35360fcc9cc7566b15c92665e933ea43775 (diff)
downloadbcm5719-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.cc21
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
OpenPOWER on IntegriCloud