diff --git a/linker/linker.cpp b/linker/linker.cpp index 32df9113d..a0205dc3c 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -3826,8 +3826,14 @@ std::vector init_default_namespaces(const char* executable // we can no longer rely on the fact that libdl.so is part of default namespace // this is why we want to add ld-android.so to all namespaces from ld.config.txt soinfo* ld_android_so = solist_get_head(); + + // we also need vdso to be available for all namespaces (if present) + soinfo* vdso = solist_get_vdso(); for (auto it : namespaces) { it.second->add_soinfo(ld_android_so); + if (vdso != nullptr) { + it.second->add_soinfo(vdso); + } // somain and ld_preloads are added to these namespaces after LD_PRELOAD libs are linked } diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp index dc1fa7550..00c72d02a 100644 --- a/linker/linker_main.cpp +++ b/linker/linker_main.cpp @@ -64,6 +64,7 @@ static ElfW(Addr) get_elf_exec_load_bias(const ElfW(Ehdr)* elf); static soinfo* solist; static soinfo* sonext; static soinfo* somain; // main process, always the one after libdl_info +static soinfo* vdso; // vdso if present void solist_add_soinfo(soinfo* si) { sonext->next = si; @@ -104,6 +105,10 @@ soinfo* solist_get_somain() { return somain; } +soinfo* solist_get_vdso() { + return vdso; +} + int g_ld_debug_verbosity; abort_msg_t* g_abort_message = nullptr; // For debuggerd. @@ -158,6 +163,8 @@ static void add_vdso(KernelArgumentBlock& args) { si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_NODELETE); si->set_linked(); si->call_constructors(); + + vdso = si; } /* gdb expects the linker to be in the debug shared object list. @@ -280,6 +287,8 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args) { } } + add_vdso(args); + struct stat file_stat; // Stat "/proc/self/exe" instead of executable_path because // the executable could be unlinked by this point and it should @@ -366,8 +375,6 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args) { } } - add_vdso(args); - // Load ld_preloads and dependencies. std::vector needed_library_name_list; size_t ld_preloads_count = 0; diff --git a/linker/linker_main.h b/linker/linker_main.h index 8d486e846..b37b9472f 100644 --- a/linker/linker_main.h +++ b/linker/linker_main.h @@ -70,3 +70,4 @@ void solist_add_soinfo(soinfo* si); bool solist_remove_soinfo(soinfo* si); soinfo* solist_get_head(); soinfo* solist_get_somain(); +soinfo* solist_get_vdso(); diff --git a/tests/libs/ld_config_test_helper.cpp b/tests/libs/ld_config_test_helper.cpp index 592e8c0b1..87e512eff 100644 --- a/tests/libs/ld_config_test_helper.cpp +++ b/tests/libs/ld_config_test_helper.cpp @@ -14,13 +14,37 @@ * limitations under the License. */ +#include #include #include +#if __has_include() +#include +#endif #include extern int get_value_from_lib(); int main() { + bool skip_vdso_check = false; +#if __has_include() + if (getauxval(AT_SYSINFO_EHDR) == 0) { + skip_vdso_check = true; + } +#endif + + if (!skip_vdso_check) { + const char* vdso_name = "linux-vdso.so.1"; +#if defined(__i386__) + vdso_name = "linux-gate.so.1"; +#endif + void* handle = dlopen(vdso_name, RTLD_NOW); + if (handle == nullptr) { + printf("%s", dlerror()); + return 1; + } + dlclose(handle); + } + printf("%d", get_value_from_lib()); return 0; }