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) }, };