Loading services/core/java/com/android/server/SystemConfig.java +38 −150 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import android.util.Xml; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.XmlUtils; import com.android.modules.utils.build.UnboundedSdkLevel; import com.android.server.pm.permission.PermissionAllowlist; import libcore.io.IoUtils; import libcore.util.EmptyArray; Loading Loading @@ -304,24 +305,7 @@ public class SystemConfig { final ArrayMap<String, List<CarrierAssociatedAppEntry>> mDisabledUntilUsedPreinstalledCarrierAssociatedApps = new ArrayMap<>(); final ArrayMap<String, ArraySet<String>> mPrivAppPermissions = new ArrayMap<>(); final ArrayMap<String, ArraySet<String>> mPrivAppDenyPermissions = new ArrayMap<>(); final ArrayMap<String, ArraySet<String>> mVendorPrivAppPermissions = new ArrayMap<>(); final ArrayMap<String, ArraySet<String>> mVendorPrivAppDenyPermissions = new ArrayMap<>(); final ArrayMap<String, ArraySet<String>> mProductPrivAppPermissions = new ArrayMap<>(); final ArrayMap<String, ArraySet<String>> mProductPrivAppDenyPermissions = new ArrayMap<>(); final ArrayMap<String, ArraySet<String>> mSystemExtPrivAppPermissions = new ArrayMap<>(); final ArrayMap<String, ArraySet<String>> mSystemExtPrivAppDenyPermissions = new ArrayMap<>(); final ArrayMap<String, ArrayMap<String, ArraySet<String>>> mApexPrivAppPermissions = new ArrayMap<>(); final ArrayMap<String, ArrayMap<String, ArraySet<String>>> mApexPrivAppDenyPermissions = new ArrayMap<>(); final ArrayMap<String, ArrayMap<String, Boolean>> mOemPermissions = new ArrayMap<>(); private final PermissionAllowlist mPermissionAllowlist = new PermissionAllowlist(); // Allowed associations between applications. If there are any entries // for an app, those are the only associations allowed; otherwise, all associations Loading Loading @@ -459,64 +443,8 @@ public class SystemConfig { return mDisabledUntilUsedPreinstalledCarrierAssociatedApps; } public ArraySet<String> getPrivAppPermissions(String packageName) { return mPrivAppPermissions.get(packageName); } public ArraySet<String> getPrivAppDenyPermissions(String packageName) { return mPrivAppDenyPermissions.get(packageName); } /** Get privapp permission allowlist for an apk-in-apex. */ public ArraySet<String> getApexPrivAppPermissions(String apexName, String apkPackageName) { return mApexPrivAppPermissions.getOrDefault(apexName, EMPTY_PERMISSIONS) .get(apkPackageName); } /** Get privapp permissions denylist for an apk-in-apex. */ public ArraySet<String> getApexPrivAppDenyPermissions(String apexName, String apkPackageName) { return mApexPrivAppDenyPermissions.getOrDefault(apexName, EMPTY_PERMISSIONS) .get(apkPackageName); } public ArraySet<String> getVendorPrivAppPermissions(String packageName) { return mVendorPrivAppPermissions.get(packageName); } public ArraySet<String> getVendorPrivAppDenyPermissions(String packageName) { return mVendorPrivAppDenyPermissions.get(packageName); } public ArraySet<String> getProductPrivAppPermissions(String packageName) { return mProductPrivAppPermissions.get(packageName); } public ArraySet<String> getProductPrivAppDenyPermissions(String packageName) { return mProductPrivAppDenyPermissions.get(packageName); } /** * Read from "permission" tags in /system_ext/etc/permissions/*.xml * @return Set of privileged permissions that are explicitly granted. */ public ArraySet<String> getSystemExtPrivAppPermissions(String packageName) { return mSystemExtPrivAppPermissions.get(packageName); } /** * Read from "deny-permission" tags in /system_ext/etc/permissions/*.xml * @return Set of privileged permissions that are explicitly denied. */ public ArraySet<String> getSystemExtPrivAppDenyPermissions(String packageName) { return mSystemExtPrivAppDenyPermissions.get(packageName); } public Map<String, Boolean> getOemPermissions(String packageName) { final Map<String, Boolean> oemPermissions = mOemPermissions.get(packageName); if (oemPermissions != null) { return oemPermissions; } return Collections.emptyMap(); public PermissionAllowlist getPermissionAllowlist() { return mPermissionAllowlist; } public ArrayMap<String, ArraySet<String>> getAllowedAssociations() { Loading Loading @@ -1253,20 +1181,20 @@ public class SystemConfig { Environment.getApexDirectory().toPath() + "/") && ApexProperties.updatable().orElse(false); if (vendor) { readPrivAppPermissions(parser, mVendorPrivAppPermissions, mVendorPrivAppDenyPermissions); readPrivAppPermissions(parser, mPermissionAllowlist.getVendorPrivilegedAppAllowlist()); } else if (product) { readPrivAppPermissions(parser, mProductPrivAppPermissions, mProductPrivAppDenyPermissions); readPrivAppPermissions(parser, mPermissionAllowlist.getProductPrivilegedAppAllowlist()); } else if (systemExt) { readPrivAppPermissions(parser, mSystemExtPrivAppPermissions, mSystemExtPrivAppDenyPermissions); readPrivAppPermissions(parser, mPermissionAllowlist.getSystemExtPrivilegedAppAllowlist()); } else if (apex) { readApexPrivAppPermissions(parser, permFile, Environment.getApexDirectory().toPath()); } else { readPrivAppPermissions(parser, mPrivAppPermissions, mPrivAppDenyPermissions); readPrivAppPermissions(parser, mPermissionAllowlist.getPrivilegedAppAllowlist()); } } else { logNotAllowedInPartition(name, permFile, parser); Loading Loading @@ -1589,50 +1517,10 @@ public class SystemConfig { } } private void readPrivAppPermissions(XmlPullParser parser, ArrayMap<String, ArraySet<String>> grantMap, ArrayMap<String, ArraySet<String>> denyMap) private void readPrivAppPermissions(@NonNull XmlPullParser parser, @NonNull ArrayMap<String, ArrayMap<String, Boolean>> allowlist) throws IOException, XmlPullParserException { String packageName = parser.getAttributeValue(null, "package"); if (TextUtils.isEmpty(packageName)) { Slog.w(TAG, "package is required for <privapp-permissions> in " + parser.getPositionDescription()); return; } ArraySet<String> permissions = grantMap.get(packageName); if (permissions == null) { permissions = new ArraySet<>(); } ArraySet<String> denyPermissions = denyMap.get(packageName); int depth = parser.getDepth(); while (XmlUtils.nextElementWithin(parser, depth)) { String name = parser.getName(); if ("permission".equals(name)) { String permName = parser.getAttributeValue(null, "name"); if (TextUtils.isEmpty(permName)) { Slog.w(TAG, "name is required for <permission> in " + parser.getPositionDescription()); continue; } permissions.add(permName); } else if ("deny-permission".equals(name)) { String permName = parser.getAttributeValue(null, "name"); if (TextUtils.isEmpty(permName)) { Slog.w(TAG, "name is required for <deny-permission> in " + parser.getPositionDescription()); continue; } if (denyPermissions == null) { denyPermissions = new ArraySet<>(); } denyPermissions.add(permName); } } grantMap.put(packageName, permissions); if (denyPermissions != null) { denyMap.put(packageName, denyPermissions); } readPermissionAllowlist(parser, allowlist, "privapp-permissions"); } private void readInstallInUserType(XmlPullParser parser, Loading Loading @@ -1683,14 +1571,21 @@ public class SystemConfig { } void readOemPermissions(XmlPullParser parser) throws IOException, XmlPullParserException { readPermissionAllowlist(parser, mPermissionAllowlist.getOemAppAllowlist(), "oem-permissions"); } private static void readPermissionAllowlist(@NonNull XmlPullParser parser, @NonNull ArrayMap<String, ArrayMap<String, Boolean>> allowlist, @NonNull String tagName) throws IOException, XmlPullParserException { final String packageName = parser.getAttributeValue(null, "package"); if (TextUtils.isEmpty(packageName)) { Slog.w(TAG, "package is required for <oem-permissions> in " Slog.w(TAG, "package is required for <" + tagName + "> in " + parser.getPositionDescription()); return; } ArrayMap<String, Boolean> permissions = mOemPermissions.get(packageName); ArrayMap<String, Boolean> permissions = allowlist.get(packageName); if (permissions == null) { permissions = new ArrayMap<>(); } Loading @@ -1698,24 +1593,24 @@ public class SystemConfig { while (XmlUtils.nextElementWithin(parser, depth)) { final String name = parser.getName(); if ("permission".equals(name)) { final String permName = parser.getAttributeValue(null, "name"); if (TextUtils.isEmpty(permName)) { final String permissionName = parser.getAttributeValue(null, "name"); if (TextUtils.isEmpty(permissionName)) { Slog.w(TAG, "name is required for <permission> in " + parser.getPositionDescription()); continue; } permissions.put(permName, Boolean.TRUE); permissions.put(permissionName, Boolean.TRUE); } else if ("deny-permission".equals(name)) { String permName = parser.getAttributeValue(null, "name"); if (TextUtils.isEmpty(permName)) { String permissionName = parser.getAttributeValue(null, "name"); if (TextUtils.isEmpty(permissionName)) { Slog.w(TAG, "name is required for <deny-permission> in " + parser.getPositionDescription()); continue; } permissions.put(permName, Boolean.FALSE); permissions.put(permissionName, Boolean.FALSE); } } mOemPermissions.put(packageName, permissions); allowlist.put(packageName, permissions); } private void readSplitPermission(XmlPullParser parser, File permFile) Loading Loading @@ -1865,21 +1760,14 @@ public class SystemConfig { Path apexDirectoryPath) throws IOException, XmlPullParserException { final String moduleName = getApexModuleNameFromFilePath(permFile.toPath(), apexDirectoryPath); final ArrayMap<String, ArraySet<String>> privAppPermissions; if (mApexPrivAppPermissions.containsKey(moduleName)) { privAppPermissions = mApexPrivAppPermissions.get(moduleName); } else { privAppPermissions = new ArrayMap<>(); mApexPrivAppPermissions.put(moduleName, privAppPermissions); } final ArrayMap<String, ArraySet<String>> privAppDenyPermissions; if (mApexPrivAppDenyPermissions.containsKey(moduleName)) { privAppDenyPermissions = mApexPrivAppDenyPermissions.get(moduleName); } else { privAppDenyPermissions = new ArrayMap<>(); mApexPrivAppDenyPermissions.put(moduleName, privAppDenyPermissions); } readPrivAppPermissions(parser, privAppPermissions, privAppDenyPermissions); final ArrayMap<String, ArrayMap<String, ArrayMap<String, Boolean>>> allowlists = mPermissionAllowlist.getApexPrivilegedAppAllowlists(); ArrayMap<String, ArrayMap<String, Boolean>> allowlist = allowlists.get(moduleName); if (allowlist == null) { allowlist = new ArrayMap<>(); allowlists.put(moduleName, allowlist); } readPrivAppPermissions(parser, allowlist); } private static boolean isSystemProcess() { Loading services/core/java/com/android/server/pm/PackageManagerShellCommand.java +46 −40 Original line number Diff line number Diff line Loading @@ -99,7 +99,6 @@ import android.system.Os; import android.text.TextUtils; import android.text.format.DateUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.IntArray; import android.util.PrintWriterPrinter; import android.util.Slog; Loading @@ -116,6 +115,7 @@ import com.android.server.SystemConfig; import com.android.server.art.ArtManagerLocal; import com.android.server.pm.PackageManagerShellCommandDataLoader.Metadata; import com.android.server.pm.permission.LegacyPermissionManagerInternal; import com.android.server.pm.permission.PermissionAllowlist; import com.android.server.pm.verify.domain.DomainVerificationShell; import dalvik.system.DexFile; Loading Loading @@ -2684,26 +2684,7 @@ class PackageManagerShellCommand extends ShellCommand { getErrPrintWriter().println("Error: no package specified."); return 1; } ArraySet<String> privAppPermissions = null; if (isVendorApp(pkg)) { privAppPermissions = SystemConfig.getInstance().getVendorPrivAppPermissions(pkg); } else if (isProductApp(pkg)) { privAppPermissions = SystemConfig.getInstance().getProductPrivAppPermissions(pkg); } else if (isSystemExtApp(pkg)) { privAppPermissions = SystemConfig.getInstance() .getSystemExtPrivAppPermissions(pkg); } else if (isApexApp(pkg)) { final String apexName = ApexManager.getInstance().getApexModuleNameForPackageName( getApexPackageNameContainingPackage(pkg)); privAppPermissions = SystemConfig.getInstance() .getApexPrivAppPermissions(apexName, pkg); } else { privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg); } getOutPrintWriter().println(privAppPermissions == null ? "{}" : privAppPermissions.toString()); getOutPrintWriter().println(getPrivAppPermissionsString(pkg, true)); return 0; } Loading @@ -2713,27 +2694,52 @@ class PackageManagerShellCommand extends ShellCommand { getErrPrintWriter().println("Error: no package specified."); return 1; } getOutPrintWriter().println(getPrivAppPermissionsString(pkg, false)); return 0; } ArraySet<String> privAppPermissions = null; if (isVendorApp(pkg)) { privAppPermissions = SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg); } else if (isProductApp(pkg)) { privAppPermissions = SystemConfig.getInstance().getProductPrivAppDenyPermissions(pkg); } else if (isSystemExtApp(pkg)) { privAppPermissions = SystemConfig.getInstance() .getSystemExtPrivAppDenyPermissions(pkg); } else if (isApexApp(pkg)) { final String apexName = ApexManager.getInstance().getApexModuleNameForPackageName( getApexPackageNameContainingPackage(pkg)); privAppPermissions = SystemConfig.getInstance() .getApexPrivAppDenyPermissions(apexName, pkg); @NonNull private String getPrivAppPermissionsString(@NonNull String packageName, boolean allowed) { final PermissionAllowlist permissionAllowlist = SystemConfig.getInstance().getPermissionAllowlist(); final ArrayMap<String, ArrayMap<String, Boolean>> privAppPermissions; if (isVendorApp(packageName)) { privAppPermissions = permissionAllowlist.getVendorPrivilegedAppAllowlist(); } else if (isProductApp(packageName)) { privAppPermissions = permissionAllowlist.getProductPrivilegedAppAllowlist(); } else if (isSystemExtApp(packageName)) { privAppPermissions = permissionAllowlist.getSystemExtPrivilegedAppAllowlist(); } else if (isApexApp(packageName)) { final String moduleName = ApexManager.getInstance().getApexModuleNameForPackageName( getApexPackageNameContainingPackage(packageName)); privAppPermissions = permissionAllowlist.getApexPrivilegedAppAllowlists() .get(moduleName); } else { privAppPermissions = SystemConfig.getInstance().getPrivAppDenyPermissions(pkg); privAppPermissions = permissionAllowlist.getPrivilegedAppAllowlist(); } final ArrayMap<String, Boolean> permissions = privAppPermissions != null ? privAppPermissions.get(packageName) : null; if (permissions == null) { return "{}"; } final StringBuilder result = new StringBuilder("{"); boolean isFirstPermission = true; final int permissionsSize = permissions.size(); for (int i = 0; i < permissionsSize; i++) { boolean permissionAllowed = permissions.valueAt(i); if (permissionAllowed != allowed) { continue; } getOutPrintWriter().println(privAppPermissions == null ? "{}" : privAppPermissions.toString()); return 0; if (isFirstPermission) { isFirstPermission = false; } else { result.append(", "); } String permissionName = permissions.keyAt(i); result.append(permissionName); } result.append("}"); return result.toString(); } private int runGetOemPermissions() { Loading @@ -2743,7 +2749,7 @@ class PackageManagerShellCommand extends ShellCommand { return 1; } final Map<String, Boolean> oemPermissions = SystemConfig.getInstance() .getOemPermissions(pkg); .getPermissionAllowlist().getOemAppAllowlist().get(pkg); if (oemPermissions == null || oemPermissions.isEmpty()) { getOutPrintWriter().println("{}"); } else { Loading services/core/java/com/android/server/pm/permission/PermissionAllowlist.java 0 → 100644 +140 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.pm.permission; import android.annotation.NonNull; import android.annotation.Nullable; import android.util.ArrayMap; /** * Data class for OEM and privileged app permission allowlist state. */ public final class PermissionAllowlist { @NonNull private final ArrayMap<String, ArrayMap<String, Boolean>> mOemAppAllowlist = new ArrayMap<>(); @NonNull private final ArrayMap<String, ArrayMap<String, Boolean>> mPrivilegedAppAllowlist = new ArrayMap<>(); @NonNull private final ArrayMap<String, ArrayMap<String, Boolean>> mVendorPrivilegedAppAllowlist = new ArrayMap<>(); @NonNull private final ArrayMap<String, ArrayMap<String, Boolean>> mProductPrivilegedAppAllowlist = new ArrayMap<>(); @NonNull private final ArrayMap<String, ArrayMap<String, Boolean>> mSystemExtPrivilegedAppAllowlist = new ArrayMap<>(); @NonNull private final ArrayMap<String, ArrayMap<String, ArrayMap<String, Boolean>>> mApexPrivilegedAppAllowlists = new ArrayMap<>(); @NonNull public ArrayMap<String, ArrayMap<String, Boolean>> getOemAppAllowlist() { return mOemAppAllowlist; } @NonNull public ArrayMap<String, ArrayMap<String, Boolean>> getPrivilegedAppAllowlist() { return mPrivilegedAppAllowlist; } @NonNull public ArrayMap<String, ArrayMap<String, Boolean>> getVendorPrivilegedAppAllowlist() { return mVendorPrivilegedAppAllowlist; } @NonNull public ArrayMap<String, ArrayMap<String, Boolean>> getProductPrivilegedAppAllowlist() { return mProductPrivilegedAppAllowlist; } @NonNull public ArrayMap<String, ArrayMap<String, Boolean>> getSystemExtPrivilegedAppAllowlist() { return mSystemExtPrivilegedAppAllowlist; } @NonNull public ArrayMap<String, ArrayMap<String, ArrayMap<String, Boolean>>> getApexPrivilegedAppAllowlists() { return mApexPrivilegedAppAllowlists; } @Nullable public Boolean getOemAppAllowlistState(@NonNull String packageName, @NonNull String permissionName) { ArrayMap<String, Boolean> permissions = mOemAppAllowlist.get(packageName); if (permissions == null) { return null; } return permissions.get(permissionName); } @Nullable public Boolean getPrivilegedAppAllowlistState(@NonNull String packageName, @NonNull String permissionName) { ArrayMap<String, Boolean> permissions = mPrivilegedAppAllowlist.get(packageName); if (permissions == null) { return null; } return permissions.get(permissionName); } @Nullable public Boolean getVendorPrivilegedAppAllowlistState(@NonNull String packageName, @NonNull String permissionName) { ArrayMap<String, Boolean> permissions = mVendorPrivilegedAppAllowlist.get(packageName); if (permissions == null) { return null; } return permissions.get(permissionName); } @Nullable public Boolean getProductPrivilegedAppAllowlistState(@NonNull String packageName, @NonNull String permissionName) { ArrayMap<String, Boolean> permissions = mProductPrivilegedAppAllowlist.get(packageName); if (permissions == null) { return null; } return permissions.get(permissionName); } @Nullable public Boolean getSystemExtPrivilegedAppAllowlistState(@NonNull String packageName, @NonNull String permissionName) { ArrayMap<String, Boolean> permissions = mSystemExtPrivilegedAppAllowlist.get(packageName); if (permissions == null) { return null; } return permissions.get(permissionName); } @Nullable public Boolean getApexPrivilegedAppAllowlistState(@NonNull String moduleName, @NonNull String packageName, @NonNull String permissionName) { ArrayMap<String, ArrayMap<String, Boolean>> allowlist = mApexPrivilegedAppAllowlists.get(moduleName); if (allowlist == null) { return null; } ArrayMap<String, Boolean> permissions = allowlist.get(packageName); if (permissions == null) { return null; } return permissions.get(permissionName); } } services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java +31 −52 File changed.Preview size limit exceeded, changes collapsed. Show changes services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java +5 −6 Original line number Diff line number Diff line Loading @@ -405,12 +405,11 @@ public class SystemConfigTest { mSysConfig.readApexPrivAppPermissions(parser, permissionFile, apexDir.toPath()); assertThat(mSysConfig.getApexPrivAppPermissions("com.android.my_module", "com.android.apk_in_apex")) .containsExactly("android.permission.FOO"); assertThat(mSysConfig.getApexPrivAppDenyPermissions("com.android.my_module", "com.android.apk_in_apex")) .containsExactly("android.permission.BAR"); ArrayMap<String, Boolean> permissions = mSysConfig.getPermissionAllowlist() .getApexPrivilegedAppAllowlists().get("com.android.my_module") .get("com.android.apk_in_apex"); assertThat(permissions) .containsExactly("android.permission.FOO", true, "android.permission.BAR", false); } /** Loading Loading
services/core/java/com/android/server/SystemConfig.java +38 −150 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import android.util.Xml; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.XmlUtils; import com.android.modules.utils.build.UnboundedSdkLevel; import com.android.server.pm.permission.PermissionAllowlist; import libcore.io.IoUtils; import libcore.util.EmptyArray; Loading Loading @@ -304,24 +305,7 @@ public class SystemConfig { final ArrayMap<String, List<CarrierAssociatedAppEntry>> mDisabledUntilUsedPreinstalledCarrierAssociatedApps = new ArrayMap<>(); final ArrayMap<String, ArraySet<String>> mPrivAppPermissions = new ArrayMap<>(); final ArrayMap<String, ArraySet<String>> mPrivAppDenyPermissions = new ArrayMap<>(); final ArrayMap<String, ArraySet<String>> mVendorPrivAppPermissions = new ArrayMap<>(); final ArrayMap<String, ArraySet<String>> mVendorPrivAppDenyPermissions = new ArrayMap<>(); final ArrayMap<String, ArraySet<String>> mProductPrivAppPermissions = new ArrayMap<>(); final ArrayMap<String, ArraySet<String>> mProductPrivAppDenyPermissions = new ArrayMap<>(); final ArrayMap<String, ArraySet<String>> mSystemExtPrivAppPermissions = new ArrayMap<>(); final ArrayMap<String, ArraySet<String>> mSystemExtPrivAppDenyPermissions = new ArrayMap<>(); final ArrayMap<String, ArrayMap<String, ArraySet<String>>> mApexPrivAppPermissions = new ArrayMap<>(); final ArrayMap<String, ArrayMap<String, ArraySet<String>>> mApexPrivAppDenyPermissions = new ArrayMap<>(); final ArrayMap<String, ArrayMap<String, Boolean>> mOemPermissions = new ArrayMap<>(); private final PermissionAllowlist mPermissionAllowlist = new PermissionAllowlist(); // Allowed associations between applications. If there are any entries // for an app, those are the only associations allowed; otherwise, all associations Loading Loading @@ -459,64 +443,8 @@ public class SystemConfig { return mDisabledUntilUsedPreinstalledCarrierAssociatedApps; } public ArraySet<String> getPrivAppPermissions(String packageName) { return mPrivAppPermissions.get(packageName); } public ArraySet<String> getPrivAppDenyPermissions(String packageName) { return mPrivAppDenyPermissions.get(packageName); } /** Get privapp permission allowlist for an apk-in-apex. */ public ArraySet<String> getApexPrivAppPermissions(String apexName, String apkPackageName) { return mApexPrivAppPermissions.getOrDefault(apexName, EMPTY_PERMISSIONS) .get(apkPackageName); } /** Get privapp permissions denylist for an apk-in-apex. */ public ArraySet<String> getApexPrivAppDenyPermissions(String apexName, String apkPackageName) { return mApexPrivAppDenyPermissions.getOrDefault(apexName, EMPTY_PERMISSIONS) .get(apkPackageName); } public ArraySet<String> getVendorPrivAppPermissions(String packageName) { return mVendorPrivAppPermissions.get(packageName); } public ArraySet<String> getVendorPrivAppDenyPermissions(String packageName) { return mVendorPrivAppDenyPermissions.get(packageName); } public ArraySet<String> getProductPrivAppPermissions(String packageName) { return mProductPrivAppPermissions.get(packageName); } public ArraySet<String> getProductPrivAppDenyPermissions(String packageName) { return mProductPrivAppDenyPermissions.get(packageName); } /** * Read from "permission" tags in /system_ext/etc/permissions/*.xml * @return Set of privileged permissions that are explicitly granted. */ public ArraySet<String> getSystemExtPrivAppPermissions(String packageName) { return mSystemExtPrivAppPermissions.get(packageName); } /** * Read from "deny-permission" tags in /system_ext/etc/permissions/*.xml * @return Set of privileged permissions that are explicitly denied. */ public ArraySet<String> getSystemExtPrivAppDenyPermissions(String packageName) { return mSystemExtPrivAppDenyPermissions.get(packageName); } public Map<String, Boolean> getOemPermissions(String packageName) { final Map<String, Boolean> oemPermissions = mOemPermissions.get(packageName); if (oemPermissions != null) { return oemPermissions; } return Collections.emptyMap(); public PermissionAllowlist getPermissionAllowlist() { return mPermissionAllowlist; } public ArrayMap<String, ArraySet<String>> getAllowedAssociations() { Loading Loading @@ -1253,20 +1181,20 @@ public class SystemConfig { Environment.getApexDirectory().toPath() + "/") && ApexProperties.updatable().orElse(false); if (vendor) { readPrivAppPermissions(parser, mVendorPrivAppPermissions, mVendorPrivAppDenyPermissions); readPrivAppPermissions(parser, mPermissionAllowlist.getVendorPrivilegedAppAllowlist()); } else if (product) { readPrivAppPermissions(parser, mProductPrivAppPermissions, mProductPrivAppDenyPermissions); readPrivAppPermissions(parser, mPermissionAllowlist.getProductPrivilegedAppAllowlist()); } else if (systemExt) { readPrivAppPermissions(parser, mSystemExtPrivAppPermissions, mSystemExtPrivAppDenyPermissions); readPrivAppPermissions(parser, mPermissionAllowlist.getSystemExtPrivilegedAppAllowlist()); } else if (apex) { readApexPrivAppPermissions(parser, permFile, Environment.getApexDirectory().toPath()); } else { readPrivAppPermissions(parser, mPrivAppPermissions, mPrivAppDenyPermissions); readPrivAppPermissions(parser, mPermissionAllowlist.getPrivilegedAppAllowlist()); } } else { logNotAllowedInPartition(name, permFile, parser); Loading Loading @@ -1589,50 +1517,10 @@ public class SystemConfig { } } private void readPrivAppPermissions(XmlPullParser parser, ArrayMap<String, ArraySet<String>> grantMap, ArrayMap<String, ArraySet<String>> denyMap) private void readPrivAppPermissions(@NonNull XmlPullParser parser, @NonNull ArrayMap<String, ArrayMap<String, Boolean>> allowlist) throws IOException, XmlPullParserException { String packageName = parser.getAttributeValue(null, "package"); if (TextUtils.isEmpty(packageName)) { Slog.w(TAG, "package is required for <privapp-permissions> in " + parser.getPositionDescription()); return; } ArraySet<String> permissions = grantMap.get(packageName); if (permissions == null) { permissions = new ArraySet<>(); } ArraySet<String> denyPermissions = denyMap.get(packageName); int depth = parser.getDepth(); while (XmlUtils.nextElementWithin(parser, depth)) { String name = parser.getName(); if ("permission".equals(name)) { String permName = parser.getAttributeValue(null, "name"); if (TextUtils.isEmpty(permName)) { Slog.w(TAG, "name is required for <permission> in " + parser.getPositionDescription()); continue; } permissions.add(permName); } else if ("deny-permission".equals(name)) { String permName = parser.getAttributeValue(null, "name"); if (TextUtils.isEmpty(permName)) { Slog.w(TAG, "name is required for <deny-permission> in " + parser.getPositionDescription()); continue; } if (denyPermissions == null) { denyPermissions = new ArraySet<>(); } denyPermissions.add(permName); } } grantMap.put(packageName, permissions); if (denyPermissions != null) { denyMap.put(packageName, denyPermissions); } readPermissionAllowlist(parser, allowlist, "privapp-permissions"); } private void readInstallInUserType(XmlPullParser parser, Loading Loading @@ -1683,14 +1571,21 @@ public class SystemConfig { } void readOemPermissions(XmlPullParser parser) throws IOException, XmlPullParserException { readPermissionAllowlist(parser, mPermissionAllowlist.getOemAppAllowlist(), "oem-permissions"); } private static void readPermissionAllowlist(@NonNull XmlPullParser parser, @NonNull ArrayMap<String, ArrayMap<String, Boolean>> allowlist, @NonNull String tagName) throws IOException, XmlPullParserException { final String packageName = parser.getAttributeValue(null, "package"); if (TextUtils.isEmpty(packageName)) { Slog.w(TAG, "package is required for <oem-permissions> in " Slog.w(TAG, "package is required for <" + tagName + "> in " + parser.getPositionDescription()); return; } ArrayMap<String, Boolean> permissions = mOemPermissions.get(packageName); ArrayMap<String, Boolean> permissions = allowlist.get(packageName); if (permissions == null) { permissions = new ArrayMap<>(); } Loading @@ -1698,24 +1593,24 @@ public class SystemConfig { while (XmlUtils.nextElementWithin(parser, depth)) { final String name = parser.getName(); if ("permission".equals(name)) { final String permName = parser.getAttributeValue(null, "name"); if (TextUtils.isEmpty(permName)) { final String permissionName = parser.getAttributeValue(null, "name"); if (TextUtils.isEmpty(permissionName)) { Slog.w(TAG, "name is required for <permission> in " + parser.getPositionDescription()); continue; } permissions.put(permName, Boolean.TRUE); permissions.put(permissionName, Boolean.TRUE); } else if ("deny-permission".equals(name)) { String permName = parser.getAttributeValue(null, "name"); if (TextUtils.isEmpty(permName)) { String permissionName = parser.getAttributeValue(null, "name"); if (TextUtils.isEmpty(permissionName)) { Slog.w(TAG, "name is required for <deny-permission> in " + parser.getPositionDescription()); continue; } permissions.put(permName, Boolean.FALSE); permissions.put(permissionName, Boolean.FALSE); } } mOemPermissions.put(packageName, permissions); allowlist.put(packageName, permissions); } private void readSplitPermission(XmlPullParser parser, File permFile) Loading Loading @@ -1865,21 +1760,14 @@ public class SystemConfig { Path apexDirectoryPath) throws IOException, XmlPullParserException { final String moduleName = getApexModuleNameFromFilePath(permFile.toPath(), apexDirectoryPath); final ArrayMap<String, ArraySet<String>> privAppPermissions; if (mApexPrivAppPermissions.containsKey(moduleName)) { privAppPermissions = mApexPrivAppPermissions.get(moduleName); } else { privAppPermissions = new ArrayMap<>(); mApexPrivAppPermissions.put(moduleName, privAppPermissions); } final ArrayMap<String, ArraySet<String>> privAppDenyPermissions; if (mApexPrivAppDenyPermissions.containsKey(moduleName)) { privAppDenyPermissions = mApexPrivAppDenyPermissions.get(moduleName); } else { privAppDenyPermissions = new ArrayMap<>(); mApexPrivAppDenyPermissions.put(moduleName, privAppDenyPermissions); } readPrivAppPermissions(parser, privAppPermissions, privAppDenyPermissions); final ArrayMap<String, ArrayMap<String, ArrayMap<String, Boolean>>> allowlists = mPermissionAllowlist.getApexPrivilegedAppAllowlists(); ArrayMap<String, ArrayMap<String, Boolean>> allowlist = allowlists.get(moduleName); if (allowlist == null) { allowlist = new ArrayMap<>(); allowlists.put(moduleName, allowlist); } readPrivAppPermissions(parser, allowlist); } private static boolean isSystemProcess() { Loading
services/core/java/com/android/server/pm/PackageManagerShellCommand.java +46 −40 Original line number Diff line number Diff line Loading @@ -99,7 +99,6 @@ import android.system.Os; import android.text.TextUtils; import android.text.format.DateUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.IntArray; import android.util.PrintWriterPrinter; import android.util.Slog; Loading @@ -116,6 +115,7 @@ import com.android.server.SystemConfig; import com.android.server.art.ArtManagerLocal; import com.android.server.pm.PackageManagerShellCommandDataLoader.Metadata; import com.android.server.pm.permission.LegacyPermissionManagerInternal; import com.android.server.pm.permission.PermissionAllowlist; import com.android.server.pm.verify.domain.DomainVerificationShell; import dalvik.system.DexFile; Loading Loading @@ -2684,26 +2684,7 @@ class PackageManagerShellCommand extends ShellCommand { getErrPrintWriter().println("Error: no package specified."); return 1; } ArraySet<String> privAppPermissions = null; if (isVendorApp(pkg)) { privAppPermissions = SystemConfig.getInstance().getVendorPrivAppPermissions(pkg); } else if (isProductApp(pkg)) { privAppPermissions = SystemConfig.getInstance().getProductPrivAppPermissions(pkg); } else if (isSystemExtApp(pkg)) { privAppPermissions = SystemConfig.getInstance() .getSystemExtPrivAppPermissions(pkg); } else if (isApexApp(pkg)) { final String apexName = ApexManager.getInstance().getApexModuleNameForPackageName( getApexPackageNameContainingPackage(pkg)); privAppPermissions = SystemConfig.getInstance() .getApexPrivAppPermissions(apexName, pkg); } else { privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg); } getOutPrintWriter().println(privAppPermissions == null ? "{}" : privAppPermissions.toString()); getOutPrintWriter().println(getPrivAppPermissionsString(pkg, true)); return 0; } Loading @@ -2713,27 +2694,52 @@ class PackageManagerShellCommand extends ShellCommand { getErrPrintWriter().println("Error: no package specified."); return 1; } getOutPrintWriter().println(getPrivAppPermissionsString(pkg, false)); return 0; } ArraySet<String> privAppPermissions = null; if (isVendorApp(pkg)) { privAppPermissions = SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg); } else if (isProductApp(pkg)) { privAppPermissions = SystemConfig.getInstance().getProductPrivAppDenyPermissions(pkg); } else if (isSystemExtApp(pkg)) { privAppPermissions = SystemConfig.getInstance() .getSystemExtPrivAppDenyPermissions(pkg); } else if (isApexApp(pkg)) { final String apexName = ApexManager.getInstance().getApexModuleNameForPackageName( getApexPackageNameContainingPackage(pkg)); privAppPermissions = SystemConfig.getInstance() .getApexPrivAppDenyPermissions(apexName, pkg); @NonNull private String getPrivAppPermissionsString(@NonNull String packageName, boolean allowed) { final PermissionAllowlist permissionAllowlist = SystemConfig.getInstance().getPermissionAllowlist(); final ArrayMap<String, ArrayMap<String, Boolean>> privAppPermissions; if (isVendorApp(packageName)) { privAppPermissions = permissionAllowlist.getVendorPrivilegedAppAllowlist(); } else if (isProductApp(packageName)) { privAppPermissions = permissionAllowlist.getProductPrivilegedAppAllowlist(); } else if (isSystemExtApp(packageName)) { privAppPermissions = permissionAllowlist.getSystemExtPrivilegedAppAllowlist(); } else if (isApexApp(packageName)) { final String moduleName = ApexManager.getInstance().getApexModuleNameForPackageName( getApexPackageNameContainingPackage(packageName)); privAppPermissions = permissionAllowlist.getApexPrivilegedAppAllowlists() .get(moduleName); } else { privAppPermissions = SystemConfig.getInstance().getPrivAppDenyPermissions(pkg); privAppPermissions = permissionAllowlist.getPrivilegedAppAllowlist(); } final ArrayMap<String, Boolean> permissions = privAppPermissions != null ? privAppPermissions.get(packageName) : null; if (permissions == null) { return "{}"; } final StringBuilder result = new StringBuilder("{"); boolean isFirstPermission = true; final int permissionsSize = permissions.size(); for (int i = 0; i < permissionsSize; i++) { boolean permissionAllowed = permissions.valueAt(i); if (permissionAllowed != allowed) { continue; } getOutPrintWriter().println(privAppPermissions == null ? "{}" : privAppPermissions.toString()); return 0; if (isFirstPermission) { isFirstPermission = false; } else { result.append(", "); } String permissionName = permissions.keyAt(i); result.append(permissionName); } result.append("}"); return result.toString(); } private int runGetOemPermissions() { Loading @@ -2743,7 +2749,7 @@ class PackageManagerShellCommand extends ShellCommand { return 1; } final Map<String, Boolean> oemPermissions = SystemConfig.getInstance() .getOemPermissions(pkg); .getPermissionAllowlist().getOemAppAllowlist().get(pkg); if (oemPermissions == null || oemPermissions.isEmpty()) { getOutPrintWriter().println("{}"); } else { Loading
services/core/java/com/android/server/pm/permission/PermissionAllowlist.java 0 → 100644 +140 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.pm.permission; import android.annotation.NonNull; import android.annotation.Nullable; import android.util.ArrayMap; /** * Data class for OEM and privileged app permission allowlist state. */ public final class PermissionAllowlist { @NonNull private final ArrayMap<String, ArrayMap<String, Boolean>> mOemAppAllowlist = new ArrayMap<>(); @NonNull private final ArrayMap<String, ArrayMap<String, Boolean>> mPrivilegedAppAllowlist = new ArrayMap<>(); @NonNull private final ArrayMap<String, ArrayMap<String, Boolean>> mVendorPrivilegedAppAllowlist = new ArrayMap<>(); @NonNull private final ArrayMap<String, ArrayMap<String, Boolean>> mProductPrivilegedAppAllowlist = new ArrayMap<>(); @NonNull private final ArrayMap<String, ArrayMap<String, Boolean>> mSystemExtPrivilegedAppAllowlist = new ArrayMap<>(); @NonNull private final ArrayMap<String, ArrayMap<String, ArrayMap<String, Boolean>>> mApexPrivilegedAppAllowlists = new ArrayMap<>(); @NonNull public ArrayMap<String, ArrayMap<String, Boolean>> getOemAppAllowlist() { return mOemAppAllowlist; } @NonNull public ArrayMap<String, ArrayMap<String, Boolean>> getPrivilegedAppAllowlist() { return mPrivilegedAppAllowlist; } @NonNull public ArrayMap<String, ArrayMap<String, Boolean>> getVendorPrivilegedAppAllowlist() { return mVendorPrivilegedAppAllowlist; } @NonNull public ArrayMap<String, ArrayMap<String, Boolean>> getProductPrivilegedAppAllowlist() { return mProductPrivilegedAppAllowlist; } @NonNull public ArrayMap<String, ArrayMap<String, Boolean>> getSystemExtPrivilegedAppAllowlist() { return mSystemExtPrivilegedAppAllowlist; } @NonNull public ArrayMap<String, ArrayMap<String, ArrayMap<String, Boolean>>> getApexPrivilegedAppAllowlists() { return mApexPrivilegedAppAllowlists; } @Nullable public Boolean getOemAppAllowlistState(@NonNull String packageName, @NonNull String permissionName) { ArrayMap<String, Boolean> permissions = mOemAppAllowlist.get(packageName); if (permissions == null) { return null; } return permissions.get(permissionName); } @Nullable public Boolean getPrivilegedAppAllowlistState(@NonNull String packageName, @NonNull String permissionName) { ArrayMap<String, Boolean> permissions = mPrivilegedAppAllowlist.get(packageName); if (permissions == null) { return null; } return permissions.get(permissionName); } @Nullable public Boolean getVendorPrivilegedAppAllowlistState(@NonNull String packageName, @NonNull String permissionName) { ArrayMap<String, Boolean> permissions = mVendorPrivilegedAppAllowlist.get(packageName); if (permissions == null) { return null; } return permissions.get(permissionName); } @Nullable public Boolean getProductPrivilegedAppAllowlistState(@NonNull String packageName, @NonNull String permissionName) { ArrayMap<String, Boolean> permissions = mProductPrivilegedAppAllowlist.get(packageName); if (permissions == null) { return null; } return permissions.get(permissionName); } @Nullable public Boolean getSystemExtPrivilegedAppAllowlistState(@NonNull String packageName, @NonNull String permissionName) { ArrayMap<String, Boolean> permissions = mSystemExtPrivilegedAppAllowlist.get(packageName); if (permissions == null) { return null; } return permissions.get(permissionName); } @Nullable public Boolean getApexPrivilegedAppAllowlistState(@NonNull String moduleName, @NonNull String packageName, @NonNull String permissionName) { ArrayMap<String, ArrayMap<String, Boolean>> allowlist = mApexPrivilegedAppAllowlists.get(moduleName); if (allowlist == null) { return null; } ArrayMap<String, Boolean> permissions = allowlist.get(packageName); if (permissions == null) { return null; } return permissions.get(permissionName); } }
services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java +31 −52 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java +5 −6 Original line number Diff line number Diff line Loading @@ -405,12 +405,11 @@ public class SystemConfigTest { mSysConfig.readApexPrivAppPermissions(parser, permissionFile, apexDir.toPath()); assertThat(mSysConfig.getApexPrivAppPermissions("com.android.my_module", "com.android.apk_in_apex")) .containsExactly("android.permission.FOO"); assertThat(mSysConfig.getApexPrivAppDenyPermissions("com.android.my_module", "com.android.apk_in_apex")) .containsExactly("android.permission.BAR"); ArrayMap<String, Boolean> permissions = mSysConfig.getPermissionAllowlist() .getApexPrivilegedAppAllowlists().get("com.android.my_module") .get("com.android.apk_in_apex"); assertThat(permissions) .containsExactly("android.permission.FOO", true, "android.permission.BAR", false); } /** Loading