summaryrefslogtreecommitdiff
path: root/libnativeloader/library_namespaces.cpp
diff options
context:
space:
mode:
author Martin Stjernholm <mast@google.com> 2022-09-11 02:15:37 +0100
committer Martin Stjernholm <mast@google.com> 2022-09-13 12:56:25 +0000
commita0a5d8ad760c73e7b21968aacc6232c091a893bb (patch)
tree87f41aa597d662df6b5013119ff417fd33f5ac13 /libnativeloader/library_namespaces.cpp
parenta501686ed1841053c54e318ce1ce15f96c484d55 (diff)
Give full access to system libs from other system libs.
In particular this addresses the case when an app without a shared namespace loads a shared system library that in turn loads a system JNI library. Give full access both ways between /system and /system_ext libraries, and add a shared system_ext library and loading from system_ext to test that. Test: atest libnativeloader_e2e_tests Bug: 237577392 Change-Id: Ief4e24dadbadd26c5602c9e593276fae01bd7038
Diffstat (limited to 'libnativeloader/library_namespaces.cpp')
-rw-r--r--libnativeloader/library_namespaces.cpp26
1 files changed, 21 insertions, 5 deletions
diff --git a/libnativeloader/library_namespaces.cpp b/libnativeloader/library_namespaces.cpp
index 0d038f54ab..fd21f168ab 100644
--- a/libnativeloader/library_namespaces.cpp
+++ b/libnativeloader/library_namespaces.cpp
@@ -83,15 +83,18 @@ constexpr const char* kAlwaysPermittedDirectories = "/data:/mnt/expand";
constexpr const char* kVendorLibPath = "/vendor/" LIB;
constexpr const char* kProductLibPath = "/product/" LIB ":/system/product/" LIB;
+constexpr const char* kSystemLibPath = "/system/" LIB ":/system_ext/" LIB;
const std::regex kVendorDexPathRegex("(^|:)/vendor/");
const std::regex kProductDexPathRegex("(^|:)(/system)?/product/");
+const std::regex kSystemDexPathRegex("(^|:)/system(_ext)?/"); // MUST be tested last.
-// Define origin of APK if it is from vendor partition or product partition
+// Define origin partition of APK
using ApkOrigin = enum {
APK_ORIGIN_DEFAULT = 0,
APK_ORIGIN_VENDOR = 1,
- APK_ORIGIN_PRODUCT = 2,
+ APK_ORIGIN_PRODUCT = 2, // Includes both /product and /system/product
+ APK_ORIGIN_SYSTEM = 3, // Includes both /system and /system_ext but not /system/product
};
jobject GetParentClassLoader(JNIEnv* env, jobject class_loader) {
@@ -114,6 +117,9 @@ ApkOrigin GetApkOriginFromDexPath(const std::string& dex_path) {
apk_origin = APK_ORIGIN_PRODUCT;
}
+ if (apk_origin == APK_ORIGIN_DEFAULT && std::regex_search(dex_path, kSystemDexPathRegex)) {
+ apk_origin = APK_ORIGIN_SYSTEM;
+ }
return apk_origin;
}
@@ -235,7 +241,18 @@ Result<NativeLoaderNamespace*> LibraryNamespaces::Create(JNIEnv* env, uint32_t t
const char* apk_origin_msg = "other apk"; // Only for debug logging.
if (!is_shared) {
- if (apk_origin == APK_ORIGIN_VENDOR) {
+ if (apk_origin == APK_ORIGIN_SYSTEM) {
+ // System apps commonly get shared namespaces and hence don't need this.
+ // In practice it's necessary for shared system libraries (i.e. JARs
+ // rather than actual APKs) that are loaded by ordinary apps which don't
+ // get shared namespaces.
+ apk_origin_msg = "system apk";
+
+ // Give access to all libraries in the system and system_ext partitions
+ // (they can freely access each other's private APIs).
+ library_path = library_path + ":" + kSystemLibPath;
+ permitted_path = permitted_path + ":" + kSystemLibPath;
+ } else if (apk_origin == APK_ORIGIN_VENDOR) {
unbundled_app_origin = APK_ORIGIN_VENDOR;
apk_origin_msg = "unbundled vendor apk";
@@ -289,8 +306,7 @@ Result<NativeLoaderNamespace*> LibraryNamespaces::Create(JNIEnv* env, uint32_t t
// they are to other apps, including those in system, system_ext, and
// product partitions. The reason is that when GSI is used, the system
// partition may get replaced, and then vendor apps may fail. It's fine for
- // product (and system_ext) apps, because those partitions aren't mounted in
- // GSI tests.
+ // product apps, because that partition isn't mounted in GSI tests.
auto libs =
filter_public_libraries(target_sdk_version, uses_libraries, extended_public_libraries());
if (!libs.empty()) {