aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Collingbourne <pcc@google.com>2019-04-30 16:05:13 -0700
committerStephen Hines <srhines@google.com>2019-06-06 02:10:57 -0700
commitd13cb58b3afda031fbe38f6dc8eaca28237c8a3b (patch)
tree2c24a26b97bdcf124828c7ab49db8db9854e2a3d
parentdd0d0d10a301991e53f387a0f89f7a4e27c2df07 (diff)
downloadandroid_bionic-d13cb58b3afda031fbe38f6dc8eaca28237c8a3b.tar.gz
android_bionic-d13cb58b3afda031fbe38f6dc8eaca28237c8a3b.tar.bz2
android_bionic-d13cb58b3afda031fbe38f6dc8eaca28237c8a3b.zip
Add bootstrap directory to bootstrap linker's search path.
A proposed set of changes: https://android-review.googlesource.com/q/topic:"no-dup-hwasans" will cause the HWASAN runtime to be moved from /system/lib64 to /system/lib64/bootstrap. This causes a problem in the case where libc is built with HWASAN but init is not built with HWASAN. In this case, libc.so will have a DT_NEEDED dependency on the HWASAN runtime but init will not. Currently, init and other bootstrap executables arrange to load bootstrap libraries by setting rpath, but rpath only has an effect on libraries directly depended on by the main executable, not libraries indirectly depended on by it. This means that the loading of the HWASAN runtime will fail. Instead of relying on rpath to find the bootstrap libraries, modify the bootstrap linker so that it searches the bootstrap library directory after searching the rpath. Bug: http://b/134503977 Test: Builds Change-Id: I297be32e04ecd316ee12b8e694588e1249e2bb89 Merged-In: I297be32e04ecd316ee12b8e694588e1249e2bb89 (cherry picked from commit ea11be0cc85cb5355ca7ed4ee8736ea52b72e38d)
-rw-r--r--linker/linker.cpp7
-rw-r--r--tests/dlfcn_test.cpp4
2 files changed, 11 insertions, 0 deletions
diff --git a/linker/linker.cpp b/linker/linker.cpp
index b59df7302..324f3ef23 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -1162,6 +1162,13 @@ static int open_library(android_namespace_t* ns,
}
}
+#if !defined(__ANDROID_APEX__)
+ if (fd == -1) {
+ std::vector<std::string> bootstrap_paths = { std::string(kSystemLibDir) + "/bootstrap" };
+ fd = open_library_on_paths(zip_archive_cache, name, file_offset, bootstrap_paths, realpath);
+ }
+#endif
+
if (fd == -1) {
fd = open_library_on_paths(zip_archive_cache, name, file_offset, ns->get_default_library_paths(), realpath);
}
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index f3be9883d..7ff553d49 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -999,6 +999,7 @@ TEST(dlfcn, dlopen_executable_by_absolute_path) {
#error "Unknown architecture"
#endif
#define PATH_TO_LIBC PATH_TO_SYSTEM_LIB "libc.so"
+#define PATH_TO_BOOTSTRAP_LIBC PATH_TO_SYSTEM_LIB "bootstrap/libc.so"
#define ALTERNATE_PATH_TO_LIBC ALTERNATE_PATH_TO_SYSTEM_LIB "libc.so"
TEST(dlfcn, dladdr_libc) {
@@ -1018,6 +1019,9 @@ TEST(dlfcn, dladdr_libc) {
sizeof(ALTERNATE_PATH_TO_SYSTEM_LIB) - 1) == 0) {
// Platform with emulated architecture. Symlink on ARC++.
ASSERT_TRUE(realpath(ALTERNATE_PATH_TO_LIBC, libc_realpath) == libc_realpath);
+ } else if (strncmp(PATH_TO_BOOTSTRAP_LIBC, info.dli_fname,
+ sizeof(PATH_TO_BOOTSTRAP_LIBC) - 1) == 0) {
+ ASSERT_TRUE(realpath(PATH_TO_BOOTSTRAP_LIBC, libc_realpath) == libc_realpath);
} else {
// /system/lib is symlink when this test is executed on host.
ASSERT_TRUE(realpath(PATH_TO_LIBC, libc_realpath) == libc_realpath);