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

Commit 97a30acf authored by Hai Zhang's avatar Hai Zhang Committed by Android (Google) Code Review
Browse files

Merge "Avoid calling into package manager while holding permission lock."

parents 7111b47e 3d012cb5
Loading
Loading
Loading
Loading
+163 −175
Original line number Original line Diff line number Diff line
@@ -554,13 +554,14 @@ public class PermissionManagerService extends IPermissionManager.Stub {
        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
            return null;
            return null;
        }
        }
        final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
        synchronized (mLock) {
        synchronized (mLock) {
            final BasePermission bp = mSettings.getPermissionLocked(permName);
            final BasePermission bp = mSettings.getPermissionLocked(permName);
            if (bp == null) {
            if (bp == null) {
                return null;
                return null;
            }
            }
            final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
            final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
                    bp.getProtectionLevel(), packageName, callingUid);
                    bp.getProtectionLevel(), pkg, callingUid);
            return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
            return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
        }
        }
    }
    }
@@ -2229,8 +2230,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
        }
        }
    }
    }


    private int adjustPermissionProtectionFlagsLocked(
    private int adjustPermissionProtectionFlagsLocked(int protectionLevel,
            int protectionLevel, String packageName, int uid) {
            @Nullable AndroidPackage pkg, int uid) {
        // Signature permission flags area always reported
        // Signature permission flags area always reported
        final int protectionLevelMasked = protectionLevel
        final int protectionLevelMasked = protectionLevel
                & (PermissionInfo.PROTECTION_NORMAL
                & (PermissionInfo.PROTECTION_NORMAL
@@ -2245,8 +2246,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                || appId == Process.SHELL_UID) {
                || appId == Process.SHELL_UID) {
            return protectionLevel;
            return protectionLevel;
        }
        }
        // Normalize package name to handle renamed packages and static libs
        final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
        if (pkg == null) {
        if (pkg == null) {
            return protectionLevel;
            return protectionLevel;
        }
        }
@@ -2254,14 +2253,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
            return protectionLevelMasked;
            return protectionLevelMasked;
        }
        }
        // Apps that target O see flags for all protection levels.
        // Apps that target O see flags for all protection levels.
        final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
                pkg.getPackageName());
        if (ps == null) {
            return protectionLevel;
        }
        if (ps.getAppId() != appId) {
            return protectionLevel;
        }
        return protectionLevel;
        return protectionLevel;
    }
    }


