diff options
author | 2024-01-30 21:33:09 +0000 | |
---|---|---|
committer | 2024-02-15 18:22:04 +0000 | |
commit | 8a9b51e34f3769a5e3ea3a4383e3f00489088738 (patch) | |
tree | 37b3705e0387d216b50bc2d1e027b1f8ccf5f914 /libnativeloader/native_loader.cpp | |
parent | 149b912110c31a2e1e69930e48fed8bbfbe04700 (diff) |
Refactorings to make more logic available at the top level in
native_loader.cpp.
- Make the code that determines the partition from the dex path
available to code in native_loader.cpp, and rename it since it'll be
applied to arbitrary paths, not just APK's.
- Move the linker namespace constants to a header file.
- Various other minor code cleanups.
To prepare for a later CL that needs to access these things from
OpenNativeLibrary. No functional changes.
Test: atest libnativeloader_e2e_tests libnativeloader_test
Bug: 237577392
Change-Id: Ifc762bf6d4664b2d477c4ed3af58f149fb4c1189
Diffstat (limited to 'libnativeloader/native_loader.cpp')
-rw-r--r-- | libnativeloader/native_loader.cpp | 130 |
1 files changed, 81 insertions, 49 deletions
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp index 2deb5ef3d0..42a0d39a87 100644 --- a/libnativeloader/native_loader.cpp +++ b/libnativeloader/native_loader.cpp @@ -27,16 +27,17 @@ #include <string> #include <vector> -#include <android-base/file.h> -#include <android-base/macros.h> -#include <android-base/strings.h> -#include <android-base/thread_annotations.h> -#include <nativebridge/native_bridge.h> -#include <nativehelper/scoped_utf_chars.h> +#include "android-base/file.h" +#include "android-base/macros.h" +#include "android-base/strings.h" +#include "android-base/thread_annotations.h" +#include "nativebridge/native_bridge.h" +#include "nativehelper/scoped_utf_chars.h" +#include "public_libraries.h" #ifdef ART_TARGET_ANDROID -#include <log/log.h> #include "library_namespaces.h" +#include "log/log.h" #include "nativeloader/dlext_namespaces.h" #endif @@ -46,6 +47,9 @@ namespace { #if defined(ART_TARGET_ANDROID) +using ::android::base::Result; +using ::android::nativeloader::LibraryNamespaces; + // NATIVELOADER_DEFAULT_NAMESPACE_LIBS is an environment variable that can be // used to list extra libraries (separated by ":") that libnativeloader will // load from the default namespace. The libraries must be listed without paths, @@ -62,14 +66,12 @@ namespace { // test libraries that depend on ART internal libraries. constexpr const char* kNativeloaderExtraLibs = "nativeloader-extra-libs"; -using android::nativeloader::LibraryNamespaces; - std::mutex g_namespaces_mutex; -LibraryNamespaces* g_namespaces = new LibraryNamespaces; -NativeLoaderNamespace* g_nativeloader_extra_libs_namespace = nullptr; +LibraryNamespaces* g_namespaces GUARDED_BY(g_namespaces_mutex) = new LibraryNamespaces; +NativeLoaderNamespace* g_nativeloader_extra_libs_namespace GUARDED_BY(g_namespaces_mutex) = nullptr; android_namespace_t* FindExportedNamespace(const char* caller_location) { - auto name = nativeloader::FindApexNamespaceName(caller_location); + Result<std::string> name = nativeloader::FindApexNamespaceName(caller_location); if (name.ok()) { android_namespace_t* boot_namespace = android_get_exported_namespace(name->c_str()); LOG_ALWAYS_FATAL_IF((boot_namespace == nullptr), @@ -139,20 +141,22 @@ Result<void*> TryLoadNativeloaderExtraLib(const char* path) { Result<NativeLoaderNamespace*> CreateClassLoaderNamespaceLocked(JNIEnv* env, int32_t target_sdk_version, jobject class_loader, + nativeloader::ApiDomain api_domain, bool is_shared, - jstring dex_path, - jstring library_path, - jstring permitted_path, - jstring uses_library_list) + const std::string& dex_path, + jstring library_path_j, + jstring permitted_path_j, + jstring uses_library_list_j) REQUIRES(g_namespaces_mutex) { Result<NativeLoaderNamespace*> ns = g_namespaces->Create(env, target_sdk_version, class_loader, + api_domain, is_shared, dex_path, - library_path, - permitted_path, - uses_library_list); + library_path_j, + permitted_path_j, + uses_library_list_j); if (!ns.ok()) { return ns; } @@ -163,7 +167,7 @@ Result<NativeLoaderNamespace*> CreateClassLoaderNamespaceLocked(JNIEnv* env, return ns; } -#endif // #if defined(ART_TARGET_ANDROID) +#endif // ART_TARGET_ANDROID } // namespace @@ -183,36 +187,63 @@ void ResetNativeLoader() { #endif } -jstring CreateClassLoaderNamespace(JNIEnv* env, int32_t target_sdk_version, jobject class_loader, - bool is_shared, jstring dex_path, jstring library_path, - jstring permitted_path, jstring uses_library_list) { +jstring CreateClassLoaderNamespace(JNIEnv* env, + int32_t target_sdk_version, + jobject class_loader, + bool is_shared, + jstring dex_path_j, + jstring library_path_j, + jstring permitted_path_j, + jstring uses_library_list_j) { #if defined(ART_TARGET_ANDROID) + std::string dex_path; + if (dex_path_j != nullptr) { + ScopedUtfChars dex_path_chars(env, dex_path_j); + dex_path = dex_path_chars.c_str(); + } + nativeloader::ApiDomain api_domain = nativeloader::GetApiDomainFromPath(dex_path); + std::lock_guard<std::mutex> guard(g_namespaces_mutex); Result<NativeLoaderNamespace*> ns = CreateClassLoaderNamespaceLocked(env, target_sdk_version, class_loader, + api_domain, is_shared, dex_path, - library_path, - permitted_path, - uses_library_list); + library_path_j, + permitted_path_j, + uses_library_list_j); if (!ns.ok()) { return env->NewStringUTF(ns.error().message().c_str()); } + #else - UNUSED(env, target_sdk_version, class_loader, is_shared, dex_path, library_path, permitted_path, - uses_library_list); + UNUSED(env, + target_sdk_version, + class_loader, + is_shared, + dex_path_j, + library_path_j, + permitted_path_j, + uses_library_list_j); #endif + return nullptr; } -void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path, - jobject class_loader, const char* caller_location, jstring library_path, - bool* needs_native_bridge, char** error_msg) { +void* OpenNativeLibrary(JNIEnv* env, + int32_t target_sdk_version, + const char* path, + jobject class_loader, + const char* caller_location, + jstring library_path_j, + bool* needs_native_bridge, + char** error_msg) { #if defined(ART_TARGET_ANDROID) - UNUSED(target_sdk_version); - if (class_loader == nullptr) { + // class_loader is null only for the boot class loader (see + // IsBootClassLoader call in JavaVMExt::LoadNativeLibrary), i.e. the caller + // is in the boot classpath. *needs_native_bridge = false; if (caller_location != nullptr) { android_namespace_t* boot_namespace = FindExportedNamespace(caller_location); @@ -244,8 +275,6 @@ void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* pat // Fall back to the system namespace. This happens for preloaded JNI // libraries in the zygote. - // TODO(b/185833744): Investigate if this should fall back to the app main - // namespace (aka anonymous namespace) instead. void* handle = OpenSystemLibrary(path, RTLD_NOW); if (handle == nullptr) { *error_msg = strdup(dlerror()); @@ -254,43 +283,46 @@ void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* pat } std::lock_guard<std::mutex> guard(g_namespaces_mutex); - NativeLoaderNamespace* ns; + NativeLoaderNamespace* ns = g_namespaces->FindNamespaceByClassLoader(env, class_loader); - if ((ns = g_namespaces->FindNamespaceByClassLoader(env, class_loader)) == nullptr) { + 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. + const std::string empty_dex_path; Result<NativeLoaderNamespace*> isolated_ns = CreateClassLoaderNamespaceLocked(env, target_sdk_version, class_loader, + nativeloader::API_DOMAIN_DEFAULT, /*is_shared=*/false, - /*dex_path=*/nullptr, - library_path, + empty_dex_path, + library_path_j, /*permitted_path=*/nullptr, /*uses_library_list=*/nullptr); if (!isolated_ns.ok()) { *error_msg = strdup(isolated_ns.error().message().c_str()); return nullptr; } else { - ns = *isolated_ns; + ns = isolated_ns.value(); } } return OpenNativeLibraryInNamespace(ns, path, needs_native_bridge, error_msg); -#else + +#else // !ART_TARGET_ANDROID UNUSED(env, target_sdk_version, class_loader, caller_location); // Do some best effort to emulate library-path support. It will not // work for dependencies. // // Note: null has a special meaning and must be preserved. - std::string c_library_path; // Empty string by default. - if (library_path != nullptr && path != nullptr && path[0] != '/') { - ScopedUtfChars library_path_utf_chars(env, library_path); - c_library_path = library_path_utf_chars.c_str(); + std::string library_path; // Empty string by default. + if (library_path_j != nullptr && path != nullptr && path[0] != '/') { + ScopedUtfChars library_path_utf_chars(env, library_path_j); + library_path = library_path_utf_chars.c_str(); } - std::vector<std::string> library_paths = base::Split(c_library_path, ":"); + std::vector<std::string> library_paths = base::Split(library_path, ":"); for (const std::string& lib_path : library_paths) { *needs_native_bridge = false; @@ -323,7 +355,7 @@ void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* pat } } return nullptr; -#endif +#endif // !ART_TARGET_ANDROID } bool CloseNativeLibrary(void* handle, const bool needs_native_bridge, char** error_msg) { @@ -351,7 +383,7 @@ void NativeLoaderFreeErrorMessage(char* msg) { #if defined(ART_TARGET_ANDROID) void* OpenNativeLibraryInNamespace(NativeLoaderNamespace* ns, const char* path, bool* needs_native_bridge, char** error_msg) { - auto handle = ns->Load(path); + Result<void*> handle = ns->Load(path); if (!handle.ok() && error_msg != nullptr) { *error_msg = strdup(handle.error().message().c_str()); } @@ -397,4 +429,4 @@ void LinkNativeLoaderNamespaceToExportedNamespaceLibrary(struct NativeLoaderName #endif // ART_TARGET_ANDROID -}; // namespace android +} // namespace android |