diff options
author | Josh Gao <jmgao@google.com> | 2019-07-18 15:33:16 -0700 |
---|---|---|
committer | Josh Gao <jmgao@google.com> | 2019-07-19 18:14:34 +0000 |
commit | 6e4deeaf452133fd03413c099b6e472778940fca (patch) | |
tree | d79b1d7347b50712d5719ef64bff74ba92722c49 /sigchainlib | |
parent | 34ac9f74e859a77eca9111debfbc25f5c037df7a (diff) |
sigchain: dlsym from libc.so instead of RTLD_NEXT.
RTLD_NEXT doesn't play well with linker namespaces currently, so switch
to directly referencing libc.so.
Bug: http://b/135284876
Test: treehugger
Test: m test-art-host
Test: adb shell /data/nativetest/art/arm/art_sigchain_tests/sigchain_test
Test: adb shell /data/nativetest64/art/arm64/art_sigchain_tests/sigchain_test
Change-Id: I980bf63e5e3bb0a1638a4806c7ad76f41d5db44e
Diffstat (limited to 'sigchainlib')
-rw-r--r-- | sigchainlib/sigchain.cc | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/sigchainlib/sigchain.cc b/sigchainlib/sigchain.cc index ad54f2395b..76027f54bb 100644 --- a/sigchainlib/sigchain.cc +++ b/sigchainlib/sigchain.cc @@ -98,9 +98,28 @@ static decltype(&sigaction64) linked_sigaction64; static decltype(&sigprocmask64) linked_sigprocmask64; #endif -template<typename T> -static void lookup_next_symbol(T* output, T wrapper, const char* name) { - void* sym = dlsym(RTLD_NEXT, name); // NOLINT glibc triggers cert-dcl16-c with RTLD_NEXT. +template <typename T> +static void lookup_libc_symbol(T* output, T wrapper, const char* name) { +#if defined(__BIONIC__) + constexpr const char* libc_name = "libc.so"; +#elif defined(__GLIBC__) +#if __GNU_LIBRARY__ != 6 +#error unsupported glibc version +#endif + constexpr const char* libc_name = "libc.so.6"; +#else +#error unsupported libc: not bionic or glibc? +#endif + + static void* libc = []() { + void* result = dlopen(libc_name, RTLD_LOCAL | RTLD_LAZY); + if (!result) { + fatal("failed to dlopen %s: %s", libc_name, dlerror()); + } + return result; + }(); + + void* sym = dlsym(libc, name); // NOLINT glibc triggers cert-dcl16-c with RTLD_NEXT. if (sym == nullptr) { sym = dlsym(RTLD_DEFAULT, name); if (sym == wrapper || sym == sigaction) { @@ -113,12 +132,12 @@ static void lookup_next_symbol(T* output, T wrapper, const char* name) { __attribute__((constructor)) static void InitializeSignalChain() { static std::once_flag once; std::call_once(once, []() { - lookup_next_symbol(&linked_sigaction, sigaction, "sigaction"); - lookup_next_symbol(&linked_sigprocmask, sigprocmask, "sigprocmask"); + lookup_libc_symbol(&linked_sigaction, sigaction, "sigaction"); + lookup_libc_symbol(&linked_sigprocmask, sigprocmask, "sigprocmask"); #if defined(__BIONIC__) - lookup_next_symbol(&linked_sigaction64, sigaction64, "sigaction64"); - lookup_next_symbol(&linked_sigprocmask64, sigprocmask64, "sigprocmask64"); + lookup_libc_symbol(&linked_sigaction64, sigaction64, "sigaction64"); + lookup_libc_symbol(&linked_sigprocmask64, sigprocmask64, "sigprocmask64"); #endif }); } |