Loading services/core/java/com/android/server/pm/PackageManagerService.java +1 −0 Original line number Diff line number Diff line Loading @@ -12499,6 +12499,7 @@ public class PackageManagerService extends IPackageManager.Stub if (hasOldPkg) { mPermissionManager.revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg, allPackageNames); mPermissionManager.revokeStoragePermissionsIfScopeExpanded(pkg, oldPkg); } if (hasPermissionDefinitionChanges) { mPermissionManager.revokeRuntimePermissionsIfPermissionDefinitionChanged( services/core/java/com/android/server/pm/permission/PermissionManagerService.java +62 −0 Original line number Diff line number Diff line Loading @@ -206,6 +206,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { private static final int USER_PERMISSION_FLAGS = FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED; /** All storage permissions */ private static final List<String> STORAGE_PERMISSIONS = new ArrayList<>(); /** If the permission of the value is granted, so is the key */ private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>(); Loading @@ -214,6 +217,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { Manifest.permission.ACCESS_FINE_LOCATION); FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS, Manifest.permission.INTERACT_ACROSS_USERS_FULL); STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE); STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); STORAGE_PERMISSIONS.add(Manifest.permission.ACCESS_MEDIA_LOCATION); } /** Lock to protect internal data access */ Loading Loading @@ -2265,6 +2271,49 @@ public class PermissionManagerService extends IPermissionManager.Stub { return protectionLevel; } /** * If the app is updated, and has scoped storage permissions, then it is possible that the * app updated in an attempt to get unscoped storage. If so, revoke all storage permissions. * @param newPackage The new package that was installed * @param oldPackage The old package that was updated */ private void revokeStoragePermissionsIfScopeExpanded( @NonNull AndroidPackage newPackage, @NonNull AndroidPackage oldPackage, @NonNull PermissionCallback permissionCallback) { boolean downgradedSdk = oldPackage.getTargetSdkVersion() >= Build.VERSION_CODES.Q && newPackage.getTargetSdkVersion() < Build.VERSION_CODES.Q; boolean upgradedSdk = oldPackage.getTargetSdkVersion() < Build.VERSION_CODES.Q && newPackage.getTargetSdkVersion() >= Build.VERSION_CODES.Q; boolean newlyRequestsLegacy = !upgradedSdk && !oldPackage.isRequestLegacyExternalStorage() && newPackage.isRequestLegacyExternalStorage(); if (!newlyRequestsLegacy && !downgradedSdk) { return; } final int callingUid = Binder.getCallingUid(); final int userId = UserHandle.getUserId(newPackage.getUid()); int numRequestedPermissions = newPackage.getRequestedPermissions().size(); for (int i = 0; i < numRequestedPermissions; i++) { PermissionInfo permInfo = getPermissionInfo(newPackage.getRequestedPermissions().get(i), newPackage.getPackageName(), 0); if (permInfo == null || !STORAGE_PERMISSIONS.contains(permInfo.name)) { continue; } EventLog.writeEvent(0x534e4554, "171430330", newPackage.getUid(), "Revoking permission " + permInfo.name + " from package " + newPackage.getPackageName() + " as either the sdk downgraded " + downgradedSdk + " or newly requested legacy full storage " + newlyRequestsLegacy); revokeRuntimePermissionInternal(permInfo.name, newPackage.getPackageName(), false, callingUid, userId, null, permissionCallback); } } /** * We might auto-grant permissions if any permission of the group is already granted. Hence if * the group of a granted permission changes we need to revoke it to avoid having permissions of Loading Loading @@ -4726,6 +4775,19 @@ public class PermissionManagerService extends IPermissionManager.Stub { @UserIdInt int userId) { return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId); } /** * If the app is updated, and has scoped storage permissions, then it is possible that the * app updated in an attempt to get unscoped storage. If so, revoke all storage permissions. * @param newPackage The new package that was installed * @param oldPackage The old package that was updated */ public void revokeStoragePermissionsIfScopeExpanded( @NonNull AndroidPackage newPackage, @NonNull AndroidPackage oldPackage ) { PermissionManagerService.this.revokeStoragePermissionsIfScopeExpanded(newPackage, oldPackage, mDefaultPermissionCallback); } @Override public void revokeRuntimePermissionsIfGroupChanged( Loading services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java +11 −0 Original line number Diff line number Diff line Loading @@ -265,6 +265,17 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager @NonNull List<String> permissionsToRevoke, @NonNull ArrayList<String> allPackageNames); /** * If the app is updated, and has scoped storage permissions, then it is possible that the * app updated in an attempt to get unscoped storage. If so, revoke all storage permissions. * @param newPackage The new package that was installed * @param oldPackage The old package that was updated */ public abstract void revokeStoragePermissionsIfScopeExpanded( @NonNull AndroidPackage newPackage, @NonNull AndroidPackage oldPackage ); /** * Add all permissions in the given package. * <p> Loading Loading
services/core/java/com/android/server/pm/PackageManagerService.java +1 −0 Original line number Diff line number Diff line Loading @@ -12499,6 +12499,7 @@ public class PackageManagerService extends IPackageManager.Stub if (hasOldPkg) { mPermissionManager.revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg, allPackageNames); mPermissionManager.revokeStoragePermissionsIfScopeExpanded(pkg, oldPkg); } if (hasPermissionDefinitionChanges) { mPermissionManager.revokeRuntimePermissionsIfPermissionDefinitionChanged(
services/core/java/com/android/server/pm/permission/PermissionManagerService.java +62 −0 Original line number Diff line number Diff line Loading @@ -206,6 +206,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { private static final int USER_PERMISSION_FLAGS = FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED; /** All storage permissions */ private static final List<String> STORAGE_PERMISSIONS = new ArrayList<>(); /** If the permission of the value is granted, so is the key */ private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>(); Loading @@ -214,6 +217,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { Manifest.permission.ACCESS_FINE_LOCATION); FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS, Manifest.permission.INTERACT_ACROSS_USERS_FULL); STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE); STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); STORAGE_PERMISSIONS.add(Manifest.permission.ACCESS_MEDIA_LOCATION); } /** Lock to protect internal data access */ Loading Loading @@ -2265,6 +2271,49 @@ public class PermissionManagerService extends IPermissionManager.Stub { return protectionLevel; } /** * If the app is updated, and has scoped storage permissions, then it is possible that the * app updated in an attempt to get unscoped storage. If so, revoke all storage permissions. * @param newPackage The new package that was installed * @param oldPackage The old package that was updated */ private void revokeStoragePermissionsIfScopeExpanded( @NonNull AndroidPackage newPackage, @NonNull AndroidPackage oldPackage, @NonNull PermissionCallback permissionCallback) { boolean downgradedSdk = oldPackage.getTargetSdkVersion() >= Build.VERSION_CODES.Q && newPackage.getTargetSdkVersion() < Build.VERSION_CODES.Q; boolean upgradedSdk = oldPackage.getTargetSdkVersion() < Build.VERSION_CODES.Q && newPackage.getTargetSdkVersion() >= Build.VERSION_CODES.Q; boolean newlyRequestsLegacy = !upgradedSdk && !oldPackage.isRequestLegacyExternalStorage() && newPackage.isRequestLegacyExternalStorage(); if (!newlyRequestsLegacy && !downgradedSdk) { return; } final int callingUid = Binder.getCallingUid(); final int userId = UserHandle.getUserId(newPackage.getUid()); int numRequestedPermissions = newPackage.getRequestedPermissions().size(); for (int i = 0; i < numRequestedPermissions; i++) { PermissionInfo permInfo = getPermissionInfo(newPackage.getRequestedPermissions().get(i), newPackage.getPackageName(), 0); if (permInfo == null || !STORAGE_PERMISSIONS.contains(permInfo.name)) { continue; } EventLog.writeEvent(0x534e4554, "171430330", newPackage.getUid(), "Revoking permission " + permInfo.name + " from package " + newPackage.getPackageName() + " as either the sdk downgraded " + downgradedSdk + " or newly requested legacy full storage " + newlyRequestsLegacy); revokeRuntimePermissionInternal(permInfo.name, newPackage.getPackageName(), false, callingUid, userId, null, permissionCallback); } } /** * We might auto-grant permissions if any permission of the group is already granted. Hence if * the group of a granted permission changes we need to revoke it to avoid having permissions of Loading Loading @@ -4726,6 +4775,19 @@ public class PermissionManagerService extends IPermissionManager.Stub { @UserIdInt int userId) { return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId); } /** * If the app is updated, and has scoped storage permissions, then it is possible that the * app updated in an attempt to get unscoped storage. If so, revoke all storage permissions. * @param newPackage The new package that was installed * @param oldPackage The old package that was updated */ public void revokeStoragePermissionsIfScopeExpanded( @NonNull AndroidPackage newPackage, @NonNull AndroidPackage oldPackage ) { PermissionManagerService.this.revokeStoragePermissionsIfScopeExpanded(newPackage, oldPackage, mDefaultPermissionCallback); } @Override public void revokeRuntimePermissionsIfGroupChanged( Loading
services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java +11 −0 Original line number Diff line number Diff line Loading @@ -265,6 +265,17 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager @NonNull List<String> permissionsToRevoke, @NonNull ArrayList<String> allPackageNames); /** * If the app is updated, and has scoped storage permissions, then it is possible that the * app updated in an attempt to get unscoped storage. If so, revoke all storage permissions. * @param newPackage The new package that was installed * @param oldPackage The old package that was updated */ public abstract void revokeStoragePermissionsIfScopeExpanded( @NonNull AndroidPackage newPackage, @NonNull AndroidPackage oldPackage ); /** * Add all permissions in the given package. * <p> Loading