Add a Method to Revoke DefaultGrant Permissions
Runtime permissions grants for system-bound
services should be revoked when no longer needed.
This ensures that in cases where say, a package
is needed while a user is using a certain cellular
provider, that package will lose its privileges
if the user changes providers.
Bug: 66955045
Test: compilation (still WIP)
Change-Id: I8dc2dd719f3b4af83ebb2b2f4a128f267b26fd91
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 83fe1c9..6f1a83e 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -1082,6 +1082,51 @@
grantRuntimePermissions(pkg, permissions, systemFixed, false, userId);
}
+ private void revokeRuntimePermissions(PackageParser.Package pkg, Set<String> permissions,
+ boolean systemFixed, int userId) {
+ if (pkg.requestedPermissions.isEmpty()) {
+ return;
+ }
+ Set<String> revokablePermissions = new ArraySet<>(pkg.requestedPermissions);
+
+ for (String permission : permissions) {
+ // We can't revoke what wasn't requested.
+ if (!revokablePermissions.contains(permission)) {
+ continue;
+ }
+
+ final int flags = mServiceInternal.getPermissionFlagsTEMP(
+ permission, pkg.packageName, userId);
+
+ // We didn't get this through the default grant policy. Move along.
+ if ((flags & PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT) == 0) {
+ continue;
+ }
+ // We aren't going to clobber device policy with a DefaultGrant.
+ if ((flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
+ continue;
+ }
+ // Do not revoke system fixed permissions unless caller set them that way;
+ // there is no refcount for the number of sources of this, so there
+ // should be at most one grantor doing SYSTEM_FIXED for any given package.
+ if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0 && !systemFixed) {
+ continue;
+ }
+ mServiceInternal.revokeRuntimePermission(pkg.packageName, permission, userId, false);
+
+ if (DEBUG) {
+ Log.i(TAG, "revoked " + (systemFixed ? "fixed " : "not fixed ")
+ + permission + " to " + pkg.packageName);
+ }
+
+ // Remove the GRANTED_BY_DEFAULT flag without touching the others.
+ // Note that we do not revoke FLAG_PERMISSION_SYSTEM_FIXED. That bit remains
+ // sticky once set.
+ mServiceInternal.updatePermissionFlagsTEMP(permission, pkg.packageName,
+ PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, 0, userId);
+ }
+ }
+
private void grantRuntimePermissions(PackageParser.Package pkg, Set<String> permissions,
boolean systemFixed, boolean ignoreSystemPackage, int userId) {
if (pkg.requestedPermissions.isEmpty()) {
@@ -1132,10 +1177,10 @@
// to make sure we can grant the needed permission to the default
// sms and phone apps after the user chooses this in the UI.
if (flags == 0 || ignoreSystemPackage) {
- // Never clobber policy or system.
- final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
- | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
- if ((flags & fixedFlags) != 0) {
+ // Never clobber policy fixed permissions.
+ // We must allow the grant of a system-fixed permission because
+ // system-fixed is sticky, but the permission itself may be revoked.
+ if ((flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
continue;
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index afa9dd0..bd30c5b 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1457,8 +1457,10 @@
final PermissionsState permissionsState = ps.getPermissionsState();
final int flags = permissionsState.getPermissionFlags(permName, userId);
- if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
- throw new SecurityException("Cannot revoke system fixed permission "
+ // Only the system may revoke SYSTEM_FIXED permissions.
+ if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
+ && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
+ throw new SecurityException("Non-System UID cannot revoke system fixed permission "
+ permName + " for package " + packageName);
}
if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {