From 899c4295652ba6c954c1dc590f9c288849f9119c Mon Sep 17 00:00:00 2001 From: Martin Stjernholm Date: Mon, 29 Jan 2024 19:57:04 +0000 Subject: Give full access to native libs from Java libs in the same partition (reland 2). For both packages and shared Java libs in system image partitions (system, product, vendor), load native libraries from the same partition by using the linker namespace for that partition ("default" or "system", "product", "sphal", respectively). This is only done for native libraries in the /lib(64) directories when specified by an absolute path (i.e. use java.lang.System.load rather than loadLibrary). Otherwise it's looked up using the classloader namespace for the package, as before. Since only loads with absolute paths are affected, compat issues are unlikely. However to be on the safe side it's only enabled for SDK level 35 (VIC) and later (regardless of targetSdkVersion of the package, because the affected code is in system image partitions). This relands https://r.android.com/2933611 but keeps the vendor and product API domain checks unchanged in the CreateClassLoaderNamespace code paths (cf. b/326631342). Test: atest libnativeloader_e2e_tests \ libnativeloader_test libnativeloader_lazy_test Test: libnativeloader_e2e_tests on S, Sv2, T, and U platforms in CI Test: ImsServiceEntitlementUnitTests Bug: 237577392 Change-Id: I246101c1663d81089d9b4ae9450c28d564a7603a --- libnativeloader/library_namespaces.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'libnativeloader/library_namespaces.cpp') diff --git a/libnativeloader/library_namespaces.cpp b/libnativeloader/library_namespaces.cpp index e2b27294f9..7b18b15dd0 100644 --- a/libnativeloader/library_namespaces.cpp +++ b/libnativeloader/library_namespaces.cpp @@ -85,6 +85,7 @@ 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. jobject GetParentClassLoader(JNIEnv* env, jobject class_loader) { jclass class_loader_class = env->FindClass("java/lang/ClassLoader"); @@ -103,11 +104,15 @@ ApiDomain GetApiDomainFromPath(const std::string_view path) { if (is_product_treblelized() && std::regex_match(path.begin(), path.end(), kProductPathRegex)) { return API_DOMAIN_PRODUCT; } + if (std::regex_match(path.begin(), path.end(), kSystemPathRegex)) { + return API_DOMAIN_SYSTEM; + } return API_DOMAIN_DEFAULT; } // Returns the API domain for a ':'-separated list of paths, or an error if they -// match more than one. +// match more than one. This function does not recognize API_DOMAIN_SYSTEM and +// will return API_DOMAIN_DEFAULT instead. Result GetApiDomainFromPathList(const std::string& path_list) { ApiDomain result = API_DOMAIN_DEFAULT; size_t start_pos = 0; @@ -115,13 +120,13 @@ Result GetApiDomainFromPathList(const std::string& path_list) { size_t end_pos = path_list.find(':', start_pos); ApiDomain api_domain = GetApiDomainFromPath(std::string_view(path_list).substr(start_pos, end_pos)); - // Allow mixing API_DOMAIN_DEFAULT with any other domain. That's a bit lax, - // since the default e.g. includes /data, which strictly speaking is a - // separate domain. However, we keep it this way to not risk compat issues - // until we actually need all domains. - if (api_domain != API_DOMAIN_DEFAULT) { - if (result != API_DOMAIN_DEFAULT && result != api_domain) { - return Error() << "Path list crosses partition boundaries: " << path_list; + if (api_domain == API_DOMAIN_VENDOR || api_domain == API_DOMAIN_PRODUCT) { + if ((result == API_DOMAIN_VENDOR || result == API_DOMAIN_PRODUCT) && result != api_domain) { + // Fail only if the path list has both vendor and product paths. Allow + // combinations of either with API_DOMAIN_SYSTEM and API_DOMAIN_DEFAULT, + // because the path list we get here may contain shared Java system + // libraries and app APKs which may be in /data. + return Error() << "Path list crosses vendor/product partition boundaries: " << path_list; } result = api_domain; } -- cgit v1.2.3-59-g8ed1b