From 3bd906146be88fb82ee4a93d06ff389a559155a7 Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Wed, 1 Feb 2017 08:54:43 -0800 Subject: [PATCH] Do not load second copy of a library into same namespace This workaround was introduced in M in order to make sure that linker loads libraries provided in apk in case a library with the same name was loaded by the system. This is no longer a problem starting with Android N because app is using different namespace and therefore does not see libraries loaded by the system. Test: bionic-unit-tests --gtest_filter=dl*:Dl* Change-Id: I9995258c0f361e8df35420682b84e85a0cb924b4 --- linker/linker.cpp | 42 ++++-------------------------------------- 1 file changed, 4 insertions(+), 38 deletions(-) diff --git a/linker/linker.cpp b/linker/linker.cpp index 83bd9f340..79c3ac54e 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -1228,10 +1228,7 @@ static bool load_library(android_namespace_t* ns, return load_library(ns, task, load_tasks, rtld_flags, realpath); } -// Returns true if library was found and false in 2 cases -// 1. (for default namespace only) The library was found but loaded under different -// target_sdk_version (*candidate != nullptr) -// 2. The library was not found by soname (*candidate is nullptr) +// Returns true if library was found and false otherwise static bool find_loaded_library_by_soname(android_namespace_t* ns, const char* name, soinfo** candidate) { *candidate = nullptr; @@ -1241,30 +1238,11 @@ static bool find_loaded_library_by_soname(android_namespace_t* ns, return false; } - uint32_t target_sdk_version = get_application_target_sdk_version(); - return !ns->soinfo_list().visit([&](soinfo* si) { const char* soname = si->get_soname(); if (soname != nullptr && (strcmp(name, soname) == 0)) { - // If the library was opened under different target sdk version - // skip this step and try to reopen it. The exceptions are - // "libdl.so" and global group. There is no point in skipping - // them because relocation process is going to use them - // in any case. - - // TODO (dimitry): remove this once linker stops imposing as libdl.so - bool is_libdl = (si == solist_get_head()); - - if (is_libdl || (si->get_dt_flags_1() & DF_1_GLOBAL) != 0 || - !si->is_linked() || si->get_target_sdk_version() == target_sdk_version || - ns != &g_default_namespace) { - *candidate = si; - return false; - } else if (*candidate == nullptr) { - // for the different sdk version in the default namespace - // remember the first library. - *candidate = si; - } + *candidate = si; + return false; } return true; @@ -1301,19 +1279,7 @@ static bool find_library_internal(android_namespace_t* ns, TRACE("[ \"%s\" find_loaded_library_by_soname failed (*candidate=%s@%p). Trying harder...]", task->get_name(), candidate == nullptr ? "n/a" : candidate->get_realpath(), candidate); - if (load_library(ns, task, zip_archive_cache, load_tasks, rtld_flags)) { - return true; - } else { - // In case we were unable to load the library but there - // is a candidate loaded under the same soname but different - // sdk level - return it anyways. - if (candidate != nullptr) { - task->set_soinfo(candidate); - return true; - } - } - - return false; + return load_library(ns, task, zip_archive_cache, load_tasks, rtld_flags); } static void soinfo_unload(soinfo* si); -- 2.11.0