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

Commit 5b53e904 authored by Hai Zhang's avatar Hai Zhang
Browse files

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
parent 0625fde1
Loading
Loading
Loading
Loading
+80 −35
Original line number Diff line number Diff line
@@ -5228,11 +5228,9 @@ public final class Settings {
                        List<RuntimePermissionsState.PermissionState> permissions =
                                getPermissionsFromPermissionsState(
                                        packageSetting.getPermissionsState(), userId);
                        if (permissions != null) {
                        packagePermissions.put(packageName, permissions);
                    }
                }
                }

                Map<String, List<RuntimePermissionsState.PermissionState>> sharedUserPermissions =
                        new ArrayMap<>();
@@ -5243,10 +5241,8 @@ public final class Settings {
                    List<RuntimePermissionsState.PermissionState> permissions =
                            getPermissionsFromPermissionsState(
                                    sharedUserSetting.getPermissionsState(), userId);
                    if (permissions != null) {
                    sharedUserPermissions.put(sharedUserName, permissions);
                }
                }

                runtimePermissions = new RuntimePermissionsState(version, fingerprint,
                        packagePermissions, sharedUserPermissions);
@@ -5255,15 +5251,11 @@ public final class Settings {
            mPersistence.write(runtimePermissions, UserHandle.of(userId));
        }

        @Nullable
        @NonNull
        private List<RuntimePermissionsState.PermissionState> getPermissionsFromPermissionsState(
                @NonNull PermissionsState permissionsState, @UserIdInt int userId) {
            List<PermissionState> permissionStates = permissionsState.getRuntimePermissionStates(
                    userId);
            if (permissionStates.isEmpty()) {
                return null;
            }

            List<RuntimePermissionsState.PermissionState> 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<String, List<RuntimePermissionsState.PermissionState>> entry
                    : runtimePermissions.getPackagePermissions().entrySet()) {
                String packageName = entry.getKey();
                List<RuntimePermissionsState.PermissionState> 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<String, List<RuntimePermissionsState.PermissionState>> 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<RuntimePermissionsState.PermissionState> 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<String, List<RuntimePermissionsState.PermissionState>> entry
                    : runtimePermissions.getSharedUserPermissions().entrySet()) {
                String sharedUserName = entry.getKey();
                List<RuntimePermissionsState.PermissionState> permissions = entry.getValue();
            Map<String, List<RuntimePermissionsState.PermissionState>> 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<RuntimePermissionsState.PermissionState> 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<String> 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);
                }
            }
        }

@@ -5390,6 +5411,30 @@ public final class Settings {
            }
        }

        private void generateFallbackPermissionsStateLpr(
                @NonNull Collection<String> 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);