diff options
author | Fangrui Song <maskray@google.com> | 2018-07-01 17:52:41 +0000 |
---|---|---|
committer | Fangrui Song <maskray@google.com> | 2018-07-01 17:52:41 +0000 |
commit | 1da06fc8d37ff2abd1da1746e4066d7fd4eaeb07 (patch) | |
tree | b4ceac9434f044a8f012aa3b617fe3d7f329c350 /lib/sanitizer_common | |
parent | 6758db1bffbd51069a083633d50252ad68be181e (diff) |
[asan] Fix deadlock issue on FreeBSD, caused by use of .preinit_array in rL325240
Summary:
Without this patch,
clang -fsanitize=address -xc =(printf 'int main(){}') -o a; ./a => deadlock in __asan_init>AsanInitInternal>AsanTSDInit>...>__getcontextx_size>_rtld_bind>rlock_acquire(rtld_bind_lock, &lockstate)
libexec/rtld-elf/rtld.c
wlock_acquire(rtld_bind_lock, &lockstate);
if (obj_main->crt_no_init)
preinit_main(); // unresolved PLT functions cannot be called here
lib/libthr/thread/thr_rtld.c
uc_len = __getcontextx_size(); // unresolved PLT function in libthr.so.3
check-xray tests currently rely on .preinit_array so we special case in
xray_init.cc
Subscribers: srhines, kubamracek, krytarowski, delcypher, llvm-commits, #sanitizers
Differential Revision: https://reviews.llvm.org/D48806
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@336067 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common')
-rw-r--r-- | lib/sanitizer_common/sanitizer_internal_defs.h | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/lib/sanitizer_common/sanitizer_internal_defs.h b/lib/sanitizer_common/sanitizer_internal_defs.h index af2a821d7..a955733fb 100644 --- a/lib/sanitizer_common/sanitizer_internal_defs.h +++ b/lib/sanitizer_common/sanitizer_internal_defs.h @@ -98,11 +98,16 @@ // We can use .preinit_array section on Linux to call sanitizer initialization // functions very early in the process startup (unless PIC macro is defined). +// +// On FreeBSD, .preinit_array functions are called with rtld_bind_lock writer +// lock held. It will lead to dead lock if unresolved PLT functions (which helds +// rtld_bind_lock reader lock) are called inside .preinit_array functions. +// // FIXME: do we have anything like this on Mac? #ifndef SANITIZER_CAN_USE_PREINIT_ARRAY -#if ((SANITIZER_LINUX && !SANITIZER_ANDROID) || \ - SANITIZER_FREEBSD || SANITIZER_OPENBSD) && !defined(PIC) -# define SANITIZER_CAN_USE_PREINIT_ARRAY 1 +#if ((SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_OPENBSD) && \ + !defined(PIC) +#define SANITIZER_CAN_USE_PREINIT_ARRAY 1 // Before Solaris 11.4, .preinit_array is fully supported only with GNU ld. // FIXME: Check for those conditions. #elif SANITIZER_SOLARIS && !defined(PIC) |