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

Commit 7d2ddf03 authored by Svetoslav Ganov's avatar Svetoslav Ganov Committed by Android (Google) Code Review
Browse files

Merge "Don't drop restricted permissions on upgrade"

parents 368b4acf 3c499ea9
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -313,6 +313,8 @@ import com.android.server.pm.permission.BasePermission;
import com.android.server.pm.permission.PermissionManagerService;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.pm.permission.PermissionsState;
import com.android.server.policy.PermissionPolicyInternal;
import com.android.server.policy.PermissionPolicyInternal.OnInitializedCallback;
import com.android.server.security.VerityUtils;
import com.android.server.storage.DeviceStorageMonitorInternal;
import com.android.server.utils.TimingsTraceAndSlog;
@@ -20273,6 +20275,16 @@ public class PackageManagerService extends IPackageManager.Stub
        // try optimizing this.
        synchronized (mLock) {
            mPermissionManager.updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, false);
            final PermissionPolicyInternal permissionPolicyInternal =
                    LocalServices.getService(PermissionPolicyInternal.class);
            permissionPolicyInternal.setOnInitializedCallback(userId -> {
                // The SDK updated case is already handled when we run during the ctor.
                synchronized (mPackages) {
                    mPermissionManager.updateAllPermissions(
                            StorageManager.UUID_PRIVATE_INTERNAL, false);
                }
            });
        }
        // Watch for external volumes that come and go over time
