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

Commit 724150d8 authored by Philip P. Moltmann's avatar Philip P. Moltmann
Browse files

Don't check pkg<->uid when called from internal

The PermissionManagerService calls AppOpsService before the package
manager is up. Hence AppOpsService cannot verify package properties.
This is not needed in the calls from PermissionManagerService as this
component can be trusted to provide correct data.

Fixes: 127470436
Test: Upgraded from P->Q with a pre-M installed
Change-Id: Ide529f13ab2cc3b7551e99c94935c0cb537a817b
parent e756f460
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.app;

import android.annotation.NonNull;
import android.util.SparseIntArray;

import com.android.internal.util.function.QuadFunction;
@@ -96,4 +97,18 @@ public abstract class AppOpsManagerInternal {
     * @param uid The uid
     */
    public abstract void setAllPkgModesToDefault(int code, int uid);

    /**
     * Get the (raw) mode of an app-op.
     *
     * <p>Does <u>not</u> verify that package belongs to uid. The caller needs to do that.
     *
     * @param code The code of the op
     * @param uid The uid of the package the op belongs to
     * @param packageName The package the op belongs to
     *
     * @return The mode of the op
     */
    public abstract @AppOpsManager.Mode int checkOperationUnchecked(int code, int uid,
            @NonNull String packageName);
}
+31 −5
Original line number Diff line number Diff line
@@ -1742,10 +1742,31 @@ public class AppOpsService extends IAppOpsService.Stub {
        return checkOperationUnchecked(code, uid, resolvedPackageName, raw);
    }

    private int checkOperationUnchecked(int code, int uid, String packageName,
    /**
     * @see #checkOperationUnchecked(int, int, String, boolean, boolean)
     */
    private @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName,
            boolean raw) {
        return checkOperationUnchecked(code, uid, packageName, raw, true);
    }

    /**
     * Get the mode of an app-op.
     *
     * @param code The code of the op
     * @param uid The uid of the package the op belongs to
     * @param packageName The package the op belongs to
     * @param raw If the raw state of eval-ed state should be checked.
     * @param verify If the code should check the package belongs to the uid
     *
     * @return The mode of the op
     */
    private @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName,
                boolean raw, boolean verify) {
        synchronized (this) {
            if (verify) {
                checkPackage(uid, packageName);
            }
            if (isOpRestrictedLocked(uid, code, packageName)) {
                return AppOpsManager.MODE_IGNORED;
            }
@@ -1756,7 +1777,7 @@ public class AppOpsService extends IAppOpsService.Stub {
                final int rawMode = uidState.opModes.get(code);
                return raw ? rawMode : uidState.evalMode(code, rawMode);
            }
            Op op = getOpLocked(code, uid, packageName, false, true, false);
            Op op = getOpLocked(code, uid, packageName, false, verify, false);
            if (op == null) {
                return AppOpsManager.opToDefaultMode(code);
            }
@@ -2359,7 +2380,7 @@ public class AppOpsService extends IAppOpsService.Stub {
        throw new IllegalArgumentException("Bad operation #" + op);
    }

    private @NonNull UidState getUidStateLocked(int uid, boolean edit) {
    private @Nullable UidState getUidStateLocked(int uid, boolean edit) {
        UidState uidState = mUidStates.get(uid);
        if (uidState == null) {
            if (!edit) {
@@ -4535,5 +4556,10 @@ public class AppOpsService extends IAppOpsService.Stub {
        public void setAllPkgModesToDefault(int code, int uid) {
            AppOpsService.this.setAllPkgModesToDefault(code, uid);
        }

        @Override
        public @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName) {
            return AppOpsService.this.checkOperationUnchecked(code, uid, packageName, true, false);
        }
    }
}
+4 −4
Original line number Diff line number Diff line
@@ -1273,7 +1273,7 @@ public class PermissionManagerService {
            @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
            @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
            @UserIdInt int userId) {
        AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
        AppOpsManagerInternal appOpsManager = LocalServices.getService(AppOpsManagerInternal.class);
        String pkgName = pkg.packageName;

        if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
@@ -1287,10 +1287,10 @@ public class PermissionManagerService {
                    String sourcePerm = sourcePerms.valueAt(i);

                    if (ps.hasRuntimePermission(sourcePerm, userId)) {
                        String sourceOp = permissionToOp(sourcePerm);
                        int sourceOp = permissionToOpCode(sourcePerm);

                        if (sourceOp != null) {
                            int mode = appOpsManager.unsafeCheckOpRaw(sourceOp,
                        if (sourceOp != OP_NONE) {
                            int mode = appOpsManager.checkOperationUnchecked(sourceOp,
                                    getUid(userId, getAppId(pkg.applicationInfo.uid)), pkgName);

                            if (mode == MODE_FOREGROUND || mode == MODE_ERRORED) {