Merge "linker: fix error message for inaccessible libs"
This commit is contained in:
commit
0b1c8be3be
4 changed files with 73 additions and 1 deletions
|
@ -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)) {
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue