diff options
author | Dimitry Ivanov <dimitry@google.com> | 2016-05-12 15:34:41 -0700 |
---|---|---|
committer | Dimitry Ivanov <dimitry@google.com> | 2016-05-17 15:58:56 -0700 |
commit | ade364b4566212a0c16920443a84aa85ac31f781 (patch) | |
tree | 7fc40f020206d0bfd6629fd6d1bade01f365c895 /libnativeloader | |
parent | 6e394f0f6c693e6f05def66d0427abd385b3f798 (diff) | |
download | system_core-ade364b4566212a0c16920443a84aa85ac31f781.tar.gz system_core-ade364b4566212a0c16920443a84aa85ac31f781.tar.bz2 system_core-ade364b4566212a0c16920443a84aa85ac31f781.zip |
Set parent namespace for linker-namespaces
This change allows applications to share RTLD_GLOBAL
native libraries between namespaces associated with
different classloaders.
The rule is - if a library is GLOBAL within namespace
associated with parent classloader, it is shared
with namespace associated with this classloader
Note that the sharing happens on create_namespace
event, which is tied to createClassloader in case of
application classloaders created by the framework, for
custom application classloaders it is tied to first
loadLibrary() event.
Bug: http://b/28560538
Bug: https://code.google.com/p/android/issues/detail?id=208458
Change-Id: I7ee701166f8ec5eff033b7acc0f80c7aa4ec5bda
(cherry picked from commit 24db75c1ce7ff8376a475214b059b9a37ac07936)
Diffstat (limited to 'libnativeloader')
-rw-r--r-- | libnativeloader/dlext_namespaces.h | 3 | ||||
-rw-r--r-- | libnativeloader/native_loader.cpp | 28 |
2 files changed, 29 insertions, 2 deletions
diff --git a/libnativeloader/dlext_namespaces.h b/libnativeloader/dlext_namespaces.h index ca9e61979..13a44e2bf 100644 --- a/libnativeloader/dlext_namespaces.h +++ b/libnativeloader/dlext_namespaces.h @@ -83,7 +83,8 @@ extern struct android_namespace_t* android_create_namespace(const char* name, const char* ld_library_path, const char* default_library_path, uint64_t type, - const char* permitted_when_isolated_path); + const char* permitted_when_isolated_path, + android_namespace_t* parent); __END_DECLS diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp index 44f17cd99..0600b9e40 100644 --- a/libnativeloader/native_loader.cpp +++ b/libnativeloader/native_loader.cpp @@ -97,11 +97,14 @@ class LibraryNamespaces { namespace_type |= ANDROID_NAMESPACE_TYPE_SHARED; } + android_namespace_t* parent_ns = FindParentNamespaceByClassLoader(env, class_loader); + ns = android_create_namespace("classloader-namespace", nullptr, library_path.c_str(), namespace_type, - permitted_path.c_str()); + permitted_path.c_str(), + parent_ns); if (ns != nullptr) { namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), ns)); @@ -198,6 +201,29 @@ class LibraryNamespaces { return initialized_; } + jobject GetParentClassLoader(JNIEnv* env, jobject class_loader) { + jclass class_loader_class = env->FindClass("java/lang/ClassLoader"); + jmethodID get_parent = env->GetMethodID(class_loader_class, + "getParent", + "()Ljava/lang/ClassLoader;"); + + return env->CallObjectMethod(class_loader, get_parent); + } + + android_namespace_t* FindParentNamespaceByClassLoader(JNIEnv* env, jobject class_loader) { + jobject parent_class_loader = GetParentClassLoader(env, class_loader); + + while (parent_class_loader != nullptr) { + android_namespace_t* ns = FindNamespaceByClassLoader(env, parent_class_loader); + if (ns != nullptr) { + return ns; + } + + parent_class_loader = GetParentClassLoader(env, parent_class_loader); + } + return nullptr; + } + bool initialized_; std::vector<std::pair<jweak, android_namespace_t*>> namespaces_; std::string public_libraries_; |