+15 −1
Original line number Diff line number Diff line
@@ -1170,6 +1170,11 @@ public final class DefaultPermissionGrantPolicy {
                final int flags = mContext.getPackageManager().getPermissionFlags(
                        permission, pkg.packageName, user);

                // If we are trying to grant as system fixed and already system fixed
                // then the system can change the system fixed grant state.
                final boolean changingGrantForSystemFixed = systemFixed
                        && (flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0;

                // Certain flags imply that the permission's current state by the system or
                // device/profile owner or the user. In these cases we do not want to clobber the
                // current state.
@@ -1177,7 +1182,8 @@ public final class DefaultPermissionGrantPolicy {
                // Unless the caller wants to override user choices. The override is
                // to make sure we can grant the needed permission to the default
                // sms and phone apps after the user chooses this in the UI.
                if (!isFixedOrUserSet(flags) || ignoreSystemPackage) {
                if (!isFixedOrUserSet(flags) || ignoreSystemPackage
                        || changingGrantForSystemFixed) {
                    // Never clobber policy fixed permissions.
                    // We must allow the grant of a system-fixed permission because
                    // system-fixed is sticky, but the permission itself may be revoked.
@@ -1196,6 +1202,14 @@ public final class DefaultPermissionGrantPolicy {
                                PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT, user);
                    }

                    // If the system tries to change a system fixed permission from one fixed
                    // state to another we need to drop the fixed flag to allow the grant.
                    if (changingGrantForSystemFixed) {
                        mContext.getPackageManager().updatePermissionFlags(permission,
                                pkg.packageName, flags,
                                flags & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, user);
                    }

                    if (pm.checkPermission(permission, pkg.packageName)
                            != PackageManager.PERMISSION_GRANTED) {
                        mContext.getPackageManager()
+51 −32
Original line number Diff line number Diff line
@@ -125,6 +125,7 @@ import com.android.server.pm.permission.PermissionManagerServiceInternal.Default
import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultHomeProvider;
import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
import com.android.server.pm.permission.PermissionsState.PermissionState;
import com.android.server.policy.PermissionPolicyInternal;
import com.android.server.policy.SoftRestrictedPermissionPolicy;

import libcore.util.EmptyArray;
@@ -227,6 +228,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
    @GuardedBy("mLock")
    private boolean mSystemReady;

    @GuardedBy("mLock")
    private PermissionPolicyInternal mPermissionPolicyInternal;

    /**
     * For each foreground/background permission the mapping:
     * Background permission -> foreground permissions
@@ -2443,6 +2447,13 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                            boolean softRestricted = bp.isSoftRestricted();

                            for (int userId : currentUserIds) {
                                // If permission policy is not ready we don't deal with restricted
                                // permissions as the policy may whitelist some permissions. Once
                                // the policy is initialized we would re-evaluate permissions.
                                final boolean permissionPolicyInitialized =
                                        mPermissionPolicyInternal != null
                                                && mPermissionPolicyInternal.isInitialized(userId);

                                PermissionState permState = origPermissions
                                        .getRuntimePermissionState(perm, userId);
                                int flags = permState != null ? permState.getFlags() : 0;
@@ -2457,7 +2468,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {

                                if (appSupportsRuntimePermissions) {
                                    // If hard restricted we don't allow holding it
                                    if (hardRestricted) {
                                    if (permissionPolicyInitialized && hardRestricted) {
                                        if (!restrictionExempt) {
                                            if (permState != null && permState.isGranted()
                                                    && permissionsState.revokeRuntimePermission(
@@ -2470,7 +2481,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                                            }
                                        }
                                    // If soft restricted we allow holding in a restricted form
                                    } else if (softRestricted) {
                                    } else if (permissionPolicyInitialized && softRestricted) {
                                        // Regardless if granted set the restriction flag as it
                                        // may affect app treatment based on this permission.
                                        if (!restrictionExempt && !restrictionApplied) {
@@ -2489,7 +2500,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                                        flags &= ~FLAG_PERMISSION_REVOKE_ON_UPGRADE;
                                        wasChanged = true;
                                    // Hard restricted permissions cannot be held.
                                    } else if (!hardRestricted || restrictionExempt) {
                                    } else if (!permissionPolicyInitialized
                                            || (!hardRestricted || restrictionExempt)) {
                                        if (permState != null && permState.isGranted()) {
                                            if (permissionsState.grantRuntimePermission(bp, userId)
                                                    == PERMISSION_OPERATION_FAILURE) {
@@ -2518,7 +2530,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {

                                    // If legacy app always grant the permission but if restricted
                                    // and not exempt take a note a restriction should be applied.
                                    if ((hardRestricted || softRestricted)
                                    if (permissionPolicyInitialized
                                            && (hardRestricted || softRestricted)
                                                    && !restrictionExempt && !restrictionApplied) {
                                        flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
                                        wasChanged = true;
@@ -2526,23 +2539,17 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                                }

                                // If unrestricted or restriction exempt, don't apply restriction.
                                if (permissionPolicyInitialized) {
                                    if (!(hardRestricted || softRestricted) || restrictionExempt) {
                                        if (restrictionApplied) {
                                            flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
                                        // Dropping restriction on a legacy app requires a review.
                                            // Dropping restriction on a legacy app implies a review
                                            if (!appSupportsRuntimePermissions) {
                                                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
                                            }
                                            wasChanged = true;
                                        }
                                    }

                                if (hardRestricted && !restrictionExempt
                                        && (flags & FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
                                    // Applying a hard restriction implies revoking it. This might
                                    // lead to a system-fixed, revoked permission.
                                    flags &= ~FLAG_PERMISSION_SYSTEM_FIXED;
                                    wasChanged = true;
                                }

                                if (wasChanged) {
@@ -2579,6 +2586,13 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                            boolean softRestricted = bp.isSoftRestricted();

                            for (int userId : currentUserIds) {
                                // If permission policy is not ready we don't deal with restricted
                                // permissions as the policy may whitelist some permissions. Once
                                // the policy is initialized we would re-evaluate permissions.
                                final boolean permissionPolicyInitialized =
                                        mPermissionPolicyInternal != null
                                                && mPermissionPolicyInternal.isInitialized(userId);

                                boolean wasChanged = false;

                                boolean restrictionExempt =
@@ -2589,7 +2603,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {

                                if (appSupportsRuntimePermissions) {
                                    // If hard restricted we don't allow holding it
                                    if (hardRestricted) {
                                    if (permissionPolicyInitialized && hardRestricted) {
                                        if (!restrictionExempt) {
                                            if (permState != null && permState.isGranted()
                                                    && permissionsState.revokeRuntimePermission(
@@ -2602,7 +2616,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                                            }
                                        }
                                    // If soft restricted we allow holding in a restricted form
                                    } else if (softRestricted) {
                                    } else if (permissionPolicyInitialized && softRestricted) {
                                        // Regardless if granted set the  restriction flag as it
                                        // may affect app treatment based on this permission.
                                        if (!restrictionExempt && !restrictionApplied) {
@@ -2621,7 +2635,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                                        flags &= ~FLAG_PERMISSION_REVOKE_ON_UPGRADE;
                                        wasChanged = true;
                                    // Hard restricted permissions cannot be held.
                                    } else if (!hardRestricted || restrictionExempt) {
                                    } else if (!permissionPolicyInitialized ||
                                            (!hardRestricted || restrictionExempt)) {
                                        if (permissionsState.grantRuntimePermission(bp, userId) !=
                                                PERMISSION_OPERATION_FAILURE) {
                                             wasChanged = true;
@@ -2637,7 +2652,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {

                                    // If legacy app always grant the permission but if restricted
                                    // and not exempt take a note a restriction should be applied.
                                    if ((hardRestricted || softRestricted)
                                    if (permissionPolicyInitialized
                                            && (hardRestricted || softRestricted)
                                                    && !restrictionExempt && !restrictionApplied) {
                                        flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
                                        wasChanged = true;
@@ -2645,16 +2661,18 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                                }

                                // If unrestricted or restriction exempt, don't apply restriction.
                                if (permissionPolicyInitialized) {
                                    if (!(hardRestricted || softRestricted) || restrictionExempt) {
                                        if (restrictionApplied) {
                                            flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
                                        // Dropping restriction on a legacy app requires a review.
                                            // Dropping restriction on a legacy app implies a review
                                            if (!appSupportsRuntimePermissions) {
                                                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
                                            }
                                            wasChanged = true;
                                        }
                                    }
                                }

                                if (wasChanged) {
                                    updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
@@ -3959,6 +3977,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
        }

        mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
        mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class);

        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
        for (int userId : UserManagerService.getInstance().getUserIds()) {
+27 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.policy;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.Intent;

/**
@@ -25,6 +26,19 @@ import android.content.Intent;
 */
public abstract class PermissionPolicyInternal {

    /**
     * Callback for initializing the permission policy service.
     */
    public interface OnInitializedCallback {

        /**
         * Called when initialized for the given user.
         *
         * @param userId The initialized user.
         */
        void onInitialized(@UserIdInt int userId);
    }

    /**
     * Check whether an activity should be started.
     *
@@ -36,4 +50,17 @@ public abstract class PermissionPolicyInternal {
     */
    public abstract boolean checkStartActivity(@NonNull Intent intent, int callingUid,
            @Nullable String callingPackage);

    /**
     * @return Whether the policy is initialized for a user.
     */
    public abstract boolean isInitialized(@UserIdInt int userId);

    /**
     * Set a callback for users being initialized. If the user is already
     * initialized the callback will not be invoked.
     *
     * @param callback The callback to register.
     */
    public abstract void setOnInitializedCallback(@NonNull OnInitializedCallback callback);
}
+25 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.pm.permission.PermissionManagerServiceInternal;

import com.android.server.policy.PermissionPolicyInternal.OnInitializedCallback;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;

@@ -86,6 +87,10 @@ public final class PermissionPolicyService extends SystemService {
    @GuardedBy("mLock")
    private final SparseBooleanArray mIsStarted = new SparseBooleanArray();

    /** Callbacks for when a user is initialized */
    @GuardedBy("mLock")
    private OnInitializedCallback mOnInitializedCallback;

    /**
     * Whether an async {@link #synchronizePackagePermissionsAndAppOpsForUser} is currently
     * scheduled for a package/user.
@@ -240,12 +245,20 @@ public final class PermissionPolicyService extends SystemService {

        grantOrUpgradeDefaultRuntimePermissionsIfNeeded(userId);

        final OnInitializedCallback callback;

        synchronized (mLock) {
            mIsStarted.put(userId, true);
            callback = mOnInitializedCallback;
        }

        // Force synchronization as permissions might have changed
        synchronizePermissionsAndAppOpsForUser(userId);

        // Tell observers we are initialized for this user.
        if (callback != null) {
            callback.onInitialized(userId);
        }
    }

    @Override
@@ -809,6 +822,18 @@ public final class PermissionPolicyService extends SystemService {
            return true;
        }

        @Override
        public boolean isInitialized(int userId) {
            return isStarted(userId);
        }

        @Override
        public void setOnInitializedCallback(@NonNull OnInitializedCallback callback) {
            synchronized (mLock) {
                mOnInitializedCallback = callback;
            }
        }

        /**
         * Check if the intent action is removed for the calling package (often based on target SDK
         * version). If the action is removed, we'll silently cancel the activity launch.
Loading