summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nate Myren <ntmyren@google.com> 2020-06-23 16:31:39 -0700
committer Nate Myren <ntmyren@google.com> 2020-06-23 16:43:27 -0700
commitc92df18fbf749984e48585260dd4f623ff7f1163 (patch)
treed21302e7e05d2f53054bc9cf050290932c54a8c5
parent2775990021e6dd22197b7b718ce1e37b14c8a690 (diff)
Update permissions flags for all users before restoring
Ensure that permission flags are updated for all users in setWhitelistedRestrictedPermissions before restoring permission state. see ag/9286799 and ag/9278208 Fixes: 144690691 Test: atest SplitPermissionTest#inheritGrantedPermissionState --iterations 10 (run on both user 0 and secondary user) or running on secondary user: $ adb install out/.../CtsAppThatRequestsLocationPermission29.apk $ adb shell pm grant --user [SECONDARY_USER_ID] android.permission.cts.appthatrequestpermission android.permission.ACCESS_COARSE_LOCATION $ adb install out/.../CtsAppThatRequestsLocationPermission28.apk $ adb shell dumpsys package android.permission.cts.appthatrequestpermission Verify that ACCESS_BACKGROUND_LOCATION is granted to secondary user Change-Id: I7ca593a807f1fad68504e59e743b736f5f2c915a
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java203
1 files changed, 109 insertions, 94 deletions
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 1b11e2d0860d..8879ccb97de3 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -29,6 +29,9 @@ import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAU
import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE;
import static android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME;
import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
@@ -754,9 +757,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
- flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
- flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
- flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
+ flagValues &= ~FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
+ flagValues &= ~FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
+ flagValues &= ~FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
}
@@ -1112,13 +1115,13 @@ public class PermissionManagerService extends IPermissionManager.Stub {
int queryFlags = 0;
if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0) {
- queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
+ queryFlags |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
}
if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
- queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
+ queryFlags |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
}
if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
- queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
+ queryFlags |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
}
ArrayList<String> whitelistedPermissions = null;
@@ -1280,8 +1283,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
final long identity = Binder.clearCallingIdentity();
try {
- setWhitelistedRestrictedPermissionsForUser(
- pkg, userId, permissions, Process.myUid(), flags, mDefaultPermissionCallback);
+ setWhitelistedRestrictedPermissionsForUsers(pkg, new int[]{ userId }, permissions,
+ Process.myUid(), flags, mDefaultPermissionCallback);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -2517,8 +2520,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
if (permission.isHardOrSoftRestricted()
|| permission.isImmutablyRestricted()) {
permissionsState.updatePermissionFlags(permission, userId,
- PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT,
- PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT);
+ FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT,
+ FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT);
}
if (targetSdkVersion < Build.VERSION_CODES.M) {
permissionsState.updatePermissionFlags(permission, userId,
@@ -3756,8 +3759,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
}
- private void setWhitelistedRestrictedPermissionsForUser(@NonNull AndroidPackage pkg,
- @UserIdInt int userId, @Nullable List<String> permissions, int callingUid,
+ private void setWhitelistedRestrictedPermissionsForUsers(@NonNull AndroidPackage pkg,
+ @UserIdInt int[] userIds, @Nullable List<String> permissions, int callingUid,
@PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) {
final PermissionsState permissionsState =
PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
@@ -3765,95 +3768,102 @@ public class PermissionManagerService extends IPermissionManager.Stub {
return;
}
- ArraySet<String> oldGrantedRestrictedPermissions = null;
+ SparseArray<ArraySet<String>> oldGrantedRestrictedPermissions = new SparseArray<>();
boolean updatePermissions = false;
-
final int permissionCount = pkg.getRequestedPermissions().size();
- for (int i = 0; i < permissionCount; i++) {
- final String permissionName = pkg.getRequestedPermissions().get(i);
- final BasePermission bp = mSettings.getPermissionLocked(permissionName);
+ for (int i = 0; i < userIds.length; i++) {
+ int userId = userIds[i];
+ for (int j = 0; j < permissionCount; j++) {
+ final String permissionName = pkg.getRequestedPermissions().get(j);
- if (bp == null || !bp.isHardOrSoftRestricted()) {
- continue;
- }
+ final BasePermission bp = mSettings.getPermissionLocked(permissionName);
- if (permissionsState.hasPermission(permissionName, userId)) {
- if (oldGrantedRestrictedPermissions == null) {
- oldGrantedRestrictedPermissions = new ArraySet<>();
+ if (bp == null || !bp.isHardOrSoftRestricted()) {
+ continue;
}
- oldGrantedRestrictedPermissions.add(permissionName);
- }
-
- final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
-
- int newFlags = oldFlags;
- int mask = 0;
- int whitelistFlagsCopy = whitelistFlags;
- while (whitelistFlagsCopy != 0) {
- final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy);
- whitelistFlagsCopy &= ~flag;
- switch (flag) {
- case FLAG_PERMISSION_WHITELIST_SYSTEM: {
- mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
- if (permissions != null && permissions.contains(permissionName)) {
- newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
- } else {
- newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
+
+ if (permissionsState.hasPermission(permissionName, userId)) {
+ if (oldGrantedRestrictedPermissions.get(userId) == null) {
+ oldGrantedRestrictedPermissions.put(userId, new ArraySet<>());
+ }
+ oldGrantedRestrictedPermissions.get(userId).add(permissionName);
+ }
+
+ final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
+
+ int newFlags = oldFlags;
+ int mask = 0;
+ int whitelistFlagsCopy = whitelistFlags;
+ while (whitelistFlagsCopy != 0) {
+ final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy);
+ whitelistFlagsCopy &= ~flag;
+ switch (flag) {
+ case FLAG_PERMISSION_WHITELIST_SYSTEM: {
+ mask |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
+ if (permissions != null && permissions.contains(permissionName)) {
+ newFlags |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
+ } else {
+ newFlags &= ~FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
+ }
}
- } break;
- case FLAG_PERMISSION_WHITELIST_UPGRADE: {
- mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
- if (permissions != null && permissions.contains(permissionName)) {
- newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
- } else {
- newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
+ break;
+ case FLAG_PERMISSION_WHITELIST_UPGRADE: {
+ mask |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
+ if (permissions != null && permissions.contains(permissionName)) {
+ newFlags |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
+ } else {
+ newFlags &= ~FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
+ }
}
- } break;
- case FLAG_PERMISSION_WHITELIST_INSTALLER: {
- mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
- if (permissions != null && permissions.contains(permissionName)) {
- newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
- } else {
- newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
+ break;
+ case FLAG_PERMISSION_WHITELIST_INSTALLER: {
+ mask |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
+ if (permissions != null && permissions.contains(permissionName)) {
+ newFlags |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
+ } else {
+ newFlags &= ~FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
+ }
}
- } break;
+ break;
+ }
}
- }
-
- if (oldFlags == newFlags) {
- continue;
- }
- updatePermissions = true;
+ if (oldFlags == newFlags) {
+ continue;
+ }
- final boolean wasWhitelisted = (oldFlags
- & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
- final boolean isWhitelisted = (newFlags
- & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
+ updatePermissions = true;
+
+ final boolean wasWhitelisted = (oldFlags
+ & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
+ final boolean isWhitelisted = (newFlags
+ & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
+
+ // If the permission is policy fixed as granted but it is no longer
+ // on any of the whitelists we need to clear the policy fixed flag
+ // as whitelisting trumps policy i.e. policy cannot grant a non
+ // grantable permission.
+ if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
+ final boolean isGranted = permissionsState.hasPermission(permissionName,
+ userId);
+ if (!isWhitelisted && isGranted) {
+ mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
+ newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
+ }
+ }
- // If the permission is policy fixed as granted but it is no longer
- // on any of the whitelists we need to clear the policy fixed flag
- // as whitelisting trumps policy i.e. policy cannot grant a non
- // grantable permission.
- if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
- final boolean isGranted = permissionsState.hasPermission(permissionName, userId);
- if (!isWhitelisted && isGranted) {
- mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
- newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
+ // If we are whitelisting an app that does not support runtime permissions
+ // we need to make sure it goes through the permission review UI at launch.
+ if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
+ && !wasWhitelisted && isWhitelisted) {
+ mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
+ newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
}
- }
- // If we are whitelisting an app that does not support runtime permissions
- // we need to make sure it goes through the permission review UI at launch.
- if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
- && !wasWhitelisted && isWhitelisted) {
- mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
- newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
+ updatePermissionFlagsInternal(permissionName, pkg.getPackageName(), mask, newFlags,
+ callingUid, userId, false, null /*callback*/);
}
-
- updatePermissionFlagsInternal(permissionName, pkg.getPackageName(), mask, newFlags,
- callingUid, userId, false, null /*callback*/);
}
if (updatePermissions) {
@@ -3861,13 +3871,20 @@ public class PermissionManagerService extends IPermissionManager.Stub {
restorePermissionState(pkg, false, pkg.getPackageName(), callback);
// If this resulted in losing a permission we need to kill the app.
- if (oldGrantedRestrictedPermissions != null) {
- final int oldGrantedCount = oldGrantedRestrictedPermissions.size();
- for (int i = 0; i < oldGrantedCount; i++) {
- final String permission = oldGrantedRestrictedPermissions.valueAt(i);
+ for (int i = 0; i < userIds.length; i++) {
+ int userId = userIds[i];
+ ArraySet<String> oldPermsForUser = oldGrantedRestrictedPermissions.get(userId);
+ if (oldPermsForUser == null) {
+ continue;
+ }
+
+ final int oldGrantedCount = oldPermsForUser.size();
+ for (int j = 0; j < oldGrantedCount; j++) {
+ final String permission = oldPermsForUser.valueAt(j);
// Sometimes we create a new permission state instance during update.
final PermissionsState newPermissionsState =
- PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
+ PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt,
+ pkg);
if (!newPermissionsState.hasPermission(permission, userId)) {
callback.onPermissionRevoked(pkg.getUid(), userId);
break;
@@ -4624,10 +4641,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
public void setWhitelistedRestrictedPermissions(@NonNull AndroidPackage pkg,
@NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
@PackageManager.PermissionWhitelistFlags int flags) {
- for (int userId : userIds) {
- setWhitelistedRestrictedPermissionsForUser(pkg, userId, permissions,
- callingUid, flags, mDefaultPermissionCallback);
- }
+ setWhitelistedRestrictedPermissionsForUsers(pkg, userIds, permissions,
+ callingUid, flags, mDefaultPermissionCallback);
}
@Override
public void setWhitelistedRestrictedPermissions(String packageName,