summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libnativeloader/library_namespaces.cpp13
-rw-r--r--libnativeloader/library_namespaces.h3
-rw-r--r--libnativeloader/native_loader.cpp124
3 files changed, 96 insertions, 44 deletions
diff --git a/libnativeloader/library_namespaces.cpp b/libnativeloader/library_namespaces.cpp
index 683e76247f..2aeaf88a1e 100644
--- a/libnativeloader/library_namespaces.cpp
+++ b/libnativeloader/library_namespaces.cpp
@@ -23,6 +23,7 @@
#include <dirent.h>
#include <dlfcn.h>
+#include <optional>
#include <regex>
#include <string>
#include <vector>
@@ -356,12 +357,12 @@ Result<NativeLoaderNamespace*> LibraryNamespaces::Create(JNIEnv* env,
}
for (const std::string& each_jar_path : android::base::Split(dex_path, ":")) {
- Result<std::string> apex_ns_name = FindApexNamespaceName(each_jar_path);
- if (apex_ns_name.ok()) {
- const std::string& jni_libs = apex_jni_libraries(*apex_ns_name);
+ std::optional<std::string> apex_ns_name = FindApexNamespaceName(each_jar_path);
+ if (apex_ns_name.has_value()) {
+ const std::string& jni_libs = apex_jni_libraries(apex_ns_name.value());
if (jni_libs != "") {
Result<NativeLoaderNamespace> apex_ns =
- NativeLoaderNamespace::GetExportedNamespace(*apex_ns_name, is_bridged);
+ NativeLoaderNamespace::GetExportedNamespace(apex_ns_name.value(), is_bridged);
if (apex_ns.ok()) {
linked = app_ns->Link(&apex_ns.value(), jni_libs);
if (!linked.ok()) {
@@ -444,7 +445,7 @@ NativeLoaderNamespace* LibraryNamespaces::FindParentNamespaceByClassLoader(JNIEn
return nullptr;
}
-base::Result<std::string> FindApexNamespaceName(const std::string& location) {
+std::optional<std::string> FindApexNamespaceName(const std::string& location) {
// Lots of implicit assumptions here: we expect `location` to be of the form:
// /apex/modulename/...
//
@@ -458,7 +459,7 @@ base::Result<std::string> FindApexNamespaceName(const std::string& location) {
std::replace(name.begin(), name.end(), '.', '_');
return name;
}
- return base::Error();
+ return std::nullopt;
}
} // namespace android::nativeloader
diff --git a/libnativeloader/library_namespaces.h b/libnativeloader/library_namespaces.h
index 25edf4faf7..741d4116b8 100644
--- a/libnativeloader/library_namespaces.h
+++ b/libnativeloader/library_namespaces.h
@@ -22,6 +22,7 @@
#endif
#include <list>
+#include <optional>
#include <string>
#include "android-base/result.h"
@@ -93,7 +94,7 @@ class LibraryNamespaces {
std::list<std::pair<jweak, NativeLoaderNamespace>> namespaces_;
};
-Result<std::string> FindApexNamespaceName(const std::string& location);
+std::optional<std::string> FindApexNamespaceName(const std::string& location);
} // namespace android::nativeloader
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index 42a0d39a87..80af4da502 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -24,6 +24,7 @@
#include <algorithm>
#include <memory>
#include <mutex>
+#include <optional>
#include <string>
#include <vector>
@@ -70,15 +71,20 @@ std::mutex g_namespaces_mutex;
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) {
- 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),
- "Error finding namespace of apex: no namespace called %s", name->c_str());
- return boot_namespace;
+std::optional<NativeLoaderNamespace> FindApexNamespace(const char* caller_location) {
+ std::optional<std::string> name = nativeloader::FindApexNamespaceName(caller_location);
+ if (name.has_value()) {
+ // Native Bridge is never used for APEXes.
+ Result<NativeLoaderNamespace> ns =
+ NativeLoaderNamespace::GetExportedNamespace(name.value(), /*is_bridged=*/false);
+ LOG_ALWAYS_FATAL_IF(!ns.ok(),
+ "Error finding ns %s for APEX location %s: %s",
+ name.value().c_str(),
+ caller_location,
+ ns.error().message().c_str());
+ return ns.value();
}
- return nullptr;
+ return std::nullopt;
}
Result<void> CreateNativeloaderDefaultNamespaceLibsLink(NativeLoaderNamespace& ns)
@@ -135,7 +141,13 @@ Result<void*> TryLoadNativeloaderExtraLib(const char* path) {
if (!ns.ok()) {
return ns.error();
}
- return ns.value()->Load(path);
+
+ Result<void*> res = ns.value()->Load(path);
+ ALOGD("Load %s using ns %s from NATIVELOADER_DEFAULT_NAMESPACE_LIBS match: %s",
+ path,
+ ns.value()->name().c_str(),
+ res.ok() ? "ok" : res.error().message().c_str());
+ return res;
}
Result<NativeLoaderNamespace*> CreateClassLoaderNamespaceLocked(JNIEnv* env,
@@ -246,15 +258,21 @@ void* OpenNativeLibrary(JNIEnv* env,
// is in the boot classpath.
*needs_native_bridge = false;
if (caller_location != nullptr) {
- android_namespace_t* boot_namespace = FindExportedNamespace(caller_location);
- if (boot_namespace != nullptr) {
+ std::optional<NativeLoaderNamespace> ns = FindApexNamespace(caller_location);
+ if (ns.has_value()) {
const android_dlextinfo dlextinfo = {
.flags = ANDROID_DLEXT_USE_NAMESPACE,
- .library_namespace = boot_namespace,
+ .library_namespace = ns.value().ToRawAndroidNamespace(),
};
void* handle = android_dlopen_ext(path, RTLD_NOW, &dlextinfo);
- if (handle == nullptr) {
- *error_msg = strdup(dlerror());
+ char* dlerror_msg = handle == nullptr ? strdup(dlerror()) : nullptr;
+ ALOGD("Load %s using APEX ns %s for caller %s: %s",
+ path,
+ ns.value().name().c_str(),
+ caller_location,
+ dlerror_msg == nullptr ? "ok" : dlerror_msg);
+ if (dlerror_msg != nullptr) {
+ *error_msg = dlerror_msg;
}
return handle;
}
@@ -276,38 +294,70 @@ void* OpenNativeLibrary(JNIEnv* env,
// Fall back to the system namespace. This happens for preloaded JNI
// libraries in the zygote.
void* handle = OpenSystemLibrary(path, RTLD_NOW);
- if (handle == nullptr) {
- *error_msg = strdup(dlerror());
+ char* dlerror_msg = handle == nullptr ? strdup(dlerror()) : nullptr;
+ ALOGD("Load %s using system ns (caller=%s): %s",
+ path,
+ caller_location == nullptr ? "<unknown>" : caller_location,
+ dlerror_msg == nullptr ? "ok" : dlerror_msg);
+ if (dlerror_msg != nullptr) {
+ *error_msg = dlerror_msg;
}
return handle;
}
std::lock_guard<std::mutex> guard(g_namespaces_mutex);
- NativeLoaderNamespace* ns = g_namespaces->FindNamespaceByClassLoader(env, class_loader);
- 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,
- 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.value();
+ {
+ NativeLoaderNamespace* ns = g_namespaces->FindNamespaceByClassLoader(env, class_loader);
+ if (ns != nullptr) {
+ *needs_native_bridge = ns->IsBridged();
+ Result<void*> handle = ns->Load(path);
+ ALOGD("Load %s using ns %s from class loader (caller=%s): %s",
+ path,
+ ns->name().c_str(),
+ caller_location == nullptr ? "<unknown>" : caller_location,
+ handle.ok() ? "ok" : handle.error().message().c_str());
+ if (!handle.ok()) {
+ *error_msg = strdup(handle.error().message().c_str());
+ return nullptr;
+ }
+ return handle.value();
}
}
- return OpenNativeLibraryInNamespace(ns, path, needs_native_bridge, error_msg);
+ // 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,
+ empty_dex_path,
+ library_path_j,
+ /*permitted_path=*/nullptr,
+ /*uses_library_list=*/nullptr);
+ if (!isolated_ns.ok()) {
+ ALOGD("Failed to create isolated ns for %s (caller=%s)",
+ path,
+ caller_location == nullptr ? "<unknown>" : caller_location);
+ *error_msg = strdup(isolated_ns.error().message().c_str());
+ return nullptr;
+ }
+
+ *needs_native_bridge = isolated_ns.value()->IsBridged();
+ Result<void*> handle = isolated_ns.value()->Load(path);
+ ALOGD("Load %s using isolated ns %s (caller=%s): %s",
+ path,
+ isolated_ns.value()->name().c_str(),
+ caller_location == nullptr ? "<unknown>" : caller_location,
+ handle.ok() ? "ok" : handle.error().message().c_str());
+ if (!handle.ok()) {
+ *error_msg = strdup(handle.error().message().c_str());
+ return nullptr;
+ }
+ return handle.value();
#else // !ART_TARGET_ANDROID
UNUSED(env, target_sdk_version, class_loader, caller_location);