summaryrefslogtreecommitdiff
path: root/linker/linker.cpp
diff options
context:
space:
mode:
authorDimitry Ivanov <dimitry@google.com>2016-08-09 19:38:43 -0700
committerDimitry Ivanov <dimitry@google.com>2016-08-10 21:37:50 -0700
commit45d25ca72872ed5df08da7a19a4c95c56d64088c (patch)
treeeb32b3458912e9ecbb77ac73b77596f4ea8e65c9 /linker/linker.cpp
parent4519a4d1829c9e9f80cf45f1003e5937f1dfb04e (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.cpp72
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;
}