Loading libnativeloader/include/nativeloader/native_loader.h +13 −3 Original line number Original line Diff line number Diff line Loading @@ -29,10 +29,20 @@ __attribute__((visibility("default"))) void PreloadPublicNativeLibraries(); void PreloadPublicNativeLibraries(); __attribute__((visibility("default"))) __attribute__((visibility("default"))) void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path, jstring CreateClassLoaderNamespace(JNIEnv* env, jobject class_loader, bool is_shared, jstring library_path, int32_t target_sdk_version, jobject class_loader, bool is_shared, jstring library_path, jstring permitted_path); jstring permitted_path); __attribute__((visibility("default"))) void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path, jobject class_loader, jstring library_path); #if defined(__ANDROID__) #if defined(__ANDROID__) // Look up linker namespace by class_loader. Returns nullptr if // Look up linker namespace by class_loader. Returns nullptr if // there is no namespace associated with the class_loader. // there is no namespace associated with the class_loader. Loading libnativeloader/native_loader.cpp +54 −18 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ #ifdef __ANDROID__ #ifdef __ANDROID__ #include <android/dlext.h> #include <android/dlext.h> #include "cutils/properties.h" #include "cutils/properties.h" #include "log/log.h" #endif #endif #include <algorithm> #include <algorithm> Loading Loading @@ -59,7 +60,8 @@ class LibraryNamespaces { public: public: LibraryNamespaces() : initialized_(false) { } LibraryNamespaces() : initialized_(false) { } android_namespace_t* GetOrCreate(JNIEnv* env, jobject class_loader, android_namespace_t* Create(JNIEnv* env, jobject class_loader, bool is_shared, bool is_shared, jstring java_library_path, jstring java_library_path, jstring java_permitted_path) { jstring java_permitted_path) { Loading @@ -79,9 +81,7 @@ class LibraryNamespaces { android_namespace_t* ns = FindNamespaceByClassLoader(env, class_loader); android_namespace_t* ns = FindNamespaceByClassLoader(env, class_loader); if (ns != nullptr) { LOG_FATAL_IF(ns != nullptr, "There is already a namespace associated with this classloader"); return ns; } uint64_t namespace_type = ANDROID_NAMESPACE_TYPE_ISOLATED; uint64_t namespace_type = ANDROID_NAMESPACE_TYPE_ISOLATED; if (is_shared) { if (is_shared) { Loading @@ -96,7 +96,9 @@ class LibraryNamespaces { permitted_path.c_str() : permitted_path.c_str() : nullptr); nullptr); if (ns != nullptr) { namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), ns)); namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), ns)); } return ns; return ns; } } Loading Loading @@ -135,6 +137,10 @@ class LibraryNamespaces { }; }; static LibraryNamespaces* g_namespaces = new LibraryNamespaces; static LibraryNamespaces* g_namespaces = new LibraryNamespaces; static bool namespaces_enabled(uint32_t target_sdk_version) { return target_sdk_version > 0; } #endif #endif void PreloadPublicNativeLibraries() { void PreloadPublicNativeLibraries() { Loading @@ -144,21 +150,52 @@ void PreloadPublicNativeLibraries() { } } void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path, jstring CreateClassLoaderNamespace(JNIEnv* env, jobject class_loader, bool is_shared, jstring java_library_path, int32_t target_sdk_version, jstring java_permitted_path) { jobject class_loader, bool is_shared, jstring library_path, jstring permitted_path) { #if defined(__ANDROID__) if (!namespaces_enabled(target_sdk_version)) { return nullptr; } android_namespace_t* ns = g_namespaces->Create(env, class_loader, is_shared, library_path, permitted_path); if (ns == nullptr) { return env->NewStringUTF(dlerror()); } #else UNUSED(env, target_sdk_version, class_loader, is_shared, library_path, permitted_path); #endif return nullptr; } void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path, jobject class_loader, jstring library_path) { #if defined(__ANDROID__) #if defined(__ANDROID__) if (target_sdk_version == 0 || class_loader == nullptr) { if (!namespaces_enabled(target_sdk_version) || class_loader == nullptr) { return dlopen(path, RTLD_NOW); return dlopen(path, RTLD_NOW); } } android_namespace_t* ns = android_namespace_t* ns = g_namespaces->FindNamespaceByClassLoader(env, class_loader); g_namespaces->GetOrCreate(env, class_loader, is_shared, java_library_path, java_permitted_path); if (ns == nullptr) { // This is the case where the classloader was not created by ApplicationLoaders // In this case we create an isolated not-shared namespace for it. ns = g_namespaces->Create(env, class_loader, false, library_path, nullptr); if (ns == nullptr) { if (ns == nullptr) { return nullptr; return nullptr; } } } android_dlextinfo extinfo; android_dlextinfo extinfo; extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE; extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE; Loading @@ -166,8 +203,7 @@ void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* pat return android_dlopen_ext(path, RTLD_NOW, &extinfo); return android_dlopen_ext(path, RTLD_NOW, &extinfo); #else #else UNUSED(env, target_sdk_version, class_loader, is_shared, UNUSED(env, target_sdk_version, class_loader, library_path); java_library_path, java_permitted_path); return dlopen(path, RTLD_NOW); return dlopen(path, RTLD_NOW); #endif #endif } } Loading Loading
libnativeloader/include/nativeloader/native_loader.h +13 −3 Original line number Original line Diff line number Diff line Loading @@ -29,10 +29,20 @@ __attribute__((visibility("default"))) void PreloadPublicNativeLibraries(); void PreloadPublicNativeLibraries(); __attribute__((visibility("default"))) __attribute__((visibility("default"))) void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path, jstring CreateClassLoaderNamespace(JNIEnv* env, jobject class_loader, bool is_shared, jstring library_path, int32_t target_sdk_version, jobject class_loader, bool is_shared, jstring library_path, jstring permitted_path); jstring permitted_path); __attribute__((visibility("default"))) void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path, jobject class_loader, jstring library_path); #if defined(__ANDROID__) #if defined(__ANDROID__) // Look up linker namespace by class_loader. Returns nullptr if // Look up linker namespace by class_loader. Returns nullptr if // there is no namespace associated with the class_loader. // there is no namespace associated with the class_loader. Loading
libnativeloader/native_loader.cpp +54 −18 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ #ifdef __ANDROID__ #ifdef __ANDROID__ #include <android/dlext.h> #include <android/dlext.h> #include "cutils/properties.h" #include "cutils/properties.h" #include "log/log.h" #endif #endif #include <algorithm> #include <algorithm> Loading Loading @@ -59,7 +60,8 @@ class LibraryNamespaces { public: public: LibraryNamespaces() : initialized_(false) { } LibraryNamespaces() : initialized_(false) { } android_namespace_t* GetOrCreate(JNIEnv* env, jobject class_loader, android_namespace_t* Create(JNIEnv* env, jobject class_loader, bool is_shared, bool is_shared, jstring java_library_path, jstring java_library_path, jstring java_permitted_path) { jstring java_permitted_path) { Loading @@ -79,9 +81,7 @@ class LibraryNamespaces { android_namespace_t* ns = FindNamespaceByClassLoader(env, class_loader); android_namespace_t* ns = FindNamespaceByClassLoader(env, class_loader); if (ns != nullptr) { LOG_FATAL_IF(ns != nullptr, "There is already a namespace associated with this classloader"); return ns; } uint64_t namespace_type = ANDROID_NAMESPACE_TYPE_ISOLATED; uint64_t namespace_type = ANDROID_NAMESPACE_TYPE_ISOLATED; if (is_shared) { if (is_shared) { Loading @@ -96,7 +96,9 @@ class LibraryNamespaces { permitted_path.c_str() : permitted_path.c_str() : nullptr); nullptr); if (ns != nullptr) { namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), ns)); namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), ns)); } return ns; return ns; } } Loading Loading @@ -135,6 +137,10 @@ class LibraryNamespaces { }; }; static LibraryNamespaces* g_namespaces = new LibraryNamespaces; static LibraryNamespaces* g_namespaces = new LibraryNamespaces; static bool namespaces_enabled(uint32_t target_sdk_version) { return target_sdk_version > 0; } #endif #endif void PreloadPublicNativeLibraries() { void PreloadPublicNativeLibraries() { Loading @@ -144,21 +150,52 @@ void PreloadPublicNativeLibraries() { } } void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path, jstring CreateClassLoaderNamespace(JNIEnv* env, jobject class_loader, bool is_shared, jstring java_library_path, int32_t target_sdk_version, jstring java_permitted_path) { jobject class_loader, bool is_shared, jstring library_path, jstring permitted_path) { #if defined(__ANDROID__) if (!namespaces_enabled(target_sdk_version)) { return nullptr; } android_namespace_t* ns = g_namespaces->Create(env, class_loader, is_shared, library_path, permitted_path); if (ns == nullptr) { return env->NewStringUTF(dlerror()); } #else UNUSED(env, target_sdk_version, class_loader, is_shared, library_path, permitted_path); #endif return nullptr; } void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path, jobject class_loader, jstring library_path) { #if defined(__ANDROID__) #if defined(__ANDROID__) if (target_sdk_version == 0 || class_loader == nullptr) { if (!namespaces_enabled(target_sdk_version) || class_loader == nullptr) { return dlopen(path, RTLD_NOW); return dlopen(path, RTLD_NOW); } } android_namespace_t* ns = android_namespace_t* ns = g_namespaces->FindNamespaceByClassLoader(env, class_loader); g_namespaces->GetOrCreate(env, class_loader, is_shared, java_library_path, java_permitted_path); if (ns == nullptr) { // This is the case where the classloader was not created by ApplicationLoaders // In this case we create an isolated not-shared namespace for it. ns = g_namespaces->Create(env, class_loader, false, library_path, nullptr); if (ns == nullptr) { if (ns == nullptr) { return nullptr; return nullptr; } } } android_dlextinfo extinfo; android_dlextinfo extinfo; extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE; extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE; Loading @@ -166,8 +203,7 @@ void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* pat return android_dlopen_ext(path, RTLD_NOW, &extinfo); return android_dlopen_ext(path, RTLD_NOW, &extinfo); #else #else UNUSED(env, target_sdk_version, class_loader, is_shared, UNUSED(env, target_sdk_version, class_loader, library_path); java_library_path, java_permitted_path); return dlopen(path, RTLD_NOW); return dlopen(path, RTLD_NOW); #endif #endif } } Loading