From 22840aab47763c88598b32d1edcac4d8b3ef21f0 Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Fri, 4 Dec 2015 18:28:49 -0800 Subject: [PATCH] Allow dlopening public libs using absolute path dlopen on isolated namespaces should be able to open public libraries using absolute path not only soname. Bug: http://b/25853820 Change-Id: If574a67853dc51226f0f376e9e2d108316002f84 --- linker/linker.cpp | 10 +++++++--- tests/dlext_test.cpp | 23 +++++++++++++++++------ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/linker/linker.cpp b/linker/linker.cpp index 97802319a..3b1e1d46c 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -1582,9 +1582,6 @@ static int open_library(android_namespace_t* ns, } } - if (fd != -1 && !ns->is_accessible(*realpath)) { - fd = -1; - } return fd; } @@ -1701,6 +1698,13 @@ static bool load_library(android_namespace_t* ns, return false; } + if (!ns->is_accessible(realpath)) { + // do not load libraries if they are not accessible for the specified namespace. + DL_ERR("library \"%s\" is not accessible for the namespace \"%s\"", + name, ns->get_name()); + return false; + } + soinfo* si = soinfo_alloc(ns, realpath.c_str(), &file_stat, file_offset, rtld_flags); if (si == nullptr) { return false; diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp index 83791ebb2..97b52080f 100644 --- a/tests/dlext_test.cpp +++ b/tests/dlext_test.cpp @@ -617,7 +617,8 @@ TEST(dlext, ns_smoke) { const std::string lib_path = std::string(getenv("ANDROID_DATA")) + NATIVE_TESTS_PATH; - void* handle_public = dlopen((lib_path + "/public_namespace_libs/" + g_public_lib).c_str(), RTLD_NOW); + const std::string lib_public_path = lib_path + "/public_namespace_libs/" + g_public_lib; + void* handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW); ASSERT_TRUE(handle_public != nullptr) << dlerror(); ASSERT_TRUE(android_init_namespaces(path.c_str(), nullptr)) << dlerror(); @@ -652,6 +653,14 @@ TEST(dlext, ns_smoke) { ASSERT_TRUE(handle1 != handle2); + // dlopen for a public library using an absolute path should work for isolated namespaces + extinfo.library_namespace = ns2; + handle = android_dlopen_ext(lib_public_path.c_str(), RTLD_NOW, &extinfo); + ASSERT_TRUE(handle != nullptr) << dlerror(); + ASSERT_TRUE(handle == handle_public); + + dlclose(handle); + typedef const char* (*fn_t)(); fn_t ns_get_local_string1 = reinterpret_cast(dlsym(handle1, "ns_get_local_string")); @@ -715,7 +724,8 @@ TEST(dlext, ns_isolated) { std::string path = std::string("libc.so:libc++.so:libdl.so:libm.so:") + g_public_lib; const std::string lib_path = std::string(getenv("ANDROID_DATA")) + NATIVE_TESTS_PATH; - void* handle_public = dlopen((lib_path + "/public_namespace_libs/" + g_public_lib).c_str(), RTLD_NOW); + const std::string lib_public_path = lib_path + "/public_namespace_libs/" + g_public_lib; + void* handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW); ASSERT_TRUE(handle_public != nullptr) << dlerror(); android_set_application_target_sdk_version(42U); // something > 23 @@ -758,7 +768,7 @@ TEST(dlext, ns_isolated) { // Check dlopen by absolute path handle2 = android_dlopen_ext(lib_private_external_path.c_str(), RTLD_NOW, &extinfo); ASSERT_TRUE(handle2 == nullptr); - ASSERT_EQ("dlopen failed: library \"" + lib_private_external_path + "\" not found", dlerror()); + ASSERT_EQ("dlopen failed: library \"" + lib_private_external_path + "\" is not accessible for the namespace \"private_isolated1\"", dlerror()); extinfo.library_namespace = ns_isolated2; @@ -769,7 +779,7 @@ TEST(dlext, ns_isolated) { // Check dlopen by absolute path handle2 = android_dlopen_ext(lib_private_external_path.c_str(), RTLD_NOW, &extinfo); ASSERT_TRUE(handle2 == nullptr); - ASSERT_EQ("dlopen failed: library \"" + lib_private_external_path + "\" not found", dlerror()); + ASSERT_EQ("dlopen failed: library \"" + lib_private_external_path + "\" is not accessible for the namespace \"private_isolated2\"", dlerror()); typedef const char* (*fn_t)(); fn_t ns_get_local_string = reinterpret_cast(dlsym(handle1, "ns_get_local_string")); @@ -803,8 +813,9 @@ TEST(dlext, ns_anonymous) { const std::string lib_path = std::string(getenv("ANDROID_DATA")) + NATIVE_TESTS_PATH; - void* handle_public = dlopen((lib_path + "/public_namespace_libs/" + g_public_lib).c_str(), - RTLD_NOW); + const std::string lib_public_path = lib_path + "/public_namespace_libs/" + g_public_lib; + void* handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW); + ASSERT_TRUE(handle_public != nullptr) << dlerror(); ASSERT_TRUE(android_init_namespaces(path.c_str(), (lib_path + "/private_namespace_libs").c_str()))