Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c92df18f authored by Nate Myren's avatar Nate Myren
Browse files

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
parent 27759900
Loading
Loading
Loading
Loading
+109 −94
Original line number Original line Diff line number Diff line
@@ -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_GRANTED_BY_ROLE;
import static android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME;
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_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_REVIEW_REQUIRED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
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;
            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
            flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
            flagValues &= ~FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
            flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
            flagValues &= ~FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
            flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
            flagValues &= ~FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
            flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
            flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
        }
        }


@@ -1112,13 +1115,13 @@ public class PermissionManagerService extends IPermissionManager.Stub {


            int queryFlags = 0;
            int queryFlags = 0;
            if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 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) {
            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) {
            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;
            ArrayList<String> whitelistedPermissions = null;
@@ -1280,8 +1283,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {


        final long identity = Binder.clearCallingIdentity();
        final long identity = Binder.clearCallingIdentity();
        try {
        try {
            setWhitelistedRestrictedPermissionsForUser(
            setWhitelistedRestrictedPermissionsForUsers(pkg, new int[]{ userId }, permissions,
                    pkg, userId, permissions, Process.myUid(), flags, mDefaultPermissionCallback);
                    Process.myUid(), flags, mDefaultPermissionCallback);
        } finally {
        } finally {
            Binder.restoreCallingIdentity(identity);
            Binder.restoreCallingIdentity(identity);
        }
        }
@@ -2517,8 +2520,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                        if (permission.isHardOrSoftRestricted()
                        if (permission.isHardOrSoftRestricted()
                                || permission.isImmutablyRestricted()) {
                                || permission.isImmutablyRestricted()) {
                            permissionsState.updatePermissionFlags(permission, userId,
                            permissionsState.updatePermissionFlags(permission, userId,
                                    PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT,
                                    FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT,
                                    PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT);
                                    FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT);
                        }
                        }
                        if (targetSdkVersion < Build.VERSION_CODES.M) {
                        if (targetSdkVersion < Build.VERSION_CODES.M) {
                            permissionsState.updatePermissionFlags(permission, userId,
                            permissionsState.updatePermissionFlags(permission, userId,
@@ -3756,8 +3759,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
        }
        }
    }
    }


    private void setWhitelistedRestrictedPermissionsForUser(@NonNull AndroidPackage pkg,
    private void setWhitelistedRestrictedPermissionsForUsers(@NonNull AndroidPackage pkg,
            @UserIdInt int userId, @Nullable List<String> permissions, int callingUid,
            @UserIdInt int[] userIds, @Nullable List<String> permissions, int callingUid,
            @PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) {
            @PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) {
        final PermissionsState permissionsState =
        final PermissionsState permissionsState =
                PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
                PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
@@ -3765,12 +3768,14 @@ public class PermissionManagerService extends IPermissionManager.Stub {
            return;
            return;
        }
        }


        ArraySet<String> oldGrantedRestrictedPermissions = null;
        SparseArray<ArraySet<String>> oldGrantedRestrictedPermissions = new SparseArray<>();
        boolean updatePermissions = false;
        boolean updatePermissions = false;

        final int permissionCount = pkg.getRequestedPermissions().size();
        final int permissionCount = pkg.getRequestedPermissions().size();
        for (int i = 0; i < permissionCount; i++) {

            final String permissionName = pkg.getRequestedPermissions().get(i);
        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);


                final BasePermission bp = mSettings.getPermissionLocked(permissionName);
                final BasePermission bp = mSettings.getPermissionLocked(permissionName);


@@ -3779,10 +3784,10 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                }
                }


                if (permissionsState.hasPermission(permissionName, userId)) {
                if (permissionsState.hasPermission(permissionName, userId)) {
                if (oldGrantedRestrictedPermissions == null) {
                    if (oldGrantedRestrictedPermissions.get(userId) == null) {
                    oldGrantedRestrictedPermissions = new ArraySet<>();
                        oldGrantedRestrictedPermissions.put(userId, new ArraySet<>());
                    }
                    }
                oldGrantedRestrictedPermissions.add(permissionName);
                    oldGrantedRestrictedPermissions.get(userId).add(permissionName);
                }
                }


                final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
                final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
@@ -3795,29 +3800,32 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                    whitelistFlagsCopy &= ~flag;
                    whitelistFlagsCopy &= ~flag;
                    switch (flag) {
                    switch (flag) {
                        case FLAG_PERMISSION_WHITELIST_SYSTEM: {
                        case FLAG_PERMISSION_WHITELIST_SYSTEM: {
                        mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
                            mask |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
                            if (permissions != null && permissions.contains(permissionName)) {
                            if (permissions != null && permissions.contains(permissionName)) {
                            newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
                                newFlags |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
                            } else {
                            } else {
                            newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
                                newFlags &= ~FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
                            }
                            }
                    } break;
                        }
                        break;
                        case FLAG_PERMISSION_WHITELIST_UPGRADE: {
                        case FLAG_PERMISSION_WHITELIST_UPGRADE: {
                        mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
                            mask |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
                            if (permissions != null && permissions.contains(permissionName)) {
                            if (permissions != null && permissions.contains(permissionName)) {
                            newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
                                newFlags |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
                            } else {
                            } else {
                            newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
                                newFlags &= ~FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
                            }
                            }
                    } break;
                        }
                        break;
                        case FLAG_PERMISSION_WHITELIST_INSTALLER: {
                        case FLAG_PERMISSION_WHITELIST_INSTALLER: {
                        mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
                            mask |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
                            if (permissions != null && permissions.contains(permissionName)) {
                            if (permissions != null && permissions.contains(permissionName)) {
                            newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
                                newFlags |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
                            } else {
                            } else {
                            newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
                                newFlags &= ~FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
                            }
                            }
                    } break;
                        }
                        break;
                    }
                    }
                }
                }


@@ -3837,7 +3845,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                // as whitelisting trumps policy i.e. policy cannot grant a non
                // as whitelisting trumps policy i.e. policy cannot grant a non
                // grantable permission.
                // grantable permission.
                if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
                if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
                final boolean isGranted = permissionsState.hasPermission(permissionName, userId);
                    final boolean isGranted = permissionsState.hasPermission(permissionName,
                            userId);
                    if (!isWhitelisted && isGranted) {
                    if (!isWhitelisted && isGranted) {
                        mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
                        mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
                        newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
                        newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
@@ -3855,19 +3864,27 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                updatePermissionFlagsInternal(permissionName, pkg.getPackageName(), mask, newFlags,
                updatePermissionFlagsInternal(permissionName, pkg.getPackageName(), mask, newFlags,
                        callingUid, userId, false, null /*callback*/);
                        callingUid, userId, false, null /*callback*/);
            }
            }
        }


        if (updatePermissions) {
        if (updatePermissions) {
            // Update permission of this app to take into account the new whitelist state.
            // Update permission of this app to take into account the new whitelist state.
            restorePermissionState(pkg, false, pkg.getPackageName(), callback);
            restorePermissionState(pkg, false, pkg.getPackageName(), callback);


            // If this resulted in losing a permission we need to kill the app.
            // If this resulted in losing a permission we need to kill the app.
            if (oldGrantedRestrictedPermissions != null) {
            for (int i = 0; i < userIds.length; i++) {
                final int oldGrantedCount = oldGrantedRestrictedPermissions.size();
                int userId = userIds[i];
                for (int i = 0; i < oldGrantedCount; i++) {
                ArraySet<String> oldPermsForUser = oldGrantedRestrictedPermissions.get(userId);
                    final String permission = oldGrantedRestrictedPermissions.valueAt(i);
                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.
                    // Sometimes we create a new permission state instance during update.
                    final PermissionsState newPermissionsState =
                    final PermissionsState newPermissionsState =
                            PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
                            PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt,
                                    pkg);
                    if (!newPermissionsState.hasPermission(permission, userId)) {
                    if (!newPermissionsState.hasPermission(permission, userId)) {
                        callback.onPermissionRevoked(pkg.getUid(), userId);
                        callback.onPermissionRevoked(pkg.getUid(), userId);
                        break;
                        break;
@@ -4624,11 +4641,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
        public void setWhitelistedRestrictedPermissions(@NonNull AndroidPackage pkg,
        public void setWhitelistedRestrictedPermissions(@NonNull AndroidPackage pkg,
                @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
                @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
                @PackageManager.PermissionWhitelistFlags int flags) {
                @PackageManager.PermissionWhitelistFlags int flags) {
            for (int userId : userIds) {
            setWhitelistedRestrictedPermissionsForUsers(pkg, userIds, permissions,
                setWhitelistedRestrictedPermissionsForUser(pkg, userId, permissions,
                    callingUid, flags, mDefaultPermissionCallback);
                    callingUid, flags, mDefaultPermissionCallback);
        }
        }
        }
        @Override
        @Override
        public void setWhitelistedRestrictedPermissions(String packageName,
        public void setWhitelistedRestrictedPermissions(String packageName,
                List<String> permissions, int flags, int userId) {
                List<String> permissions, int flags, int userId) {