diff options
author | Dimitry Ivanov <dimitry@google.com> | 2016-08-09 19:38:43 -0700 |
---|---|---|
committer | Dimitry Ivanov <dimitry@google.com> | 2016-08-10 21:37:50 -0700 |
commit | 45d25ca72872ed5df08da7a19a4c95c56d64088c (patch) | |
tree | eb32b3458912e9ecbb77ac73b77596f4ea8e65c9 /linker/linker.cpp | |
parent | 4519a4d1829c9e9f80cf45f1003e5937f1dfb04e (diff) |
linker_asan: Translate absolute dlopen paths to use asan-libraries.
This patch enables absolute path translation to instrumented library
when linker_asan is in use.
Test: adb shell cat /proc/<rlid pid>/maps | grep libril-qc-qmi-1.so
check that it is mapped from /data/vendor/lib64 and not /vendor/lib64
Bug: http://b/30320104
Change-Id: I3bc24754b192afc0a72d6f3801f7b42141ce715b
(cherry picked from commit 5aa67675f853af9588ac9274ecf86d7858695ce2)
Diffstat (limited to 'linker/linker.cpp')
-rw-r--r-- | linker/linker.cpp | 72 |
1 files changed, 50 insertions, 22 deletions
diff --git a/linker/linker.cpp b/linker/linker.cpp index 9b90028d7..7d3482329 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -91,32 +91,35 @@ static soinfo* solist; static soinfo* sonext; static soinfo* somain; // main process, always the one after libdl_info -static const char* const kDefaultLdPaths[] = { #if defined(__LP64__) - "/system/lib64", - "/vendor/lib64", +static const char* const kSystemLibDir = "/system/lib64"; +static const char* const kVendorLibDir = "/vendor/lib64"; +static const char* const kAsanSystemLibDir = "/data/lib64"; +static const char* const kAsanVendorLibDir = "/data/vendor/lib64"; #else - "/system/lib", - "/vendor/lib", +static const char* const kSystemLibDir = "/system/lib"; +static const char* const kVendorLibDir = "/vendor/lib"; +static const char* const kAsanSystemLibDir = "/data/lib"; +static const char* const kAsanVendorLibDir = "/data/vendor/lib"; #endif + +static const char* const kDefaultLdPaths[] = { + kSystemLibDir, + kVendorLibDir, nullptr }; static const char* const kAsanDefaultLdPaths[] = { -#if defined(__LP64__) - "/data/lib64", - "/system/lib64", - "/data/vendor/lib64", - "/vendor/lib64", -#else - "/data/lib", - "/system/lib", - "/data/vendor/lib", - "/vendor/lib", -#endif + kAsanSystemLibDir, + kSystemLibDir, + kAsanVendorLibDir, + kVendorLibDir, nullptr }; +// Is ASAN enabled? +static bool g_is_asan = false; + static bool is_system_library(const std::string& realpath) { for (const auto& dir : g_default_namespace.get_default_library_paths()) { if (file_is_in_dir(realpath, dir)) { @@ -126,11 +129,16 @@ static bool is_system_library(const std::string& realpath) { return false; } -#if defined(__LP64__) -static const char* const kSystemLibDir = "/system/lib64"; -#else -static const char* const kSystemLibDir = "/system/lib"; -#endif +// Checks if the file exists and not a directory. +static bool file_exists(const char* path) { + int fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC)); + if (fd == -1) { + return false; + } else { + close(fd); + return true; + } +} // TODO(dimitry): The grey-list is a workaround for http://b/26394120 --- // gradually remove libraries from this list until it is gone. @@ -1828,8 +1836,27 @@ void* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo, } } + std::string asan_name_holder; + + const char* translated_name = name; + if (g_is_asan) { + if (file_is_in_dir(name, kSystemLibDir)) { + asan_name_holder = std::string(kAsanSystemLibDir) + "/" + basename(name); + if (file_exists(asan_name_holder.c_str())) { + translated_name = asan_name_holder.c_str(); + PRINT("linker_asan dlopen translating \"%s\" -> \"%s\"", name, translated_name); + } + } else if (file_is_in_dir(name, kVendorLibDir)) { + asan_name_holder = std::string(kAsanVendorLibDir) + "/" + basename(name); + if (file_exists(asan_name_holder.c_str())) { + translated_name = asan_name_holder.c_str(); + PRINT("linker_asan dlopen translating \"%s\" -> \"%s\"", name, translated_name); + } + } + } + ProtectedDataGuard guard; - soinfo* si = find_library(ns, name, flags, extinfo, caller); + soinfo* si = find_library(ns, translated_name, flags, extinfo, caller); if (si != nullptr) { failure_guard.disable(); si->call_constructors(); @@ -3283,6 +3310,7 @@ static void init_default_namespace() { const char* bname = basename(interp); if (bname && (strcmp(bname, "linker_asan") == 0 || strcmp(bname, "linker_asan64") == 0)) { g_default_ld_paths = kAsanDefaultLdPaths; + g_is_asan = true; } else { g_default_ld_paths = kDefaultLdPaths; } |