Skip to content

Commit

Permalink
Recognise system/system_ext as a system image partition path.
Browse files Browse the repository at this point in the history
Also move the regex used for that next to the other partition regex'es
for visibility, and add some unit tests.

Test: atest libnativeloader_tests libnativeloader_e2e_tests
  on mokey_go32
Bug: 346515837
Change-Id: I30a85678e0d3c45645d6f089f5f1d92e1360e8bf
  • Loading branch information
marstj committed Jun 19, 2024
1 parent b8d63df commit 7d4ebce
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 7 deletions.
8 changes: 8 additions & 0 deletions libnativeloader/library_namespaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -138,6 +140,12 @@ Result<ApiDomain> GetApiDomainFromPathList(const std::string& path_list) {
return result;
}

// Returns true if the given path is in a partition-wide native library location,
// i.e. <partition root>/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
Expand Down
1 change: 1 addition & 0 deletions libnativeloader/library_namespaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ using ApiDomain = enum {

ApiDomain GetApiDomainFromPath(const std::string_view path);
Result<ApiDomain> 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
Expand Down
17 changes: 17 additions & 0 deletions libnativeloader/library_namespaces_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
11 changes: 4 additions & 7 deletions libnativeloader/native_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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()) {
Expand Down

0 comments on commit 7d4ebce

Please sign in to comment.