From 74629e3183b275b87e54387ff620cfa377d314b6 Mon Sep 17 00:00:00 2001 From: Todd Kennedy Date: Tue, 15 Aug 2017 14:48:07 -0700 Subject: Allow explicit permission denial Change-Id: I5d348ed555f249d210253dab60ae11d4831c4f0a Fixes: 63675512 Test: Manual --- core/java/com/android/server/SystemConfig.java | 20 ++++++++++++++++++++ .../com/android/server/pm/PackageManagerService.java | 20 +++++++++++++++----- .../server/pm/PackageManagerShellCommand.java | 15 +++++++++++++++ 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java index 81018fe4b357..77788921635f 100644 --- a/core/java/com/android/server/SystemConfig.java +++ b/core/java/com/android/server/SystemConfig.java @@ -141,6 +141,7 @@ public class SystemConfig { final ArrayMap> mPrivAppPermissions = new ArrayMap<>(); + final ArrayMap> mPrivAppDenyPermissions = new ArrayMap<>(); public static SystemConfig getInstance() { synchronized (SystemConfig.class) { @@ -219,6 +220,10 @@ public class SystemConfig { return mPrivAppPermissions.get(packageName); } + public ArraySet getPrivAppDenyPermissions(String packageName) { + return mPrivAppDenyPermissions.get(packageName); + } + SystemConfig() { // Read configuration from system readPermissions(Environment.buildPath( @@ -660,6 +665,7 @@ public class SystemConfig { if (permissions == null) { permissions = new ArraySet<>(); } + ArraySet denyPermissions = mPrivAppDenyPermissions.get(packageName); int depth = parser.getDepth(); while (XmlUtils.nextElementWithin(parser, depth)) { String name = parser.getName(); @@ -671,8 +677,22 @@ public class SystemConfig { 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 in " + + parser.getPositionDescription()); + continue; + } + if (denyPermissions == null) { + denyPermissions = new ArraySet<>(); + } + denyPermissions.add(permName); } } mPrivAppPermissions.put(packageName, permissions); + if (denyPermissions != null) { + mPrivAppDenyPermissions.put(packageName, denyPermissions); + } } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 99261add1408..72e72d62d1a2 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -13126,18 +13126,28 @@ public class PackageManagerService extends IPackageManager.Stub boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName); if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp() && !platformPackage && platformPermission) { - ArraySet wlPermissions = SystemConfig.getInstance() + final ArraySet allowedPermissions = SystemConfig.getInstance() .getPrivAppPermissions(pkg.packageName); - boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm); + final boolean whitelisted = + allowedPermissions != null && allowedPermissions.contains(perm); if (!whitelisted) { Slog.w(TAG, "Privileged permission " + perm + " for package " + pkg.packageName + " - not in privapp-permissions whitelist"); // Only report violations for apps on system image if (!mSystemReady && !pkg.isUpdatedSystemApp()) { - if (mPrivappPermissionsViolations == null) { - mPrivappPermissionsViolations = new ArraySet<>(); + // it's only a reportable violation if the permission isn't explicitly denied + final ArraySet deniedPermissions = SystemConfig.getInstance() + .getPrivAppDenyPermissions(pkg.packageName); + final boolean permissionViolation = + deniedPermissions == null || !deniedPermissions.contains(perm); + if (permissionViolation) { + if (mPrivappPermissionsViolations == null) { + mPrivappPermissionsViolations = new ArraySet<>(); + } + mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm); + } else { + return false; } - mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm); } if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) { return false; diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 46e21dbc98bd..909ffabfd2db 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -148,6 +148,8 @@ class PackageManagerShellCommand extends ShellCommand { return runSetHomeActivity(); case "get-privapp-permissions": return runGetPrivappPermissions(); + case "get-privapp-deny-permissions": + return runGetPrivappDenyPermissions(); case "get-instantapp-resolver": return runGetInstantAppResolver(); case "has-feature": @@ -1293,6 +1295,19 @@ class PackageManagerShellCommand extends ShellCommand { return 0; } + private int runGetPrivappDenyPermissions() { + final String pkg = getNextArg(); + if (pkg == null) { + System.err.println("Error: no package specified."); + return 1; + } + ArraySet privAppDenyPermissions = + SystemConfig.getInstance().getPrivAppDenyPermissions(pkg); + getOutPrintWriter().println(privAppDenyPermissions == null + ? "{}" : privAppDenyPermissions.toString()); + return 0; + } + private int runGetInstantAppResolver() { final PrintWriter pw = getOutPrintWriter(); try { -- cgit v1.2.3-59-g8ed1b