@@ -2586,8 +2577,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                // changed runtime permissions here are promotion of an install to
                // changed runtime permissions here are promotion of an install to
                // runtime and revocation of a runtime from a shared user.
                // runtime and revocation of a runtime from a shared user.
                synchronized (mLock) {
                synchronized (mLock) {
                    updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
                    updatedUserIds = revokeUnusedSharedUserPermissionsLocked(ps.getSharedUser(),
                            ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
                            currentUserIds);
                    if (!ArrayUtils.isEmpty(updatedUserIds)) {
                    if (!ArrayUtils.isEmpty(updatedUserIds)) {
                        runtimePermissionsRevoked = true;
                        runtimePermissionsRevoked = true;
                    }
                    }
@@ -2597,13 +2588,12 @@ public class PermissionManagerService extends IPermissionManager.Stub {


        permissionsState.setGlobalGids(mGlobalGids);
        permissionsState.setGlobalGids(mGlobalGids);


        synchronized (mLock) {
        ArraySet<String> newImplicitPermissions = new ArraySet<>();
        ArraySet<String> newImplicitPermissions = new ArraySet<>();


        final int N = pkg.getRequestedPermissions().size();
        final int N = pkg.getRequestedPermissions().size();
        for (int i = 0; i < N; i++) {
        for (int i = 0; i < N; i++) {
            final String permName = pkg.getRequestedPermissions().get(i);
            final String permName = pkg.getRequestedPermissions().get(i);
                final BasePermission bp = mSettings.getPermissionLocked(permName);
            final BasePermission bp = mSettings.getPermission(permName);
            final boolean appSupportsRuntimePermissions =
            final boolean appSupportsRuntimePermissions =
                    pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M;
                    pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M;
            String upgradedActivityRecognitionPermission = null;
            String upgradedActivityRecognitionPermission = null;
@@ -2708,17 +2698,12 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                }
                }
            } else if (bp.isSignature()) {
            } else if (bp.isSignature()) {
                // For all apps signature permissions are install time ones.
                // For all apps signature permissions are install time ones.
                    allowedSig = grantSignaturePermission(perm, pkg, ps, bp, origPermissions);
                allowedSig = shouldGrantSignaturePermission(perm, pkg, ps, bp, origPermissions);
                if (allowedSig) {
                if (allowedSig) {
                    grant = GRANT_INSTALL;
                    grant = GRANT_INSTALL;
                }
                }
            }
            }


                if (DEBUG_PERMISSIONS) {
                    Slog.i(TAG, "Considering granting permission " + perm + " to package "
                            + pkg.getPackageName());
                }

            if (grant != GRANT_DENIED) {
            if (grant != GRANT_DENIED) {
                if (!ps.isSystem() && ps.areInstallPermissionsFixed() && !bp.isRuntime()) {
                if (!ps.isSystem() && ps.areInstallPermissionsFixed() && !bp.isRuntime()) {
                    // If this is an existing, non-system package, then
                    // If this is an existing, non-system package, then
@@ -2733,14 +2718,22 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                        }
                        }
                    }
                    }
                }
                }
            }

            if (DEBUG_PERMISSIONS) {
                Slog.i(TAG, "Considering granting permission " + perm + " to package "
                        + pkg.getPackageName());
            }


            synchronized (mLock) {
                if (grant != GRANT_DENIED) {
                    switch (grant) {
                    switch (grant) {
                        case GRANT_INSTALL: {
                        case GRANT_INSTALL: {
                            // Revoke this as runtime permission to handle the case of
                            // Revoke this as runtime permission to handle the case of
                            // a runtime permission being downgraded to an install one.
                            // a runtime permission being downgraded to an install one.
                            // Also in permission review mode we keep dangerous permissions
                            // Also in permission review mode we keep dangerous permissions
                            // for legacy apps
                            // for legacy apps
                            for (int userId : UserManagerService.getInstance().getUserIds()) {
                            for (int userId : currentUserIds) {
                                if (origPermissions.getRuntimePermissionState(
                                if (origPermissions.getRuntimePermissionState(
                                        perm, userId) != null) {
                                        perm, userId) != null) {
                                    // Revoke the runtime permission and clear the flags.
                                    // Revoke the runtime permission and clear the flags.
@@ -3042,6 +3035,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                    }
                    }
                }
                }
            }
            }
        }


        if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
        if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
                !ps.isSystem() || ps.getPkgState().isUpdatedSystemApp()) {
                !ps.isSystem() || ps.getPkgState().isUpdatedSystemApp()) {
@@ -3051,11 +3045,13 @@ public class PermissionManagerService extends IPermissionManager.Stub {
            ps.setInstallPermissionsFixed(true);
            ps.setInstallPermissionsFixed(true);
        }
        }


        synchronized (mLock) {
            updatedUserIds = revokePermissionsNoLongerImplicitLocked(permissionsState, pkg,
            updatedUserIds = revokePermissionsNoLongerImplicitLocked(permissionsState, pkg,
                    updatedUserIds);
                    currentUserIds, updatedUserIds);
            updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
            updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
                    permissionsState, pkg, newImplicitPermissions, updatedUserIds);
                    permissionsState, pkg, newImplicitPermissions, currentUserIds, updatedUserIds);
            updatedUserIds = checkIfLegacyStorageOpsNeedToBeUpdated(pkg, replace, updatedUserIds);
            updatedUserIds = checkIfLegacyStorageOpsNeedToBeUpdated(pkg, replace, currentUserIds,
                    updatedUserIds);
        }
        }


        // Persist the runtime permissions state for users with changes. If permissions
        // Persist the runtime permissions state for users with changes. If permissions
