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
This commit is contained in:
parent
7e2d49ae3e
commit
5aa67675f8
|
@ -155,32 +155,35 @@ static soinfo* solist;
|
||||||
static soinfo* sonext;
|
static soinfo* sonext;
|
||||||
static soinfo* somain; // main process, always the one after libdl_info
|
static soinfo* somain; // main process, always the one after libdl_info
|
||||||
|
|
||||||
static const char* const kDefaultLdPaths[] = {
|
|
||||||
#if defined(__LP64__)
|
#if defined(__LP64__)
|
||||||
"/system/lib64",
|
static const char* const kSystemLibDir = "/system/lib64";
|
||||||
"/vendor/lib64",
|
static const char* const kVendorLibDir = "/vendor/lib64";
|
||||||
|
static const char* const kAsanSystemLibDir = "/data/lib64";
|
||||||
|
static const char* const kAsanVendorLibDir = "/data/vendor/lib64";
|
||||||
#else
|
#else
|
||||||
"/system/lib",
|
static const char* const kSystemLibDir = "/system/lib";
|
||||||
"/vendor/lib",
|
static const char* const kVendorLibDir = "/vendor/lib";
|
||||||
|
static const char* const kAsanSystemLibDir = "/data/lib";
|
||||||
|
static const char* const kAsanVendorLibDir = "/data/vendor/lib";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static const char* const kDefaultLdPaths[] = {
|
||||||
|
kSystemLibDir,
|
||||||
|
kVendorLibDir,
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* const kAsanDefaultLdPaths[] = {
|
static const char* const kAsanDefaultLdPaths[] = {
|
||||||
#if defined(__LP64__)
|
kAsanSystemLibDir,
|
||||||
"/data/lib64",
|
kSystemLibDir,
|
||||||
"/system/lib64",
|
kAsanVendorLibDir,
|
||||||
"/data/vendor/lib64",
|
kVendorLibDir,
|
||||||
"/vendor/lib64",
|
|
||||||
#else
|
|
||||||
"/data/lib",
|
|
||||||
"/system/lib",
|
|
||||||
"/data/vendor/lib",
|
|
||||||
"/vendor/lib",
|
|
||||||
#endif
|
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Is ASAN enabled?
|
||||||
|
static bool g_is_asan = false;
|
||||||
|
|
||||||
static bool is_system_library(const std::string& realpath) {
|
static bool is_system_library(const std::string& realpath) {
|
||||||
for (const auto& dir : g_default_namespace.get_default_library_paths()) {
|
for (const auto& dir : g_default_namespace.get_default_library_paths()) {
|
||||||
if (file_is_in_dir(realpath, dir)) {
|
if (file_is_in_dir(realpath, dir)) {
|
||||||
|
@ -190,12 +193,16 @@ static bool is_system_library(const std::string& realpath) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__LP64__)
|
// Checks if the file exists and not a directory.
|
||||||
static const char* const kSystemLibDir = "/system/lib64";
|
static bool file_exists(const char* path) {
|
||||||
#else
|
int fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC));
|
||||||
static const char* const kSystemLibDir = "/system/lib";
|
if (fd == -1) {
|
||||||
#endif
|
return false;
|
||||||
|
} else {
|
||||||
|
close(fd);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
static std::string dirname(const char *path);
|
static std::string dirname(const char *path);
|
||||||
|
|
||||||
// TODO(dimitry): The grey-list is a workaround for http://b/26394120 ---
|
// TODO(dimitry): The grey-list is a workaround for http://b/26394120 ---
|
||||||
|
@ -2370,8 +2377,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;
|
ProtectedDataGuard guard;
|
||||||
soinfo* si = find_library(ns, name, flags, extinfo, caller);
|
soinfo* si = find_library(ns, translated_name, flags, extinfo, caller);
|
||||||
if (si != nullptr) {
|
if (si != nullptr) {
|
||||||
si->call_constructors();
|
si->call_constructors();
|
||||||
return si->to_handle();
|
return si->to_handle();
|
||||||
|
@ -4122,6 +4148,7 @@ static void init_default_namespace() {
|
||||||
const char* bname = basename(interp);
|
const char* bname = basename(interp);
|
||||||
if (bname && (strcmp(bname, "linker_asan") == 0 || strcmp(bname, "linker_asan64") == 0)) {
|
if (bname && (strcmp(bname, "linker_asan") == 0 || strcmp(bname, "linker_asan64") == 0)) {
|
||||||
g_default_ld_paths = kAsanDefaultLdPaths;
|
g_default_ld_paths = kAsanDefaultLdPaths;
|
||||||
|
g_is_asan = true;
|
||||||
} else {
|
} else {
|
||||||
g_default_ld_paths = kDefaultLdPaths;
|
g_default_ld_paths = kDefaultLdPaths;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue