Merge "linker: Allow link namespaces without name filters"
This commit is contained in:
commit
40517761dc
26 changed files with 463 additions and 16 deletions
|
@ -41,6 +41,11 @@ LIBC_OMR1 { # introduced=27
|
|||
__cfi_slowpath_diag;
|
||||
} LIBC_N;
|
||||
|
||||
LIBC_PRIVATE {
|
||||
global:
|
||||
android_link_namespaces_all_libs;
|
||||
} LIBC_OMR1;
|
||||
|
||||
LIBC_PLATFORM {
|
||||
global:
|
||||
__cfi_init;
|
||||
|
|
|
@ -40,6 +40,11 @@ LIBC_OMR1 { # introduced=27
|
|||
__cfi_slowpath_diag;
|
||||
} LIBC_N;
|
||||
|
||||
LIBC_PRIVATE {
|
||||
global:
|
||||
android_link_namespaces_all_libs;
|
||||
} LIBC_OMR1;
|
||||
|
||||
LIBC_PLATFORM {
|
||||
global:
|
||||
__cfi_init;
|
||||
|
|
|
@ -92,6 +92,11 @@ bool __loader_android_link_namespaces(
|
|||
struct android_namespace_t* namespace_to,
|
||||
const char* shared_libs_sonames);
|
||||
|
||||
__attribute__((__weak__, visibility("default")))
|
||||
bool __loader_android_link_namespaces_all_libs(
|
||||
struct android_namespace_t* namespace_from,
|
||||
struct android_namespace_t* namespace_to);
|
||||
|
||||
__attribute__((__weak__, visibility("default")))
|
||||
void __loader_android_dlwarning(void* obj, void (*f)(void*, const char*));
|
||||
|
||||
|
@ -204,6 +209,12 @@ bool android_link_namespaces(struct android_namespace_t* namespace_from,
|
|||
return __loader_android_link_namespaces(namespace_from, namespace_to, shared_libs_sonames);
|
||||
}
|
||||
|
||||
__attribute__((__weak__))
|
||||
bool android_link_namespaces_all_libs(struct android_namespace_t* namespace_from,
|
||||
struct android_namespace_t* namespace_to) {
|
||||
return __loader_android_link_namespaces_all_libs(namespace_from, namespace_to);
|
||||
}
|
||||
|
||||
__attribute__((__weak__))
|
||||
void android_dlwarning(void* obj, void (*f)(void*, const char*)) {
|
||||
__loader_android_dlwarning(obj, f);
|
||||
|
|
|
@ -40,6 +40,11 @@ LIBC_OMR1 { # introduced=27
|
|||
__cfi_slowpath_diag;
|
||||
} LIBC_N;
|
||||
|
||||
LIBC_PRIVATE {
|
||||
global:
|
||||
android_link_namespaces_all_libs;
|
||||
} LIBC_OMR1;
|
||||
|
||||
LIBC_PLATFORM {
|
||||
global:
|
||||
__cfi_init;
|
||||
|
|
|
@ -40,6 +40,11 @@ LIBC_OMR1 { # introduced=27
|
|||
__cfi_slowpath_diag;
|
||||
} LIBC_N;
|
||||
|
||||
LIBC_PRIVATE {
|
||||
global:
|
||||
android_link_namespaces_all_libs;
|
||||
} LIBC_OMR1;
|
||||
|
||||
LIBC_PLATFORM {
|
||||
global:
|
||||
__cfi_init;
|
||||
|
|
|
@ -40,6 +40,11 @@ LIBC_OMR1 { # introduced=27
|
|||
__cfi_slowpath_diag;
|
||||
} LIBC_N;
|
||||
|
||||
LIBC_PRIVATE {
|
||||
global:
|
||||
android_link_namespaces_all_libs;
|
||||
} LIBC_OMR1;
|
||||
|
||||
LIBC_PLATFORM {
|
||||
global:
|
||||
__cfi_init;
|
||||
|
|
|
@ -40,6 +40,11 @@ LIBC_OMR1 { # introduced=27
|
|||
__cfi_slowpath_diag;
|
||||
} LIBC_N;
|
||||
|
||||
LIBC_PRIVATE {
|
||||
global:
|
||||
android_link_namespaces_all_libs;
|
||||
} LIBC_OMR1;
|
||||
|
||||
LIBC_PLATFORM {
|
||||
global:
|
||||
__cfi_init;
|
||||
|
|
|
@ -40,6 +40,11 @@ LIBC_OMR1 { # introduced=27
|
|||
__cfi_slowpath_diag;
|
||||
} LIBC_N;
|
||||
|
||||
LIBC_PRIVATE {
|
||||
global:
|
||||
android_link_namespaces_all_libs;
|
||||
} LIBC_OMR1;
|
||||
|
||||
LIBC_PLATFORM {
|
||||
global:
|
||||
__cfi_init;
|
||||
|
|
|
@ -65,6 +65,8 @@ bool __loader_android_init_anonymous_namespace(const char* shared_libs_sonames,
|
|||
bool __loader_android_link_namespaces(android_namespace_t* namespace_from,
|
||||
android_namespace_t* namespace_to,
|
||||
const char* shared_libs_sonames) __LINKER_PUBLIC__;
|
||||
bool __loader_android_link_namespaces_all_libs(android_namespace_t* namespace_from,
|
||||
android_namespace_t* namespace_to) __LINKER_PUBLIC__;
|
||||
void __loader_android_set_application_target_sdk_version(uint32_t target) __LINKER_PUBLIC__;
|
||||
void __loader_android_update_LD_LIBRARY_PATH(const char* ld_library_path) __LINKER_PUBLIC__;
|
||||
void __loader_cfi_fail(uint64_t CallSiteTypeId,
|
||||
|
@ -266,6 +268,19 @@ bool __loader_android_link_namespaces(android_namespace_t* namespace_from,
|
|||
return success;
|
||||
}
|
||||
|
||||
bool __loader_android_link_namespaces_all_libs(android_namespace_t* namespace_from,
|
||||
android_namespace_t* namespace_to) {
|
||||
ScopedPthreadMutexLocker locker(&g_dl_mutex);
|
||||
|
||||
bool success = link_namespaces_all_libs(namespace_from, namespace_to);
|
||||
|
||||
if (!success) {
|
||||
__bionic_format_dlerror("android_link_namespaces_all_libs failed", linker_get_error_buffer());
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
android_namespace_t* __loader_android_get_exported_namespace(const char* name) {
|
||||
return get_exported_namespace(name);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ __strong_alias(__loader_android_get_LD_LIBRARY_PATH, __internal_linker_error);
|
|||
__strong_alias(__loader_android_get_exported_namespace, __internal_linker_error);
|
||||
__strong_alias(__loader_android_init_anonymous_namespace, __internal_linker_error);
|
||||
__strong_alias(__loader_android_link_namespaces, __internal_linker_error);
|
||||
__strong_alias(__loader_android_link_namespaces_all_libs, __internal_linker_error);
|
||||
__strong_alias(__loader_android_set_application_target_sdk_version, __internal_linker_error);
|
||||
__strong_alias(__loader_android_update_LD_LIBRARY_PATH, __internal_linker_error);
|
||||
__strong_alias(__loader_cfi_fail, __internal_linker_error);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
__loader_android_dlwarning;
|
||||
__loader_cfi_fail;
|
||||
__loader_android_link_namespaces;
|
||||
__loader_android_link_namespaces_all_libs;
|
||||
__loader_android_get_exported_namespace;
|
||||
__loader_dl_unwind_find_exidx;
|
||||
__loader_add_thread_local_dtor;
|
||||
|
|
|
@ -1430,7 +1430,7 @@ static bool find_library_in_linked_namespace(const android_namespace_link_t& nam
|
|||
}
|
||||
|
||||
// returning true with empty soinfo means that the library is okay to be
|
||||
// loaded in the namespace buy has not yet been loaded there before.
|
||||
// loaded in the namespace but has not yet been loaded there before.
|
||||
task->set_soinfo(nullptr);
|
||||
return true;
|
||||
}
|
||||
|
@ -2363,7 +2363,8 @@ android_namespace_t* create_namespace(const void* caller_addr,
|
|||
add_soinfos_to_namespace(parent_namespace->soinfo_list(), ns);
|
||||
// and copy parent namespace links
|
||||
for (auto& link : parent_namespace->linked_namespaces()) {
|
||||
ns->add_linked_namespace(link.linked_namespace(), link.shared_lib_sonames());
|
||||
ns->add_linked_namespace(link.linked_namespace(), link.shared_lib_sonames(),
|
||||
link.allow_all_shared_libs());
|
||||
}
|
||||
} else {
|
||||
// If not shared - copy only the shared group
|
||||
|
@ -2399,7 +2400,25 @@ bool link_namespaces(android_namespace_t* namespace_from,
|
|||
std::unordered_set<std::string> sonames_set(sonames.begin(), sonames.end());
|
||||
|
||||
ProtectedDataGuard guard;
|
||||
namespace_from->add_linked_namespace(namespace_to, sonames_set);
|
||||
namespace_from->add_linked_namespace(namespace_to, sonames_set, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool link_namespaces_all_libs(android_namespace_t* namespace_from,
|
||||
android_namespace_t* namespace_to) {
|
||||
if (namespace_from == nullptr) {
|
||||
DL_ERR("error linking namespaces: namespace_from is null.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (namespace_to == nullptr) {
|
||||
DL_ERR("error linking namespaces: namespace_to is null.");
|
||||
return false;
|
||||
}
|
||||
|
||||
ProtectedDataGuard guard;
|
||||
namespace_from->add_linked_namespace(namespace_to, std::unordered_set<std::string>(), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -3763,7 +3782,11 @@ std::vector<android_namespace_t*> init_default_namespaces(const char* executable
|
|||
auto it_to = namespaces.find(ns_link.ns_name());
|
||||
CHECK(it_to != namespaces.end());
|
||||
android_namespace_t* namespace_to = it_to->second;
|
||||
link_namespaces(namespace_from, namespace_to, ns_link.shared_libs().c_str());
|
||||
if (ns_link.allow_all_shared_libs()) {
|
||||
link_namespaces_all_libs(namespace_from, namespace_to);
|
||||
} else {
|
||||
link_namespaces(namespace_from, namespace_to, ns_link.shared_libs().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
// we can no longer rely on the fact that libdl.so is part of default namespace
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
__loader_android_dlwarning;
|
||||
__loader_cfi_fail;
|
||||
__loader_android_link_namespaces;
|
||||
__loader_android_link_namespaces_all_libs;
|
||||
__loader_android_get_exported_namespace;
|
||||
__loader_add_thread_local_dtor;
|
||||
__loader_remove_thread_local_dtor;
|
||||
|
|
|
@ -180,6 +180,9 @@ bool link_namespaces(android_namespace_t* namespace_from,
|
|||
android_namespace_t* namespace_to,
|
||||
const char* shared_lib_sonames);
|
||||
|
||||
bool link_namespaces_all_libs(android_namespace_t* namespace_from,
|
||||
android_namespace_t* namespace_to);
|
||||
|
||||
android_namespace_t* get_exported_namespace(const char* name);
|
||||
|
||||
void increment_dso_handle_reference_counter(void* dso_handle);
|
||||
|
|
|
@ -489,12 +489,15 @@ bool Config::read_binary_config(const char* ld_config_file_path,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool allow_all_shared_libs = properties.get_bool(property_name_prefix + ".link." +
|
||||
linked_ns_name + ".allow_all_shared_libs");
|
||||
|
||||
std::string shared_libs = properties.get_string(property_name_prefix +
|
||||
".link." +
|
||||
linked_ns_name +
|
||||
".shared_libs", &lineno);
|
||||
|
||||
if (shared_libs.empty()) {
|
||||
if (!allow_all_shared_libs && shared_libs.empty()) {
|
||||
*error_msg = create_error_msg(ld_config_file_path,
|
||||
lineno,
|
||||
std::string("list of shared_libs for ") +
|
||||
|
@ -505,7 +508,15 @@ bool Config::read_binary_config(const char* ld_config_file_path,
|
|||
return false;
|
||||
}
|
||||
|
||||
ns_config->add_namespace_link(linked_ns_name, shared_libs);
|
||||
if (allow_all_shared_libs && !shared_libs.empty()) {
|
||||
*error_msg = create_error_msg(ld_config_file_path, lineno,
|
||||
std::string("both shared_libs and allow_all_shared_libs "
|
||||
"are set for ") +
|
||||
name + "->" + linked_ns_name + " link.");
|
||||
return false;
|
||||
}
|
||||
|
||||
ns_config->add_namespace_link(linked_ns_name, shared_libs, allow_all_shared_libs);
|
||||
}
|
||||
|
||||
ns_config->set_isolated(properties.get_bool(property_name_prefix + ".isolated"));
|
||||
|
|
|
@ -43,8 +43,10 @@
|
|||
class NamespaceLinkConfig {
|
||||
public:
|
||||
NamespaceLinkConfig() = default;
|
||||
NamespaceLinkConfig(const std::string& ns_name, const std::string& shared_libs)
|
||||
: ns_name_(ns_name), shared_libs_(shared_libs) {}
|
||||
NamespaceLinkConfig(const std::string& ns_name, const std::string& shared_libs,
|
||||
bool allow_all_shared_libs)
|
||||
: ns_name_(ns_name), shared_libs_(shared_libs),
|
||||
allow_all_shared_libs_(allow_all_shared_libs) {}
|
||||
|
||||
const std::string& ns_name() const {
|
||||
return ns_name_;
|
||||
|
@ -54,9 +56,14 @@ class NamespaceLinkConfig {
|
|||
return shared_libs_;
|
||||
}
|
||||
|
||||
bool allow_all_shared_libs() const {
|
||||
return allow_all_shared_libs_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string ns_name_;
|
||||
std::string shared_libs_;
|
||||
bool allow_all_shared_libs_;
|
||||
};
|
||||
|
||||
class NamespaceConfig {
|
||||
|
@ -89,8 +96,9 @@ class NamespaceConfig {
|
|||
return namespace_links_;
|
||||
}
|
||||
|
||||
void add_namespace_link(const std::string& ns_name, const std::string& shared_libs) {
|
||||
namespace_links_.push_back(NamespaceLinkConfig(ns_name, shared_libs));
|
||||
void add_namespace_link(const std::string& ns_name, const std::string& shared_libs,
|
||||
bool allow_all_shared_libs) {
|
||||
namespace_links_.push_back(NamespaceLinkConfig(ns_name, shared_libs, allow_all_shared_libs));
|
||||
}
|
||||
|
||||
void set_isolated(bool isolated) {
|
||||
|
|
|
@ -40,8 +40,10 @@ struct android_namespace_t;
|
|||
struct android_namespace_link_t {
|
||||
public:
|
||||
android_namespace_link_t(android_namespace_t* linked_namespace,
|
||||
const std::unordered_set<std::string>& shared_lib_sonames)
|
||||
: linked_namespace_(linked_namespace), shared_lib_sonames_(shared_lib_sonames)
|
||||
const std::unordered_set<std::string>& shared_lib_sonames,
|
||||
bool allow_all_shared_libs)
|
||||
: linked_namespace_(linked_namespace), shared_lib_sonames_(shared_lib_sonames),
|
||||
allow_all_shared_libs_(allow_all_shared_libs)
|
||||
{}
|
||||
|
||||
android_namespace_t* linked_namespace() const {
|
||||
|
@ -53,12 +55,17 @@ struct android_namespace_link_t {
|
|||
}
|
||||
|
||||
bool is_accessible(const char* soname) const {
|
||||
return shared_lib_sonames_.find(soname) != shared_lib_sonames_.end();
|
||||
return allow_all_shared_libs_ || shared_lib_sonames_.find(soname) != shared_lib_sonames_.end();
|
||||
}
|
||||
|
||||
bool allow_all_shared_libs() const {
|
||||
return allow_all_shared_libs_;
|
||||
}
|
||||
|
||||
private:
|
||||
android_namespace_t* const linked_namespace_;
|
||||
const std::unordered_set<std::string> shared_lib_sonames_;
|
||||
bool allow_all_shared_libs_;
|
||||
};
|
||||
|
||||
struct android_namespace_t {
|
||||
|
@ -105,8 +112,10 @@ struct android_namespace_t {
|
|||
return linked_namespaces_;
|
||||
}
|
||||
void add_linked_namespace(android_namespace_t* linked_namespace,
|
||||
const std::unordered_set<std::string>& shared_lib_sonames) {
|
||||
linked_namespaces_.push_back(android_namespace_link_t(linked_namespace, shared_lib_sonames));
|
||||
const std::unordered_set<std::string>& shared_lib_sonames,
|
||||
bool allow_all_shared_libs) {
|
||||
linked_namespaces_.push_back(
|
||||
android_namespace_link_t(linked_namespace, shared_lib_sonames, allow_all_shared_libs));
|
||||
}
|
||||
|
||||
void add_soinfo(soinfo* si) {
|
||||
|
|
|
@ -81,6 +81,8 @@ static const char* config_str =
|
|||
"namespace.vndk.search.paths = /system/${LIB}/vndk\n"
|
||||
"namespace.vndk.asan.search.paths = /data\n"
|
||||
"namespace.vndk.asan.search.paths += /system/${LIB}/vndk\n"
|
||||
"namespace.vndk.links = default\n"
|
||||
"namespace.vndk.link.default.allow_all_shared_libs = true\n"
|
||||
"\n";
|
||||
|
||||
static bool write_version(const std::string& path, uint32_t version) {
|
||||
|
@ -154,10 +156,14 @@ static void run_linker_config_smoke_test(bool is_asan) {
|
|||
|
||||
const auto& default_ns_links = default_ns_config->links();
|
||||
ASSERT_EQ(2U, default_ns_links.size());
|
||||
|
||||
ASSERT_EQ("system", default_ns_links[0].ns_name());
|
||||
ASSERT_EQ("libc.so:libm.so:libdl.so:libstdc++.so", default_ns_links[0].shared_libs());
|
||||
ASSERT_FALSE(default_ns_links[0].allow_all_shared_libs());
|
||||
|
||||
ASSERT_EQ("vndk", default_ns_links[1].ns_name());
|
||||
ASSERT_EQ("libcutils.so:libbase.so", default_ns_links[1].shared_libs());
|
||||
ASSERT_FALSE(default_ns_links[1].allow_all_shared_libs());
|
||||
|
||||
auto& ns_configs = config->namespace_configs();
|
||||
ASSERT_EQ(3U, ns_configs.size());
|
||||
|
@ -187,8 +193,13 @@ static void run_linker_config_smoke_test(bool is_asan) {
|
|||
ASSERT_TRUE(ns_vndk != nullptr) << "vndk namespace was not found";
|
||||
|
||||
ASSERT_FALSE(ns_vndk->isolated()); // malformed bool property
|
||||
ASSERT_FALSE(ns_vndk->visible()); // undefined bool property
|
||||
ASSERT_FALSE(ns_vndk->visible()); // undefined bool property
|
||||
ASSERT_EQ(kExpectedVndkSearchPath, ns_vndk->search_paths());
|
||||
|
||||
const auto& ns_vndk_links = ns_vndk->links();
|
||||
ASSERT_EQ(1U, ns_vndk_links.size());
|
||||
ASSERT_EQ("default", ns_vndk_links[0].ns_name());
|
||||
ASSERT_TRUE(ns_vndk_links[0].allow_all_shared_libs());
|
||||
}
|
||||
|
||||
TEST(linker_config, smoke) {
|
||||
|
@ -198,3 +209,40 @@ TEST(linker_config, smoke) {
|
|||
TEST(linker_config, asan_smoke) {
|
||||
run_linker_config_smoke_test(true);
|
||||
}
|
||||
|
||||
TEST(linker_config, ns_link_shared_libs_invalid_settings) {
|
||||
// This unit test ensures an error is emitted when a namespace link in ld.config.txt specifies
|
||||
// both shared_libs and allow_all_shared_libs.
|
||||
|
||||
static const char config_str[] =
|
||||
"dir.test = /data/local/tmp\n"
|
||||
"\n"
|
||||
"[test]\n"
|
||||
"additional.namespaces = system\n"
|
||||
"namespace.default.links = system\n"
|
||||
"namespace.default.link.system.shared_libs = libc.so:libm.so\n"
|
||||
"namespace.default.link.system.allow_all_shared_libs = true\n"
|
||||
"\n";
|
||||
|
||||
TemporaryFile tmp_file;
|
||||
close(tmp_file.fd);
|
||||
tmp_file.fd = -1;
|
||||
|
||||
android::base::WriteStringToFile(config_str, tmp_file.path);
|
||||
|
||||
TemporaryDir tmp_dir;
|
||||
|
||||
std::string executable_path = std::string(tmp_dir.path) + "/some-binary";
|
||||
|
||||
const Config* config = nullptr;
|
||||
std::string error_msg;
|
||||
ASSERT_FALSE(Config::read_binary_config(tmp_file.path,
|
||||
executable_path.c_str(),
|
||||
false,
|
||||
&config,
|
||||
&error_msg));
|
||||
ASSERT_TRUE(config == nullptr);
|
||||
ASSERT_EQ(std::string(tmp_file.path) + ":6: "
|
||||
"error: both shared_libs and allow_all_shared_libs are set for default->system link.",
|
||||
error_msg);
|
||||
}
|
||||
|
|
|
@ -554,6 +554,10 @@ cc_test {
|
|||
"libnstest_root",
|
||||
"libnstest_public",
|
||||
"libnstest_public_internal",
|
||||
"libnstest_ns_a_public1",
|
||||
"libnstest_ns_a_public1_internal",
|
||||
"libnstest_ns_b_public2",
|
||||
"libnstest_ns_b_public3",
|
||||
],
|
||||
}
|
||||
|
||||
|
|
|
@ -95,6 +95,9 @@ extern bool android_link_namespaces(android_namespace_t* from,
|
|||
android_namespace_t* to,
|
||||
const char* shared_libs_sonames);
|
||||
|
||||
extern bool android_link_namespaces_all_libs(android_namespace_t* from,
|
||||
android_namespace_t* to);
|
||||
|
||||
extern void android_set_application_target_sdk_version(uint32_t target);
|
||||
|
||||
__END_DECLS
|
||||
|
|
|
@ -1737,6 +1737,123 @@ TEST(dlext, ns_inaccessible_error_message) {
|
|||
ASSERT_EQ(expected_dlerror, dlerror());
|
||||
}
|
||||
|
||||
TEST(dlext, ns_link_namespaces_invalid_arguments) {
|
||||
ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
|
||||
|
||||
android_namespace_t* ns =
|
||||
android_create_namespace("private",
|
||||
nullptr,
|
||||
(get_testlib_root() + "/private_namespace_libs").c_str(),
|
||||
ANDROID_NAMESPACE_TYPE_REGULAR,
|
||||
nullptr,
|
||||
nullptr);
|
||||
ASSERT_TRUE(ns != nullptr) << dlerror();
|
||||
|
||||
// Test android_link_namespaces()
|
||||
ASSERT_FALSE(android_link_namespaces(nullptr, nullptr, "libc.so"));
|
||||
ASSERT_STREQ("android_link_namespaces failed: error linking namespaces: namespace_from is null.",
|
||||
dlerror());
|
||||
|
||||
ASSERT_FALSE(android_link_namespaces(ns, nullptr, nullptr));
|
||||
ASSERT_STREQ("android_link_namespaces failed: "
|
||||
"error linking namespaces \"private\"->\"(default)\": "
|
||||
"the list of shared libraries is empty.", dlerror());
|
||||
|
||||
ASSERT_FALSE(android_link_namespaces(ns, nullptr, ""));
|
||||
ASSERT_STREQ("android_link_namespaces failed: "
|
||||
"error linking namespaces \"private\"->\"(default)\": "
|
||||
"the list of shared libraries is empty.", dlerror());
|
||||
|
||||
// Test android_link_namespaces_all_libs()
|
||||
ASSERT_FALSE(android_link_namespaces_all_libs(nullptr, nullptr));
|
||||
ASSERT_STREQ("android_link_namespaces_all_libs failed: "
|
||||
"error linking namespaces: namespace_from is null.", dlerror());
|
||||
|
||||
ASSERT_FALSE(android_link_namespaces_all_libs(nullptr, ns));
|
||||
ASSERT_STREQ("android_link_namespaces_all_libs failed: "
|
||||
"error linking namespaces: namespace_from is null.", dlerror());
|
||||
|
||||
ASSERT_FALSE(android_link_namespaces_all_libs(ns, nullptr));
|
||||
ASSERT_STREQ("android_link_namespaces_all_libs failed: "
|
||||
"error linking namespaces: namespace_to is null.", dlerror());
|
||||
}
|
||||
|
||||
TEST(dlext, ns_allow_all_shared_libs) {
|
||||
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() + "/ns_a").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() + "/ns_b").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_b, ns_a, "libnstest_ns_a_public1.so")) << dlerror();
|
||||
ASSERT_TRUE(android_link_namespaces_all_libs(ns_a, ns_b)) << dlerror();
|
||||
|
||||
// Load libs with android_dlopen_ext() from namespace b
|
||||
android_dlextinfo extinfo;
|
||||
extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
|
||||
extinfo.library_namespace = ns_b;
|
||||
|
||||
void* ns_b_handle1 = android_dlopen_ext("libnstest_ns_a_public1.so", RTLD_NOW, &extinfo);
|
||||
ASSERT_TRUE(ns_b_handle1 != nullptr) << dlerror();
|
||||
|
||||
void* ns_b_handle1_internal =
|
||||
android_dlopen_ext("libnstest_ns_a_public1_internal.so", RTLD_NOW, &extinfo);
|
||||
ASSERT_TRUE(ns_b_handle1_internal == nullptr);
|
||||
|
||||
void* ns_b_handle2 = android_dlopen_ext("libnstest_ns_b_public2.so", RTLD_NOW, &extinfo);
|
||||
ASSERT_TRUE(ns_b_handle2 != nullptr) << dlerror();
|
||||
|
||||
void* ns_b_handle3 = android_dlopen_ext("libnstest_ns_b_public3.so", RTLD_NOW, &extinfo);
|
||||
ASSERT_TRUE(ns_b_handle3 != nullptr) << dlerror();
|
||||
|
||||
// Load libs with android_dlopen_ext() from namespace a
|
||||
extinfo.library_namespace = ns_a;
|
||||
|
||||
void* ns_a_handle1 = android_dlopen_ext("libnstest_ns_a_public1.so", RTLD_NOW, &extinfo);
|
||||
ASSERT_TRUE(ns_a_handle1 != nullptr) << dlerror();
|
||||
|
||||
void* ns_a_handle1_internal =
|
||||
android_dlopen_ext("libnstest_ns_a_public1_internal.so", RTLD_NOW, &extinfo);
|
||||
ASSERT_TRUE(ns_a_handle1_internal != nullptr) << dlerror();
|
||||
|
||||
void* ns_a_handle2 = android_dlopen_ext("libnstest_ns_b_public2.so", RTLD_NOW, &extinfo);
|
||||
ASSERT_TRUE(ns_a_handle2 != nullptr) << dlerror();
|
||||
|
||||
void* ns_a_handle3 = android_dlopen_ext("libnstest_ns_b_public3.so", RTLD_NOW, &extinfo);
|
||||
ASSERT_TRUE(ns_a_handle3 != nullptr) << dlerror();
|
||||
|
||||
// Compare the dlopen handle
|
||||
ASSERT_EQ(ns_b_handle1, ns_a_handle1);
|
||||
ASSERT_EQ(ns_b_handle2, ns_a_handle2);
|
||||
ASSERT_EQ(ns_b_handle3, ns_a_handle3);
|
||||
|
||||
// Close libs
|
||||
dlclose(ns_b_handle1);
|
||||
dlclose(ns_b_handle2);
|
||||
dlclose(ns_b_handle3);
|
||||
|
||||
dlclose(ns_a_handle1);
|
||||
dlclose(ns_a_handle1_internal);
|
||||
dlclose(ns_a_handle2);
|
||||
dlclose(ns_a_handle3);
|
||||
}
|
||||
|
||||
TEST(dlext, ns_anonymous) {
|
||||
static const char* root_lib = "libnstest_root.so";
|
||||
std::string shared_libs = g_core_shared_libs + ":" + g_public_lib;
|
||||
|
|
|
@ -258,6 +258,58 @@ cc_test_library {
|
|||
relative_install_path: "bionic-loader-test-libs/private_namespace_libs",
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Build test helper libraries for linker namespaces for allow all shared libs
|
||||
//
|
||||
// This set of libraries is used to verify linker namespaces for allow all
|
||||
// shared libs.
|
||||
//
|
||||
// Test cases
|
||||
// 1. Check that namespace a exposes libnstest_ns_a_public1 to
|
||||
// namespace b while keeping libnstest_ns_a_public1_internal as an
|
||||
// internal lib.
|
||||
// 2. Check that namespace b exposes all libraries to namespace a.
|
||||
//
|
||||
// Dependency tree (visibility)
|
||||
// libnstest_ns_b_public2.so (ns:b)
|
||||
// +-> libnstest_ns_a_public1.so (ns:a)
|
||||
// +-> libnstest_ns_a_public2_internal.so (ns:a)
|
||||
// +-> libnstest_ns_b_public3.so (ns:b)
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
cc_test_library {
|
||||
name: "libnstest_ns_a_public1",
|
||||
defaults: ["bionic_testlib_defaults"],
|
||||
srcs: ["libnstest_ns_a_public1.cpp"],
|
||||
relative_install_path: "bionic-loader-test-libs/ns_a",
|
||||
shared_libs: [
|
||||
"libnstest_ns_a_public1_internal",
|
||||
"libnstest_ns_b_public3",
|
||||
],
|
||||
}
|
||||
|
||||
cc_test_library {
|
||||
name: "libnstest_ns_a_public1_internal",
|
||||
defaults: ["bionic_testlib_defaults"],
|
||||
srcs: ["libnstest_ns_a_public1_internal.cpp"],
|
||||
relative_install_path: "bionic-loader-test-libs/ns_a",
|
||||
}
|
||||
|
||||
cc_test_library {
|
||||
name: "libnstest_ns_b_public2",
|
||||
defaults: ["bionic_testlib_defaults"],
|
||||
srcs: ["libnstest_ns_b_public2.cpp"],
|
||||
relative_install_path: "bionic-loader-test-libs/ns_b",
|
||||
shared_libs: ["libnstest_ns_a_public1"],
|
||||
}
|
||||
|
||||
cc_test_library {
|
||||
name: "libnstest_ns_b_public3",
|
||||
defaults: ["bionic_testlib_defaults"],
|
||||
srcs: ["libnstest_ns_b_public3.cpp"],
|
||||
relative_install_path: "bionic-loader-test-libs/ns_b",
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Build DT_RUNPATH test helper libraries
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
35
tests/libs/libnstest_ns_a_public1.cpp
Normal file
35
tests/libs/libnstest_ns_a_public1.cpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
static const char ns_a_public1_string[] = "libnstest_ns_a_public1.so";
|
||||
|
||||
extern "C" const char* get_ns_a_public1_string() {
|
||||
return ns_a_public1_string;
|
||||
}
|
||||
|
||||
|
||||
extern "C" const char *get_ns_a_public1_internal_string();
|
||||
|
||||
extern "C" const char *delegate_get_ns_a_public1_internal_string() {
|
||||
return get_ns_a_public1_internal_string();
|
||||
}
|
||||
|
||||
|
||||
extern "C" const char *get_ns_b_public3_string();
|
||||
|
||||
extern "C" const char *delegate_get_ns_b_public3_string() {
|
||||
return get_ns_b_public3_string();
|
||||
}
|
21
tests/libs/libnstest_ns_a_public1_internal.cpp
Normal file
21
tests/libs/libnstest_ns_a_public1_internal.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
static const char ns_a_public1_internal_string[] = "libnstest_ns_a_public1_internal.so";
|
||||
|
||||
extern "C" const char* get_ns_a_public1_internal_string() {
|
||||
return ns_a_public1_internal_string;
|
||||
}
|
28
tests/libs/libnstest_ns_b_public2.cpp
Normal file
28
tests/libs/libnstest_ns_b_public2.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
static const char ns_b_public2_string[] = "libnstest_ns_b_public2.so";
|
||||
|
||||
extern "C" const char* get_ns_b_public2_string() {
|
||||
return ns_b_public2_string;
|
||||
}
|
||||
|
||||
|
||||
extern "C" const char* get_ns_a_public1_string();
|
||||
|
||||
extern "C" const char* delegate_get_ns_a_public1_string() {
|
||||
return get_ns_a_public1_string();
|
||||
}
|
21
tests/libs/libnstest_ns_b_public3.cpp
Normal file
21
tests/libs/libnstest_ns_b_public3.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
static const char ns_b_public3_string[] = "libnstest_ns_b_public3.so";
|
||||
|
||||
extern "C" const char* get_ns_b_public3_string() {
|
||||
return ns_b_public3_string;
|
||||
}
|
Loading…
Reference in a new issue