@@ -3076,23 +3072,19 @@ public class PermissionManagerService extends IPermissionManager.Stub {
     *
     *
     * @param ps The state of the permissions of the package
     * @param ps The state of the permissions of the package
     * @param pkg The package that is currently looked at
     * @param pkg The package that is currently looked at
     * @param userIds All user IDs in the system, must be passed in because this method is locked
     * @param updatedUserIds a list of user ids that needs to be amended if the permission state
     * @param updatedUserIds a list of user ids that needs to be amended if the permission state
     *                       for a user is changed.
     *                       for a user is changed.
     *
     *
     * @return The updated value of the {@code updatedUserIds} parameter
     * @return The updated value of the {@code updatedUserIds} parameter
     */
     */
    private @NonNull int[] revokePermissionsNoLongerImplicitLocked(
    private @NonNull int[] revokePermissionsNoLongerImplicitLocked(@NonNull PermissionsState ps,
            @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
            @NonNull AndroidPackage pkg, @NonNull int[] userIds, @NonNull int[] updatedUserIds) {
            @NonNull int[] updatedUserIds) {
        String pkgName = pkg.getPackageName();
        String pkgName = pkg.getPackageName();
        boolean supportsRuntimePermissions = pkg.getTargetSdkVersion()
        boolean supportsRuntimePermissions = pkg.getTargetSdkVersion()
                >= Build.VERSION_CODES.M;
                >= Build.VERSION_CODES.M;


        int[] users = UserManagerService.getInstance().getUserIds();
        for (int userId : userIds) {
        int numUsers = users.length;
        for (int i = 0; i < numUsers; i++) {
            int userId = users[i];

            for (String permission : ps.getPermissions(userId)) {
            for (String permission : ps.getPermissions(userId)) {
                if (!pkg.getImplicitPermissions().contains(permission)) {
                if (!pkg.getImplicitPermissions().contains(permission)) {
                    if (!ps.hasInstallPermission(permission)) {
                    if (!ps.hasInstallPermission(permission)) {
@@ -3188,16 +3180,17 @@ public class PermissionManagerService extends IPermissionManager.Stub {
     *
     *
     * @param pkg The package for which the permissions are updated
     * @param pkg The package for which the permissions are updated
     * @param replace If the app is being replaced
     * @param replace If the app is being replaced
     * @param userIds All user IDs in the system, must be passed in because this method is locked
     * @param updatedUserIds The ids of the users that already changed.
     * @param updatedUserIds The ids of the users that already changed.
     *
     *
     * @return The ids of the users that are changed
     * @return The ids of the users that are changed
     */
     */
    private @NonNull int[] checkIfLegacyStorageOpsNeedToBeUpdated(
    private @NonNull int[] checkIfLegacyStorageOpsNeedToBeUpdated(@NonNull AndroidPackage pkg,
            @NonNull AndroidPackage pkg, boolean replace, @NonNull int[] updatedUserIds) {
            boolean replace, @NonNull int[] userIds, @NonNull int[] updatedUserIds) {
        if (replace && pkg.isRequestLegacyExternalStorage() && (
        if (replace && pkg.isRequestLegacyExternalStorage() && (
                pkg.getRequestedPermissions().contains(READ_EXTERNAL_STORAGE)
                pkg.getRequestedPermissions().contains(READ_EXTERNAL_STORAGE)
                        || pkg.getRequestedPermissions().contains(WRITE_EXTERNAL_STORAGE))) {
                        || pkg.getRequestedPermissions().contains(WRITE_EXTERNAL_STORAGE))) {
            return UserManagerService.getInstance().getUserIds();
            return userIds.clone();
        }
        }


        return updatedUserIds;
        return updatedUserIds;
@@ -3209,15 +3202,15 @@ public class PermissionManagerService extends IPermissionManager.Stub {
     * @param origPs The permission state of the package before the split
     * @param origPs The permission state of the package before the split
     * @param ps The new permission state
     * @param ps The new permission state
     * @param pkg The package the permission belongs to
     * @param pkg The package the permission belongs to
     * @param userIds All user IDs in the system, must be passed in because this method is locked
     * @param updatedUserIds List of users for which the permission state has already been changed
     * @param updatedUserIds List of users for which the permission state has already been changed
     *
     *
     * @return  List of users for which the permission state has been changed
     * @return  List of users for which the permission state has been changed
     */
     */
    private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked(
    private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked(
            @NonNull PermissionsState origPs,
            @NonNull PermissionsState origPs, @NonNull PermissionsState ps,
            @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
            @NonNull AndroidPackage pkg, @NonNull ArraySet<String> newImplicitPermissions,
            @NonNull ArraySet<String> newImplicitPermissions,
            @NonNull int[] userIds, @NonNull int[] updatedUserIds) {
            @NonNull int[] updatedUserIds) {
        String pkgName = pkg.getPackageName();
        String pkgName = pkg.getPackageName();
        ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();
        ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();


@@ -3251,11 +3244,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                if (!ps.hasInstallPermission(newPerm)) {
                if (!ps.hasInstallPermission(newPerm)) {
                    BasePermission bp = mSettings.getPermissionLocked(newPerm);
                    BasePermission bp = mSettings.getPermissionLocked(newPerm);


                    int[] users = UserManagerService.getInstance().getUserIds();
                    for (int userId : userIds) {
                    int numUsers = users.length;
                    for (int userNum = 0; userNum < numUsers; userNum++) {
                        int userId = users[userNum];

                        if (!newPerm.equals(Manifest.permission.ACTIVITY_RECOGNITION)) {
                        if (!newPerm.equals(Manifest.permission.ACTIVITY_RECOGNITION)) {
                            ps.updatePermissionFlags(bp, userId,
                            ps.updatePermissionFlags(bp, userId,
                                    FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
                                    FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
@@ -3413,7 +3402,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
        return wlPermissions != null && wlPermissions.contains(perm);
        return wlPermissions != null && wlPermissions.contains(perm);
    }
    }


    private boolean grantSignaturePermission(String perm, AndroidPackage pkg,
    private boolean shouldGrantSignaturePermission(String perm, AndroidPackage pkg,
            PackageSetting pkgSetting, BasePermission bp, PermissionsState origPermissions) {
            PackageSetting pkgSetting, BasePermission bp, PermissionsState origPermissions) {
        boolean oemPermission = bp.isOEM();
        boolean oemPermission = bp.isOEM();
        boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
        boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
@@ -4210,6 +4199,14 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                // The target package is the source of the current permission
                // The target package is the source of the current permission
                // Set to changed for either install or uninstall
                // Set to changed for either install or uninstall
                changed = true;
                changed = true;
                if (needsUpdate == null) {
                    needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
                }
                needsUpdate.add(bp);
            }
        }
        if (needsUpdate != null) {
            for (final BasePermission bp : needsUpdate) {
                // If the target package is being uninstalled, we need to revoke this permission
                // If the target package is being uninstalled, we need to revoke this permission
                // From all other packages
                // From all other packages
                if (pkg == null || !hasPermission(pkg, bp.getName())) {
                if (pkg == null || !hasPermission(pkg, bp.getName())) {
@@ -4239,16 +4236,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                            }
                            }
                        });
                        });
                    }
                    }
                    it.remove();
                    mSettings.removePermissionLocked(bp.getName());
                }
                    continue;
                if (needsUpdate == null) {
                    needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
                }
                needsUpdate.add(bp);
            }
                }
                }
        if (needsUpdate != null) {
            for (final BasePermission bp : needsUpdate) {
                final AndroidPackage sourcePkg =
                final AndroidPackage sourcePkg =
                        mPackageManagerInt.getPackage(bp.getSourcePackageName());
                        mPackageManagerInt.getPackage(bp.getSourcePackageName());
                final PackageSetting sourcePs =
                final PackageSetting sourcePs =
@@ -5007,11 +4997,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
        @Override
        @Override
        public void onNewUserCreated(int userId) {
        public void onNewUserCreated(int userId) {
            mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
            mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
            synchronized (mLock) {
            // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
            // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
                PermissionManagerService.this.updateAllPermissions(
            PermissionManagerService.this.updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL,
                        StorageManager.UUID_PRIVATE_INTERNAL, true, mDefaultPermissionCallback);
                    true, mDefaultPermissionCallback);
            }
        }
        }


        @Override
        @Override
+7 −5
Original line number Original line Diff line number Diff line
@@ -88,6 +88,7 @@ public class PermissionSettings {
    }
    }


    public void addAppOpPackage(String permName, String packageName) {
    public void addAppOpPackage(String permName, String packageName) {
        synchronized (mLock) {
            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permName);
            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permName);
            if (pkgs == null) {
            if (pkgs == null) {
                pkgs = new ArraySet<>();
                pkgs = new ArraySet<>();
@@ -95,6 +96,7 @@ public class PermissionSettings {
            }
            }
            pkgs.add(packageName);
            pkgs.add(packageName);
        }
        }
    }


    /**
    /**
     * Transfers ownership of permissions from one package to another.
     * Transfers ownership of permissions from one package to another.