Don't create anonymous namespace
Anonymous namespace is not created separately. When a regular namespace is created with ANDROID_NAMESPACE_TYPE_ALSO_USED_AS_ANONYMOUS, that namespace is used as the anonymous namespace. Bug: 130388701 Test: CtsBionicTestCases Change-Id: Ie449a59f303487a7a9ff6fff98e6148e9f968fd2
This commit is contained in:
parent
fd56f55419
commit
25bedfd3dd
3 changed files with 50 additions and 14 deletions
|
@ -76,6 +76,7 @@
|
||||||
|
|
||||||
static std::unordered_map<void*, size_t> g_dso_handle_counters;
|
static std::unordered_map<void*, size_t> g_dso_handle_counters;
|
||||||
|
|
||||||
|
static bool g_anonymous_namespace_set = false;
|
||||||
static android_namespace_t* g_anonymous_namespace = &g_default_namespace;
|
static android_namespace_t* g_anonymous_namespace = &g_default_namespace;
|
||||||
static std::unordered_map<std::string, android_namespace_t*> g_exported_namespaces;
|
static std::unordered_map<std::string, android_namespace_t*> g_exported_namespaces;
|
||||||
|
|
||||||
|
@ -270,8 +271,6 @@ static bool translateSystemPathToApexPath(const char* name, std::string* out_nam
|
||||||
|
|
||||||
static std::vector<std::string> g_ld_preload_names;
|
static std::vector<std::string> g_ld_preload_names;
|
||||||
|
|
||||||
static bool g_anonymous_namespace_initialized;
|
|
||||||
|
|
||||||
#if STATS
|
#if STATS
|
||||||
struct linker_stats_t {
|
struct linker_stats_t {
|
||||||
int count[kRelocMax];
|
int count[kRelocMax];
|
||||||
|
@ -2471,14 +2470,29 @@ int do_dlclose(void* handle) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init_anonymous_namespace(const char* shared_lib_sonames, const char* library_search_path) {
|
// Make ns as the anonymous namespace that is a namespace used when
|
||||||
if (g_anonymous_namespace_initialized) {
|
// we fail to determine the caller address (e.g., call from mono-jited code)
|
||||||
DL_ERR("anonymous namespace has already been initialized.");
|
// Since there can be multiple anonymous namespace in a process, subsequent
|
||||||
return false;
|
// call to this function causes an error.
|
||||||
|
static bool set_anonymous_namespace(android_namespace_t* ns) {
|
||||||
|
if (!g_anonymous_namespace_set && ns != nullptr) {
|
||||||
|
CHECK(ns->is_also_used_as_anonymous());
|
||||||
|
g_anonymous_namespace = ns;
|
||||||
|
g_anonymous_namespace_set = true;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(b/130388701) remove this. Currently, this is used only for testing
|
||||||
|
// where we don't have classloader namespace.
|
||||||
|
bool init_anonymous_namespace(const char* shared_lib_sonames, const char* library_search_path) {
|
||||||
ProtectedDataGuard guard;
|
ProtectedDataGuard guard;
|
||||||
|
|
||||||
|
// Test-only feature: we need to change the anonymous namespace multiple times
|
||||||
|
// while the test is running.
|
||||||
|
g_anonymous_namespace_set = false;
|
||||||
|
|
||||||
// create anonymous namespace
|
// create anonymous namespace
|
||||||
// When the caller is nullptr - create_namespace will take global group
|
// When the caller is nullptr - create_namespace will take global group
|
||||||
// from the anonymous namespace, which is fine because anonymous namespace
|
// from the anonymous namespace, which is fine because anonymous namespace
|
||||||
|
@ -2488,21 +2502,18 @@ bool init_anonymous_namespace(const char* shared_lib_sonames, const char* librar
|
||||||
"(anonymous)",
|
"(anonymous)",
|
||||||
nullptr,
|
nullptr,
|
||||||
library_search_path,
|
library_search_path,
|
||||||
ANDROID_NAMESPACE_TYPE_ISOLATED,
|
ANDROID_NAMESPACE_TYPE_ISOLATED |
|
||||||
|
ANDROID_NAMESPACE_TYPE_ALSO_USED_AS_ANONYMOUS,
|
||||||
nullptr,
|
nullptr,
|
||||||
&g_default_namespace);
|
&g_default_namespace);
|
||||||
|
|
||||||
if (anon_ns == nullptr) {
|
CHECK(anon_ns != nullptr);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!link_namespaces(anon_ns, &g_default_namespace, shared_lib_sonames)) {
|
if (!link_namespaces(anon_ns, &g_default_namespace, shared_lib_sonames)) {
|
||||||
|
// TODO: delete anon_ns
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_anonymous_namespace = anon_ns;
|
|
||||||
g_anonymous_namespace_initialized = true;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2542,6 +2553,7 @@ android_namespace_t* create_namespace(const void* caller_addr,
|
||||||
ns->set_name(name);
|
ns->set_name(name);
|
||||||
ns->set_isolated((type & ANDROID_NAMESPACE_TYPE_ISOLATED) != 0);
|
ns->set_isolated((type & ANDROID_NAMESPACE_TYPE_ISOLATED) != 0);
|
||||||
ns->set_greylist_enabled((type & ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED) != 0);
|
ns->set_greylist_enabled((type & ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED) != 0);
|
||||||
|
ns->set_also_used_as_anonymous((type & ANDROID_NAMESPACE_TYPE_ALSO_USED_AS_ANONYMOUS) != 0);
|
||||||
|
|
||||||
if ((type & ANDROID_NAMESPACE_TYPE_SHARED) != 0) {
|
if ((type & ANDROID_NAMESPACE_TYPE_SHARED) != 0) {
|
||||||
// append parent namespace paths.
|
// append parent namespace paths.
|
||||||
|
@ -2573,6 +2585,16 @@ android_namespace_t* create_namespace(const void* caller_addr,
|
||||||
ns->set_default_library_paths(std::move(default_library_paths));
|
ns->set_default_library_paths(std::move(default_library_paths));
|
||||||
ns->set_permitted_paths(std::move(permitted_paths));
|
ns->set_permitted_paths(std::move(permitted_paths));
|
||||||
|
|
||||||
|
if (ns->is_also_used_as_anonymous() && !set_anonymous_namespace(ns)) {
|
||||||
|
DL_ERR("failed to set namespace: [name=\"%s\", ld_library_path=\"%s\", default_library_paths=\"%s\""
|
||||||
|
" permitted_paths=\"%s\"] as the anonymous namespace",
|
||||||
|
ns->get_name(),
|
||||||
|
android::base::Join(ns->get_ld_library_paths(), ':').c_str(),
|
||||||
|
android::base::Join(ns->get_default_library_paths(), ':').c_str(),
|
||||||
|
android::base::Join(ns->get_permitted_paths(), ':').c_str());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return ns;
|
return ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,6 +165,13 @@ enum {
|
||||||
*/
|
*/
|
||||||
ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED = 0x08000000,
|
ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED = 0x08000000,
|
||||||
|
|
||||||
|
/* This flag instructs linker to use this namespace as the anonymous
|
||||||
|
* namespace. There can be only one anonymous namespace in a process. If there
|
||||||
|
* already an anonymous namespace in the process, using this flag when
|
||||||
|
* creating a new namespace causes an error
|
||||||
|
*/
|
||||||
|
ANDROID_NAMESPACE_TYPE_ALSO_USED_AS_ANONYMOUS = 0x10000000,
|
||||||
|
|
||||||
ANDROID_NAMESPACE_TYPE_SHARED_ISOLATED = ANDROID_NAMESPACE_TYPE_SHARED |
|
ANDROID_NAMESPACE_TYPE_SHARED_ISOLATED = ANDROID_NAMESPACE_TYPE_SHARED |
|
||||||
ANDROID_NAMESPACE_TYPE_ISOLATED,
|
ANDROID_NAMESPACE_TYPE_ISOLATED,
|
||||||
};
|
};
|
||||||
|
|
|
@ -72,7 +72,10 @@ struct android_namespace_link_t {
|
||||||
|
|
||||||
struct android_namespace_t {
|
struct android_namespace_t {
|
||||||
public:
|
public:
|
||||||
android_namespace_t() : is_isolated_(false), is_greylist_enabled_(false) {}
|
android_namespace_t() :
|
||||||
|
is_isolated_(false),
|
||||||
|
is_greylist_enabled_(false),
|
||||||
|
is_also_used_as_anonymous_(false) {}
|
||||||
|
|
||||||
const char* get_name() const { return name_.c_str(); }
|
const char* get_name() const { return name_.c_str(); }
|
||||||
void set_name(const char* name) { name_ = name; }
|
void set_name(const char* name) { name_ = name; }
|
||||||
|
@ -83,6 +86,9 @@ struct android_namespace_t {
|
||||||
bool is_greylist_enabled() const { return is_greylist_enabled_; }
|
bool is_greylist_enabled() const { return is_greylist_enabled_; }
|
||||||
void set_greylist_enabled(bool enabled) { is_greylist_enabled_ = enabled; }
|
void set_greylist_enabled(bool enabled) { is_greylist_enabled_ = enabled; }
|
||||||
|
|
||||||
|
bool is_also_used_as_anonymous() const { return is_also_used_as_anonymous_; }
|
||||||
|
void set_also_used_as_anonymous(bool yes) { is_also_used_as_anonymous_ = yes; }
|
||||||
|
|
||||||
const std::vector<std::string>& get_ld_library_paths() const {
|
const std::vector<std::string>& get_ld_library_paths() const {
|
||||||
return ld_library_paths_;
|
return ld_library_paths_;
|
||||||
}
|
}
|
||||||
|
@ -164,6 +170,7 @@ struct android_namespace_t {
|
||||||
std::string name_;
|
std::string name_;
|
||||||
bool is_isolated_;
|
bool is_isolated_;
|
||||||
bool is_greylist_enabled_;
|
bool is_greylist_enabled_;
|
||||||
|
bool is_also_used_as_anonymous_;
|
||||||
std::vector<std::string> ld_library_paths_;
|
std::vector<std::string> ld_library_paths_;
|
||||||
std::vector<std::string> default_library_paths_;
|
std::vector<std::string> default_library_paths_;
|
||||||
std::vector<std::string> permitted_paths_;
|
std::vector<std::string> permitted_paths_;
|
||||||
|
|
Loading…
Reference in a new issue