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

Commit c88dec32 authored by Svetoslav's avatar Svetoslav Committed by Android Git Automerger
Browse files

am 6638c182: Merge "Fix reset permissions on clear data and package uninstall." into mnc-dev

* commit '6638c182':
  Fix reset permissions on clear data and package uninstall.
parents c69e1410 6638c182
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -4627,12 +4627,12 @@ public abstract class PackageManager {
    /** {@hide} */
    public static String permissionFlagToString(int flag) {
        switch (flag) {
            case FLAG_PERMISSION_GRANTED_BY_DEFAULT: return "FLAG_PERMISSION_GRANTED_BY_DEFAULT";
            case FLAG_PERMISSION_POLICY_FIXED: return "FLAG_PERMISSION_POLICY_FIXED";
            case FLAG_PERMISSION_SYSTEM_FIXED: return "FLAG_PERMISSION_SYSTEM_FIXED";
            case FLAG_PERMISSION_USER_SET: return "FLAG_PERMISSION_USER_SET";
            case FLAG_PERMISSION_REVOKE_ON_UPGRADE: return "FLAG_PERMISSION_REVOKE_ON_UPGRADE";
            case FLAG_PERMISSION_USER_FIXED: return "FLAG_PERMISSION_USER_FIXED";
            case FLAG_PERMISSION_GRANTED_BY_DEFAULT: return "GRANTED_BY_DEFAULT";
            case FLAG_PERMISSION_POLICY_FIXED: return "POLICY_FIXED";
            case FLAG_PERMISSION_SYSTEM_FIXED: return "SYSTEM_FIXED";
            case FLAG_PERMISSION_USER_SET: return "USER_SET";
            case FLAG_PERMISSION_REVOKE_ON_UPGRADE: return "REVOKE_ON_UPGRADE";
            case FLAG_PERMISSION_USER_FIXED: return "USER_FIXED";
            default: return Integer.toString(flag);
        }
    }
+116 −51
Original line number Diff line number Diff line
@@ -25,6 +25,12 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
@@ -72,6 +78,9 @@ import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
import android.Manifest;
import android.app.ActivityManager;
@@ -12781,8 +12790,14 @@ public class PackageManagerService extends IPackageManager.Stub {
        // writer
        synchronized (mPackages) {
            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
            // Propagate the permissions state as we do want to drop on the floor
            // runtime permissions. The update permissions method below will take
            // care of removing obsolete permissions and grant install permissions.
            ps.getPermissionsState().copyFrom(disabledPs.getPermissionsState());
            updatePermissionsLPw(newPkg.packageName, newPkg,
                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
            if (applyUserRestrictions) {
                if (DEBUG_REMOVE) {
                    Slog.d(TAG, "Propagating install state across reinstall");
@@ -12943,8 +12958,7 @@ public class PackageManagerService extends IPackageManager.Stub {
                if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) {
                    scheduleWritePackageRestrictionsLocked(removeUser);
                }
                revokeRuntimePermissionsAndClearAllFlagsLocked(ps.getPermissionsState(),
                        removeUser);
                resetUserChangesToRuntimePermissionsAndFlagsLocked(ps, removeUser);
            }
            return true;
        }
@@ -13105,8 +13119,7 @@ public class PackageManagerService extends IPackageManager.Stub {
            }
            PackageSetting ps = (PackageSetting) pkg.mExtras;
            PermissionsState permissionsState = ps.getPermissionsState();
            revokeRuntimePermissionsAndClearUserSetFlagsLocked(permissionsState, userId);
            resetUserChangesToRuntimePermissionsAndFlagsLocked(ps, userId);
        }
        // Always delete data directories for package, even if we found no other
@@ -13137,66 +13150,118 @@ public class PackageManagerService extends IPackageManager.Stub {
        return true;
    }
    /**
     * Revokes granted runtime permissions and clears resettable flags
     * which are flags that can be set by a user interaction.
     * Reverts user permission state changes (permissions and flags).
     *
     * @param permissionsState The permission state to reset.
     * @param ps The package for which to reset.
     * @param userId The device user for which to do a reset.
     */
    private void revokeRuntimePermissionsAndClearUserSetFlagsLocked(
            PermissionsState permissionsState, int userId) {
        final int userSetFlags = PackageManager.FLAG_PERMISSION_USER_SET
                | PackageManager.FLAG_PERMISSION_USER_FIXED
                | PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
    private void resetUserChangesToRuntimePermissionsAndFlagsLocked(
            final PackageSetting ps, final int userId) {
        if (ps.pkg == null) {
            return;
        }
        revokeRuntimePermissionsAndClearFlagsLocked(permissionsState, userId, userSetFlags);
        final int userSettableFlags = FLAG_PERMISSION_USER_SET
                | FLAG_PERMISSION_USER_FIXED
                | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
                | FLAG_PERMISSION_POLICY_FIXED;
        boolean writeInstallPermissions = false;
        boolean writeRuntimePermissions = false;
        final int permissionCount = ps.pkg.requestedPermissions.size();
        for (int i = 0; i < permissionCount; i++) {
            String permission = ps.pkg.requestedPermissions.get(i);
            BasePermission bp = mSettings.mPermissions.get(permission);
            if (bp == null) {
                continue;
            }
    /**
     * Revokes granted runtime permissions and clears all flags.
     *
     * @param permissionsState The permission state to reset.
     * @param userId The device user for which to do a reset.
     */
    private void revokeRuntimePermissionsAndClearAllFlagsLocked(
            PermissionsState permissionsState, int userId) {
        revokeRuntimePermissionsAndClearFlagsLocked(permissionsState, userId,
                PackageManager.MASK_PERMISSION_FLAGS);
            // If shared user we just reset the state to which only this app contributed.
            if (ps.sharedUser != null) {
                boolean used = false;
                final int packageCount = ps.sharedUser.packages.size();
                for (int j = 0; j < packageCount; j++) {
                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
                            && pkg.pkg.requestedPermissions.contains(permission)) {
                        used = true;
                        break;
                    }
                }
                if (used) {
                    continue;
                }
            }
    /**
     * Revokes granted runtime permissions and clears certain flags.
     *
     * @param permissionsState The permission state to reset.
     * @param userId The device user for which to do a reset.
     * @param flags The flags that is going to be reset.
     */
    private void revokeRuntimePermissionsAndClearFlagsLocked(
            PermissionsState permissionsState, final int userId, int flags) {
        boolean needsWrite = false;
            PermissionsState permissionsState = ps.getPermissionsState();
        for (PermissionState state : permissionsState.getRuntimePermissionStates(userId)) {
            BasePermission bp = mSettings.mPermissions.get(state.getName());
            if (bp != null) {
                permissionsState.revokeRuntimePermission(bp, userId);
                permissionsState.updatePermissionFlags(bp, userId, flags, 0);
                needsWrite = true;
            final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
            // Always clear the user settable flags.
            final boolean hasInstallState = permissionsState.getInstallPermissionState(
                    bp.name) != null;
            if (permissionsState.updatePermissionFlags(bp, userId, userSettableFlags, 0)) {
                if (hasInstallState) {
                    writeInstallPermissions = true;
                } else {
                    writeRuntimePermissions = true;
                }
            }
        // Ensure default permissions are never cleared.
            // Below is only runtime permission handling.
            if (!bp.isRuntime()) {
                continue;
            }
            // Never clobber system or policy.
            if ((oldFlags & policyOrSystemFlags) != 0) {
                continue;
            }
            // If this permission was granted by default, make sure it is.
            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
                if (permissionsState.grantRuntimePermission(bp, userId)
                        != PERMISSION_OPERATION_FAILURE) {
                    writeRuntimePermissions = true;
                }
            } else {
                // Otherwise, reset the permission.
                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
                switch (revokeResult) {
                    case PERMISSION_OPERATION_SUCCESS: {
                        writeRuntimePermissions = true;
                    } break;
                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
                        writeRuntimePermissions = true;
                        // If gids changed for this user, kill all affected packages.
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                mDefaultPermissionPolicy.grantDefaultPermissions(userId);
                                // This has to happen with no lock held.
                                killSettingPackagesForUser(ps, userId,
                                        KILL_APP_REASON_GIDS_CHANGED);
                            }
                        });
                    } break;
                }
            }
        }
        if (needsWrite) {
        // Synchronously write as we are taking permissions away.
        if (writeRuntimePermissions) {
            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
        }
        // Synchronously write as we are taking permissions away.
        if (writeInstallPermissions) {
            mSettings.writeLPr();
        }
    }
    /**
+33 −22
Original line number Diff line number Diff line
@@ -824,14 +824,8 @@ final class Settings {
                continue;
            }

            // If no user has the permission, nothing to remove.
            if (!sus.getPermissionsState().hasPermission(bp.name, userId)) {
                 continue;
            }

            boolean used = false;

            // Check if another package in the shared user needs the permission.
            boolean used = false;
            for (PackageSetting pkg : sus.packages) {
                if (pkg.pkg != null
                        && !pkg.pkg.packageName.equals(deletedPs.pkg.packageName)
@@ -840,9 +834,27 @@ final class Settings {
                    break;
                }
            }
            if (used) {
                continue;
            }

            if (!used) {
            PermissionsState permissionsState = sus.getPermissionsState();
            PackageSetting disabledPs = getDisabledSystemPkgLPr(deletedPs.pkg.packageName);

            // If the package is shadowing is a disabled system package,
            // do not drop permissions that the shadowed package requests.
            if (disabledPs != null) {
                boolean reqByDisabledSysPkg = false;
                for (String permission : disabledPs.pkg.requestedPermissions) {
                    if (permission.equals(eachPerm)) {
                        reqByDisabledSysPkg = true;
                        break;
                    }
                }
                if (reqByDisabledSysPkg) {
                    continue;
                }
            }

            // Try to revoke as an install permission which is for all users.
            // The package is gone - no need to keep flags for applying policy.
@@ -860,7 +872,6 @@ final class Settings {
                return userId;
            }
        }
        }

        return UserHandle.USER_NULL;
    }