From fcad69682ab112b6a6be65f2156413ad88901eec Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Tue, 22 Aug 2017 10:24:28 +0900 Subject: [PATCH] vendor apk is unbundled Vendor apks has been regarded as bundled apps and thus provided with all internal libraries under /system/lib and /vendor/lib. However, in new devices where Treble is fully enabled, system and vendor partitions are no longer bundled together; system partition can be updated independently from the vendor partition. In that case, the apks in vendor partition are considered as unbundled so that access to /system/lib is limited. In addition, when the linker namespace is created for apks, information on whether the apk is in vendor partition or not is given to the libnativeloader library. The information is used to conditionally configure the linker namespace for vendors. For examle, vendor apks are allowed to access /vendor/lib even though they are considered as unbundled; because vendor apks and vendor libs are still bundled together in the same vendor partition. Bug: 63553457 Test: 1) set target as 2017 pixel 2) m -j CtsVendorJniTestCases 3) copy the built apk into /vendor/app/CtsVendorJniTestCases 4) reboot / factory reset 5) adb shell am instrument -w android.jni.vendor.cts Change-Id: Iadd34af2878c507d4d6ec50153abef4e65604ac9 --- core/java/android/app/LoadedApk.java | 18 +++++++++++++++--- .../internal/os/ClassLoaderFactory.java | 13 +++++++++++-- ..._android_internal_os_ClassLoaderFactory.cpp | 6 ++++-- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index b38be6626e50a..0f9a3d71313a7 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -625,17 +625,29 @@ public final class LoadedApk { final List zipPaths = new ArrayList<>(10); final List libPaths = new ArrayList<>(10); - final boolean isBundledApp = mApplicationInfo.isSystemApp() + boolean isBundledApp = mApplicationInfo.isSystemApp() && !mApplicationInfo.isUpdatedSystemApp(); + // Vendor apks are treated as bundled only when /vendor/lib is in the default search + // paths. If not, they are treated as unbundled; access to system libs is limited. + // Having /vendor/lib in the default search paths means that all system processes + // are allowed to use any vendor library, which in turn means that system is dependent + // on vendor partition. In the contrary, not having /vendor/lib in the default search + // paths mean that the two partitions are separated and thus we can treat vendor apks + // as unbundled. + final String defaultSearchPaths = System.getProperty("java.library.path"); + final boolean treatVendorApkAsUnbundled = !defaultSearchPaths.contains("/vendor/lib"); + if (mApplicationInfo.getCodePath().startsWith("/vendor/") && treatVendorApkAsUnbundled) { + isBundledApp = false; + } + makePaths(mActivityThread, isBundledApp, mApplicationInfo, zipPaths, libPaths); String libraryPermittedPath = mDataDir; if (isBundledApp) { // This is necessary to grant bundled apps access to // libraries located in subdirectories of /system/lib - libraryPermittedPath += File.pathSeparator + - System.getProperty("java.library.path"); + libraryPermittedPath += File.pathSeparator + defaultSearchPaths; } final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths); diff --git a/core/java/com/android/internal/os/ClassLoaderFactory.java b/core/java/com/android/internal/os/ClassLoaderFactory.java index b2b769ee2fece..387857f0c9971 100644 --- a/core/java/com/android/internal/os/ClassLoaderFactory.java +++ b/core/java/com/android/internal/os/ClassLoaderFactory.java @@ -88,12 +88,20 @@ public class ClassLoaderFactory { final ClassLoader classLoader = createClassLoader(dexPath, librarySearchPath, parent, classloaderName); + boolean isForVendor = false; + for (String path : dexPath.split(":")) { + if (path.startsWith("/vendor/")) { + isForVendor = true; + break; + } + } Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "createClassloaderNamespace"); String errorMessage = createClassloaderNamespace(classLoader, targetSdkVersion, librarySearchPath, libraryPermittedPath, - isNamespaceShared); + isNamespaceShared, + isForVendor); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); if (errorMessage != null) { @@ -108,5 +116,6 @@ public class ClassLoaderFactory { int targetSdkVersion, String librarySearchPath, String libraryPermittedPath, - boolean isNamespaceShared); + boolean isNamespaceShared, + boolean isForVendor); } diff --git a/core/jni/com_android_internal_os_ClassLoaderFactory.cpp b/core/jni/com_android_internal_os_ClassLoaderFactory.cpp index 7052e5f3ce4b0..9ce328948ca88 100644 --- a/core/jni/com_android_internal_os_ClassLoaderFactory.cpp +++ b/core/jni/com_android_internal_os_ClassLoaderFactory.cpp @@ -27,15 +27,17 @@ static jstring createClassloaderNamespace_native(JNIEnv* env, jint targetSdkVersion, jstring librarySearchPath, jstring libraryPermittedPath, - jboolean isShared) { + jboolean isShared, + jboolean isForVendor) { return android::CreateClassLoaderNamespace(env, targetSdkVersion, classLoader, isShared == JNI_TRUE, + isForVendor == JNI_TRUE, librarySearchPath, libraryPermittedPath); } static const JNINativeMethod g_methods[] = { { "createClassloaderNamespace", - "(Ljava/lang/ClassLoader;ILjava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;", + "(Ljava/lang/ClassLoader;ILjava/lang/String;Ljava/lang/String;ZZ)Ljava/lang/String;", reinterpret_cast(createClassloaderNamespace_native) }, };