summaryrefslogtreecommitdiffstats
path: root/linker
diff options
context:
space:
mode:
authorDmitriy Ivanov <dimitry@google.com>2015-06-29 14:48:25 -0700
committerDmitriy Ivanov <dimitry@google.com>2015-06-29 14:48:25 -0700
commitf7d5bf334dc4bc5b7399d4c8268e1b0bf676548f (patch)
tree6ceb11112515fce7d625d8c6d4715bee2f1b05eb /linker
parent06700b2b5e92a365505b15d0d05e2d5b0706c511 (diff)
downloadbionic-f7d5bf334dc4bc5b7399d4c8268e1b0bf676548f.zip
bionic-f7d5bf334dc4bc5b7399d4c8268e1b0bf676548f.tar.gz
bionic-f7d5bf334dc4bc5b7399d4c8268e1b0bf676548f.tar.bz2
Lock on dl_interate_phdr
There is possibility of someone dlclosing a library while dl_iterate_phdr in progress which can lead to dl_iterate_phdr calling callback with invalid address if it was unmapped by dlclose. Bug: http://b/22047255 Change-Id: I3fc0d9fd2c51fb36fd34cb035f37271fa893a7be
Diffstat (limited to 'linker')
-rw-r--r--linker/dlfcn.cpp5
-rw-r--r--linker/linker.cpp2
-rw-r--r--linker/linker.h2
3 files changed, 8 insertions, 1 deletions
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index a70abf5..ef454ab 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -158,6 +158,11 @@ int dlclose(void* handle) {
return 0;
}
+int dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
+ ScopedPthreadMutexLocker locker(&g_dl_mutex);
+ return do_dl_iterate_phdr(cb, data);
+}
+
void android_set_application_target_sdk_version(uint32_t target) {
// lock to avoid modification in the middle of dlopen.
ScopedPthreadMutexLocker locker(&g_dl_mutex);
diff --git a/linker/linker.cpp b/linker/linker.cpp
index e1b8ca9..f7b58c4 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -353,7 +353,7 @@ _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) {
// Here, we only have to provide a callback to iterate across all the
// loaded libraries. gcc_eh does the rest.
-int dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
+int do_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
int rv = 0;
for (soinfo* si = solist; si != nullptr; si = si->next) {
dl_phdr_info dl_info;
diff --git a/linker/linker.h b/linker/linker.h
index 6042cb8..023b672 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -421,6 +421,8 @@ void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path);
soinfo* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo);
void do_dlclose(soinfo* si);
+int do_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data);
+
const ElfW(Sym)* dlsym_linear_lookup(const char* name, soinfo** found, soinfo* caller, void* handle);
soinfo* find_containing_library(const void* addr);