summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Martin Stjernholm <mast@google.com> 2024-11-27 18:10:12 +0000
committer Martin Stjernholm <mast@google.com> 2024-11-28 20:07:01 +0000
commitcca3341e67fd9f45362448428abd47da09cdb954 (patch)
tree8c774142faec127575a2e19a3eaf02172b4b1af1
parentecee442f6432c727eea77d80d9c20ba037bcbaa9 (diff)
Do not hold g_namespace_mutex during library loads.
Significantly shortens the locked durations, and makes it easier to ascertain there's no reentrancy through the load code paths. Test: atest libnativeloader_e2e_tests libnativeloader_test \ art_libnativeloader_cts_test libnativeloader_lazy_test with and without CHECK condition inverted Bug: 326505705 Bug: 326610154 Change-Id: Ib2290714fd102ae22f960e9f631c1623236f4d27
-rw-r--r--libnativeloader/native_loader.cpp72
1 files changed, 33 insertions, 39 deletions
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index 3d24c3da14..f37f661a3e 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -414,52 +414,46 @@ void* OpenNativeLibrary(JNIEnv* env,
}
}
- std::lock_guard<std::mutex> guard(g_namespaces_mutex);
-
+ NativeLoaderNamespace* ns;
+ const char* ns_descr;
{
- 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());
+ std::lock_guard<std::mutex> guard(g_namespaces_mutex);
+
+ ns = g_namespaces->FindNamespaceByClassLoader(env, class_loader);
+ ns_descr = "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*> res =
+ CreateClassLoaderNamespaceLocked(env,
+ target_sdk_version,
+ class_loader,
+ nativeloader::API_DOMAIN_DEFAULT,
+ /*is_shared=*/false,
+ empty_dex_path,
+ library_path_j,
+ /*permitted_path_j=*/nullptr,
+ /*uses_library_list_j=*/nullptr);
+ if (!res.ok()) {
+ ALOGD("Failed to create isolated ns for %s (caller=%s)",
+ path,
+ caller_location == nullptr ? "<unknown>" : caller_location);
+ *error_msg = strdup(res.error().message().c_str());
return nullptr;
}
- return handle.value();
+ ns = res.value();
+ ns_descr = "isolated";
}
}
- // 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_j=*/nullptr,
- /*uses_library_list_j=*/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",
+ *needs_native_bridge = ns->IsBridged();
+ Result<void*> handle = ns->Load(path);
+ ALOGD("Load %s using %s ns %s (caller=%s): %s",
path,
- isolated_ns.value()->name().c_str(),
+ ns_descr,
+ ns->name().c_str(),
caller_location == nullptr ? "<unknown>" : caller_location,
handle.ok() ? "ok" : handle.error().message().c_str());
if (!handle.ok()) {