Merge "linker: fix error message for inaccessible libs"

This commit is contained in:
Dimitry Ivanov 2017-10-24 06:44:19 +00:00 committed by Gerrit Code Review
commit 0b1c8be3be
4 changed files with 73 additions and 1 deletions

View file

@ -1433,6 +1433,8 @@ static bool find_library_internal(android_namespace_t* ns,
if (search_linked_namespaces) {
// if a library was not found - look into linked namespaces
// preserve current dlerror in the case it fails.
DlErrorRestorer dlerror_restorer;
for (auto& linked_namespace : ns->linked_namespaces()) {
if (find_library_in_linked_namespace(linked_namespace,
task)) {

View file

@ -32,6 +32,7 @@
#include <link.h>
#include <stddef.h>
#include <string>
#include <unordered_map>
#include <async_safe/log.h>
@ -39,7 +40,6 @@
#define DL_ERR(fmt, x...) \
do { \
async_safe_format_buffer(linker_get_error_buffer(), linker_get_error_buffer_size(), fmt, ##x); \
/* If LD_DEBUG is set high enough, log every dlerror(3) message. */ \
} while (false)
#define DL_WARN(fmt, x...) \
@ -75,4 +75,16 @@ extern std::unordered_map<uintptr_t, soinfo*> g_soinfo_handles_map;
char* linker_get_error_buffer();
size_t linker_get_error_buffer_size();
class DlErrorRestorer {
public:
DlErrorRestorer() {
saved_error_msg_ = linker_get_error_buffer();
}
~DlErrorRestorer() {
strlcpy(linker_get_error_buffer(), saved_error_msg_.c_str(), linker_get_error_buffer_size());
}
private:
std::string saved_error_msg_;
};
#endif /* __LINKER_GLOBALS_H */

View file

@ -1589,6 +1589,54 @@ TEST(dlext, ns_isolated_rtld_global) {
ASSERT_STREQ("dlopen failed: library \"libnstest_public.so\" not found", dlerror());
}
TEST(dlext, ns_inaccessible_error_message) {
// We set up 2 namespaces (a and b) and link a->b with a shared library
// libtestshared.so. Then try to dlopen different library with the same
// name from in namespace a. Note that library should not be accessible
// in either namespace but since it's soname is in the list of shared libs
// the linker will attempt to find it in linked namespace.
//
// Check the error message and make sure it mentions correct namespace name.
ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
android_namespace_t* ns_a =
android_create_namespace("ns_a",
nullptr,
(get_testlib_root() + "/private_namespace_libs").c_str(),
ANDROID_NAMESPACE_TYPE_ISOLATED,
nullptr,
nullptr);
ASSERT_TRUE(ns_a != nullptr) << dlerror();
ASSERT_TRUE(android_link_namespaces(ns_a, nullptr, g_core_shared_libs.c_str())) << dlerror();
android_namespace_t* ns_b =
android_create_namespace("ns_b",
nullptr,
get_testlib_root().c_str(),
ANDROID_NAMESPACE_TYPE_ISOLATED,
nullptr,
nullptr);
ASSERT_TRUE(ns_b != nullptr) << dlerror();
ASSERT_TRUE(android_link_namespaces(ns_b, nullptr, g_core_shared_libs.c_str())) << dlerror();
ASSERT_TRUE(android_link_namespaces(ns_a, ns_b, "libtestshared.so")) << dlerror();
android_dlextinfo extinfo;
extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
extinfo.library_namespace = ns_a;
std::string library_path = get_testlib_root() + "/inaccessible_libs/libtestshared.so";
void* handle = android_dlopen_ext(library_path.c_str(), RTLD_NOW, &extinfo);
ASSERT_TRUE(handle == nullptr);
std::string expected_dlerror =
android::base::StringPrintf("dlopen failed: library \"%s\" needed or dlopened by \"%s\""
" is not accessible for the namespace \"ns_a\"",
library_path.c_str(),
get_executable_path().c_str());
ASSERT_EQ(expected_dlerror, dlerror());
}
TEST(dlext, ns_anonymous) {
static const char* root_lib = "libnstest_root.so";
std::string shared_libs = g_core_shared_libs + ":" + g_public_lib;

View file

@ -439,6 +439,16 @@ cc_test_library {
srcs: ["empty.cpp"],
}
// -----------------------------------------------------------------------------
// Library for inaccessible shared library test
// -----------------------------------------------------------------------------
cc_test_library {
name: "libtestshared",
defaults: ["bionic_testlib_defaults"],
srcs: ["empty.cpp"],
relative_install_path: "/inaccessible_libs",
}
// -----------------------------------------------------------------------------
// Library with weak undefined function
// -----------------------------------------------------------------------------