summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java49
1 files changed, 49 insertions, 0 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 fb1ed2f6b58b..13c866d0d8e2 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -205,6 +205,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<>();
@@ -213,6 +216,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 */
@@ -2358,6 +2364,48 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
/**
+ * 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 revokeStoragePermissionsIfScopeExpandedInternal(
+ @NonNull AndroidPackage newPackage,
+ @NonNull AndroidPackage oldPackage) {
+ 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, mDefaultPermissionCallback);
+ }
+
+ }
+
+ /**
* 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
* the new group auto-granted.
@@ -4884,6 +4932,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
AsyncTask.execute(() -> {
if (hasOldPkg) {
revokeRuntimePermissionsIfGroupChangedInternal(pkg, oldPkg);
+ revokeStoragePermissionsIfScopeExpandedInternal(pkg, oldPkg);
}
if (hasPermissionDefinitionChanges) {
revokeRuntimePermissionsIfPermissionDefinitionChangedInternal(