diff --git a/libnativeloader/library_namespaces.cpp b/libnativeloader/library_namespaces.cpp index e0f3d6af8c..7aa14080ce 100644 --- a/libnativeloader/library_namespaces.cpp +++ b/libnativeloader/library_namespaces.cpp @@ -86,6 +86,8 @@ constexpr const char* kProductLibPath = "/product/" LIB ":/system/product/" LIB; const std::regex kVendorPathRegex("(/system)?/vendor/.*"); const std::regex kProductPathRegex("(/system)?/product/.*"); const std::regex kSystemPathRegex("/system(_ext)?/.*"); // MUST be tested last. +const std::regex kPartitionNativeLibPathRegex( + "/(system|(system/)?(system_ext|vendor|product))/lib(64)?/.*"); jobject GetParentClassLoader(JNIEnv* env, jobject class_loader) { jclass class_loader_class = env->FindClass("java/lang/ClassLoader"); @@ -138,6 +140,12 @@ Result GetApiDomainFromPathList(const std::string& path_list) { return result; } +// Returns true if the given path is in a partition-wide native library location, +// i.e. /lib(64). +bool IsPartitionNativeLibPath(const std::string& path) { + return std::regex_match(path, kPartitionNativeLibPathRegex); +} + void LibraryNamespaces::Initialize() { // Once public namespace is initialized there is no // point in running this code - it will have no effect diff --git a/libnativeloader/library_namespaces.h b/libnativeloader/library_namespaces.h index b932a557e0..c9adee314c 100644 --- a/libnativeloader/library_namespaces.h +++ b/libnativeloader/library_namespaces.h @@ -58,6 +58,7 @@ using ApiDomain = enum { ApiDomain GetApiDomainFromPath(const std::string_view path); Result GetApiDomainFromPathList(const std::string& path_list); +bool IsPartitionNativeLibPath(const std::string& path); // LibraryNamespaces is a singleton object that manages NativeLoaderNamespace // objects for an app process. Its main job is to create (and configure) a new diff --git a/libnativeloader/library_namespaces_test.cpp b/libnativeloader/library_namespaces_test.cpp index 706209a28e..0e2fa5de58 100644 --- a/libnativeloader/library_namespaces_test.cpp +++ b/libnativeloader/library_namespaces_test.cpp @@ -98,6 +98,23 @@ TEST(LibraryNamespacesTest, TestGetApiDomainFromPathList) { } } +TEST(LibraryNamespacesTest, TestIsPartitionNativeLibPath) { + EXPECT_TRUE(IsPartitionNativeLibPath("/system/lib/libfoo.so")); + EXPECT_TRUE(IsPartitionNativeLibPath("/system/lib64/libfoo.so")); + EXPECT_TRUE(IsPartitionNativeLibPath("/system_ext/lib64/libfoo.so")); + EXPECT_TRUE(IsPartitionNativeLibPath("/product/lib64/libfoo.so")); + EXPECT_TRUE(IsPartitionNativeLibPath("/vendor/lib64/libfoo.so")); + EXPECT_TRUE(IsPartitionNativeLibPath("/vendor/lib64/hw/libhw.so")); + EXPECT_TRUE(IsPartitionNativeLibPath("/system/system_ext/lib64/libfoo.so")); + EXPECT_TRUE(IsPartitionNativeLibPath("/system/product/lib64/libfoo.so")); + EXPECT_TRUE(IsPartitionNativeLibPath("/system/vendor/lib64/libfoo.so")); + + EXPECT_FALSE(IsPartitionNativeLibPath("/data/app/~~hash==/myapp-hash==/lib/arm64/libapp.so")); + EXPECT_FALSE( + IsPartitionNativeLibPath("/system/app/PrintSpooler/lib/arm64/libprintspooler_jni.so")); + EXPECT_FALSE(IsPartitionNativeLibPath("/product/app/Camera2/lib/arm64/libjni_jpegutil.so")); +} + } // namespace } // namespace nativeloader } // namespace android diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp index 13a4c2a482..580d833d9d 100644 --- a/libnativeloader/native_loader.cpp +++ b/libnativeloader/native_loader.cpp @@ -54,9 +54,6 @@ namespace { using ::android::base::Result; using ::android::nativeloader::LibraryNamespaces; -const std::regex kPartitionNativeLibPathRegex( - "/(system(_ext)?|(system/)?(vendor|product))/lib(64)?/.*"); - // 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, @@ -340,10 +337,10 @@ void* OpenNativeLibrary(JNIEnv* env, // path, so we don't affect the lookup process for libraries specified by name // only. if (caller_location != nullptr && - // Check that the library is in the partition-wide native library - // location. Apps in the partition may have their own native libraries, - // and those should still be loaded with the app's classloader namespace. - std::regex_match(path, kPartitionNativeLibPathRegex) && + // Apps in the partition may have their own native libraries which should + // be loaded with the app's classloader namespace, so only do this for + // libraries in the partition-wide lib(64) directories. + nativeloader::IsPartitionNativeLibPath(path) && // Don't do this if the system image is older than V, to avoid any compat // issues with apps and shared libs in them. android::modules::sdklevel::IsAtLeastV()) {