From 5b53e904dcbe97479c967d17320a1e8363868567 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Tue, 11 Feb 2020 13:34:04 -0800 Subject: [PATCH] Generate fallback permission state if it is missing. This can happen after rollback if a package is installed after snapshot is taken for APEX update. We need to generate reasonable states for these packages or they may become unusable due to missing whitelisting or permission review. Bug: 136503238 Test: presubmit and ag/10203950 when it's ready Change-Id: Iafe71de1f2bfff2c624f96259e28605aec84fbda --- .../java/com/android/server/pm/Settings.java | 105 +++++++++++++----- 1 file changed, 75 insertions(+), 30 deletions(-) diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index fbea59570ac07..289eaa151eb85 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -5228,9 +5228,7 @@ public final class Settings { List permissions = getPermissionsFromPermissionsState( packageSetting.getPermissionsState(), userId); - if (permissions != null) { - packagePermissions.put(packageName, permissions); - } + packagePermissions.put(packageName, permissions); } } @@ -5243,9 +5241,7 @@ public final class Settings { List permissions = getPermissionsFromPermissionsState( sharedUserSetting.getPermissionsState(), userId); - if (permissions != null) { - sharedUserPermissions.put(sharedUserName, permissions); - } + sharedUserPermissions.put(sharedUserName, permissions); } runtimePermissions = new RuntimePermissionsState(version, fingerprint, @@ -5255,15 +5251,11 @@ public final class Settings { mPersistence.write(runtimePermissions, UserHandle.of(userId)); } - @Nullable + @NonNull private List getPermissionsFromPermissionsState( @NonNull PermissionsState permissionsState, @UserIdInt int userId) { List permissionStates = permissionsState.getRuntimePermissionStates( userId); - if (permissionStates.isEmpty()) { - return null; - } - List permissions = new ArrayList<>(); int permissionStatesSize = permissionStates.size(); @@ -5335,31 +5327,60 @@ public final class Settings { boolean defaultPermissionsGranted = Build.FINGERPRINT.equals(fingerprint); mDefaultPermissionsGranted.put(userId, defaultPermissionsGranted); - for (Map.Entry> entry - : runtimePermissions.getPackagePermissions().entrySet()) { - String packageName = entry.getKey(); - List permissions = entry.getValue(); + boolean isUpgradeToR = getInternalVersion().sdkVersion < Build.VERSION_CODES.R; - PackageSetting packageSetting = mPackages.get(packageName); - if (packageSetting == null) { - Slog.w(PackageManagerService.TAG, "Unknown package:" + packageName); - continue; + Map> packagePermissions = + runtimePermissions.getPackagePermissions(); + int packagesSize = mPackages.size(); + for (int i = 0; i < packagesSize; i++) { + String packageName = mPackages.keyAt(i); + PackageSetting packageSetting = mPackages.valueAt(i); + + List permissions = + packagePermissions.get(packageName); + if (permissions != null) { + readPermissionsStateLpr(permissions, packageSetting.getPermissionsState(), + userId); + } else if (packageSetting.sharedUser == null && !isUpgradeToR) { + Slog.w(TAG, "Missing permission state for package: " + packageName); + generateFallbackPermissionsStateLpr( + packageSetting.pkg.getRequestedPermissions(), + packageSetting.pkg.getTargetSdkVersion(), + packageSetting.getPermissionsState(), userId); } - readPermissionsStateLpr(permissions, packageSetting.getPermissionsState(), userId); } - for (Map.Entry> entry - : runtimePermissions.getSharedUserPermissions().entrySet()) { - String sharedUserName = entry.getKey(); - List permissions = entry.getValue(); + Map> sharedUserPermissions = + runtimePermissions.getSharedUserPermissions(); + int sharedUsersSize = mSharedUsers.size(); + for (int i = 0; i < sharedUsersSize; i++) { + String sharedUserName = mSharedUsers.keyAt(i); + SharedUserSetting sharedUserSetting = mSharedUsers.valueAt(i); - SharedUserSetting sharedUserSetting = mSharedUsers.get(sharedUserName); - if (sharedUserSetting == null) { - Slog.w(PackageManagerService.TAG, "Unknown shared user:" + sharedUserName); - continue; + List permissions = + sharedUserPermissions.get(sharedUserName); + if (permissions != null) { + readPermissionsStateLpr(permissions, sharedUserSetting.getPermissionsState(), + userId); + } else if (!isUpgradeToR) { + Slog.w(TAG, "Missing permission state for shared user: " + sharedUserName); + ArraySet requestedPermissions = new ArraySet<>(); + int targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT; + int sharedUserPackagesSize = sharedUserSetting.packages.size(); + for (int packagesI = 0; packagesI < sharedUserPackagesSize; packagesI++) { + PackageSetting packageSetting = sharedUserSetting.packages.valueAt( + packagesI); + if (packageSetting == null || packageSetting.pkg == null + || !packageSetting.getInstalled(userId)) { + continue; + } + AndroidPackage pkg = packageSetting.pkg; + requestedPermissions.addAll(pkg.getRequestedPermissions()); + targetSdkVersion = Math.min(targetSdkVersion, pkg.getTargetSdkVersion()); + } + generateFallbackPermissionsStateLpr(requestedPermissions, targetSdkVersion, + sharedUserSetting.getPermissionsState(), userId); } - readPermissionsStateLpr(permissions, sharedUserSetting.getPermissionsState(), - userId); } } @@ -5390,6 +5411,30 @@ public final class Settings { } } + private void generateFallbackPermissionsStateLpr( + @NonNull Collection requestedPermissions, int targetSdkVersion, + @NonNull PermissionsState permissionsState, @UserIdInt int userId) { + for (String permissionName : requestedPermissions) { + BasePermission permission = mPermissions.getPermission(permissionName); + if (Objects.equals(permission.getSourcePackageName(), PLATFORM_PACKAGE_NAME) + && permission.isRuntime() && !permission.isRemoved()) { + if (permission.isHardOrSoftRestricted() || permission.isImmutablyRestricted()) { + permissionsState.updatePermissionFlags(permission, userId, + PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT, + PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT); + } + if (targetSdkVersion < Build.VERSION_CODES.M) { + permissionsState.updatePermissionFlags(permission, userId, + PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED + | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT, + PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED + | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT); + permissionsState.grantRuntimePermission(permission, userId); + } + } + } + } + @GuardedBy("Settings.this.mLock") private void readLegacyStateForUserSyncLPr(int userId) { File permissionsFile = getUserRuntimePermissionsFile(userId);