From 64a27bd856adf6ad126163926393f248ed050ea8 Mon Sep 17 00:00:00 2001 From: Andrei Onea Date: Thu, 16 Dec 2021 17:30:25 +0000 Subject: [PATCH] Ignore vendor apex priv-app permission allowlists Apexes contain the allowlists for privileged permissions used by their respective apk's, however vendor (partner) apexes should be forbidden from using this mechanism. Test: atest FrameworksServicesTests:SystemConfigTest Bug: 190375768 Change-Id: I34bf2a80fb66f2b2a732234111a338e3af1e919b --- .../java/com/android/server/SystemConfig.java | 16 +++++ .../server/systemconfig/SystemConfigTest.java | 61 +++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java index f364cb27888dc..fb0b7fdd6ce3d 100644 --- a/core/java/com/android/server/SystemConfig.java +++ b/core/java/com/android/server/SystemConfig.java @@ -663,6 +663,7 @@ public class SystemConfig { readPermissions(parser, Environment.buildPath(f, "etc", "permissions"), apexPermissionFlag); } + pruneVendorApexPrivappAllowlists(); } @VisibleForTesting @@ -1526,6 +1527,21 @@ public class SystemConfig { } } + /** + * Prunes out any privileged permission allowlists bundled in vendor apexes. + */ + @VisibleForTesting + public void pruneVendorApexPrivappAllowlists() { + for (String moduleName: mAllowedVendorApexes.keySet()) { + if (mApexPrivAppPermissions.containsKey(moduleName) + || mApexPrivAppDenyPermissions.containsKey(moduleName)) { + Slog.w(TAG, moduleName + " is a vendor apex, ignore its priv-app allowlist"); + mApexPrivAppPermissions.remove(moduleName); + mApexPrivAppDenyPermissions.remove(moduleName); + } + } + } + private void readInstallInUserType(XmlPullParser parser, Map> doInstallMap, Map> nonInstallMap) diff --git a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java index ca756f4778d50..bfdffc0e65677 100644 --- a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java +++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java @@ -360,6 +360,67 @@ public class SystemConfigTest { .containsExactly("android.permission.BAR"); } + @Test + public void pruneVendorApexPrivappAllowlists_removeVendor() + throws Exception { + File apexDir = createTempSubfolder("apex"); + + // Read non-vendor apex permission allowlists + final String allowlistNonVendorContents = + "" + + "" + + "" + + ""; + File nonVendorPermDir = + createTempSubfolder("apex/com.android.non_vendor/etc/permissions"); + File nonVendorPermissionFile = + createTempFile(nonVendorPermDir, "permissions.xml", allowlistNonVendorContents); + XmlPullParser nonVendorParser = readXmlUntilStartTag(nonVendorPermissionFile); + mSysConfig.readApexPrivAppPermissions(nonVendorParser, nonVendorPermissionFile, + apexDir.toPath()); + + // Read vendor apex permission allowlists + final String allowlistVendorContents = + "" + + "" + + "" + + ""; + File vendorPermissionFile = + createTempFile(createTempSubfolder("apex/com.android.vendor/etc/permissions"), + "permissions.xml", allowlistNonVendorContents); + XmlPullParser vendorParser = readXmlUntilStartTag(vendorPermissionFile); + mSysConfig.readApexPrivAppPermissions(vendorParser, vendorPermissionFile, + apexDir.toPath()); + + // Read allowed vendor apex list + final String allowedVendorContents = + "\n" + + " \n" + + ""; + final File allowedVendorFolder = createTempSubfolder("folder"); + createTempFile(allowedVendorFolder, "vendor-apex-allowlist.xml", allowedVendorContents); + readPermissions(allowedVendorFolder, /* Grant all permission flags */ ~0); + + // Finally, prune non-vendor allowlists. + // There is no guarantee in which order the above reads will be done, however pruning + // will always happen last. + mSysConfig.pruneVendorApexPrivappAllowlists(); + + assertThat(mSysConfig.getApexPrivAppPermissions("com.android.non_vendor", + "com.android.apk_in_non_vendor_apex")) + .containsExactly("android.permission.FOO"); + assertThat(mSysConfig.getApexPrivAppDenyPermissions("com.android.non_vendor", + "com.android.apk_in_non_vendor_apex")) + .containsExactly("android.permission.BAR"); + assertThat(mSysConfig.getApexPrivAppPermissions("com.android.vendor", + "com.android.apk_in_vendor_apex")) + .isNull(); + assertThat(mSysConfig.getApexPrivAppDenyPermissions("com.android.vendor", + "com.android.apk_in_vendor_apex")) + .isNull(); + } + /** * Tests that readPermissions works correctly for a library with on-bootclasspath-before * and on-bootclasspath-since.