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

Commit 8dce4771 authored by Alex Buynytskyy's avatar Alex Buynytskyy
Browse files

Support for multiple required verifiers.

Bug: 171907685
Test: atest PackageManagerShellCommandTest PackageManagerShellCommandMultiUserTest PackageVerificationStateTest
Change-Id: I7502b4998353951ee36f1569004c5bbb2e7a6f68
parent 78c33bb4
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -816,10 +816,11 @@ final class DeletePackageHelper {
        }

        // Allow package verifier to silently uninstall.
        if (mPm.mRequiredVerifierPackage != null && callingUid == snapshot
                .getPackageUid(mPm.mRequiredVerifierPackage, 0, callingUserId)) {
        for (String verifierPackageName : mPm.mRequiredVerifierPackages) {
            if (callingUid == snapshot.getPackageUid(verifierPackageName, 0, callingUserId)) {
                return true;
            }
        }

        // Allow package uninstaller to silently uninstall.
        if (mPm.mRequiredUninstallerPackage != null && callingUid == snapshot
+34 −30
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ final class DumpHelper {
    private final StorageEventHelper mStorageEventHelper;
    private final DomainVerificationManagerInternal mDomainVerificationManager;
    private final PackageInstallerService mInstallerService;
    private final String mRequiredVerifierPackage;
    private final String[] mRequiredVerifierPackages;
    private final KnownPackages mKnownPackages;
    private final ChangedPackagesTracker mChangedPackagesTracker;
    private final ArrayMap<String, FeatureInfo> mAvailableFeatures;
@@ -65,7 +65,7 @@ final class DumpHelper {
            PermissionManagerServiceInternal permissionManager,
            StorageEventHelper storageEventHelper,
            DomainVerificationManagerInternal domainVerificationManager,
            PackageInstallerService installerService, String requiredVerifierPackage,
            PackageInstallerService installerService, String[] requiredVerifierPackages,
            KnownPackages knownPackages,
            ChangedPackagesTracker changedPackagesTracker,
            ArrayMap<String, FeatureInfo> availableFeatures,
@@ -75,7 +75,7 @@ final class DumpHelper {
        mStorageEventHelper = storageEventHelper;
        mDomainVerificationManager = domainVerificationManager;
        mInstallerService = installerService;
        mRequiredVerifierPackage = requiredVerifierPackage;
        mRequiredVerifierPackages = requiredVerifierPackages;
        mKnownPackages = knownPackages;
        mChangedPackagesTracker = changedPackagesTracker;
        mAvailableFeatures = availableFeatures;
@@ -313,21 +313,22 @@ final class DumpHelper {
            ipw.decreaseIndent();
        }

        if (dumpState.isDumping(DumpState.DUMP_VERIFIERS)
                && packageName == null) {
            final String requiredVerifierPackage = mRequiredVerifierPackage;
            if (!checkin) {
        if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
            if (!checkin && mRequiredVerifierPackages.length > 0) {
                if (dumpState.onTitlePrinted()) {
                    pw.println();
                }
                pw.println("Verifiers:");
            }
            for (String requiredVerifierPackage : mRequiredVerifierPackages) {
                if (!checkin) {
                    pw.print("  Required: ");
                    pw.print(requiredVerifierPackage);
                    pw.print(" (uid=");
                    pw.print(snapshot.getPackageUid(requiredVerifierPackage,
                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM));
                    pw.println(")");
            } else if (requiredVerifierPackage != null) {
                } else {
                    pw.print("vrfy,");
                    pw.print(requiredVerifierPackage);
                    pw.print(",");
@@ -335,6 +336,7 @@ final class DumpHelper {
                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM));
                }
            }
        }

        if (dumpState.isDumping(DumpState.DUMP_DOMAIN_VERIFIER)
                && packageName == null) {
@@ -642,17 +644,19 @@ final class DumpHelper {
    private void dumpProto(Computer snapshot, FileDescriptor fd) {
        final ProtoOutputStream proto = new ProtoOutputStream(fd);

        for (String requiredVerifierPackage : mRequiredVerifierPackages) {
            final long requiredVerifierPackageToken =
                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
            proto.write(PackageServiceDumpProto.PackageShortProto.NAME,
                mRequiredVerifierPackage);
                    requiredVerifierPackage);
            proto.write(
                    PackageServiceDumpProto.PackageShortProto.UID,
                    snapshot.getPackageUid(
                        mRequiredVerifierPackage,
                            requiredVerifierPackage,
                            MATCH_DEBUG_TRIAGED_MISSING,
                            UserHandle.USER_SYSTEM));
            proto.end(requiredVerifierPackageToken);
        }

        DomainVerificationProxy proxy = mDomainVerificationManager.getProxy();
        ComponentName verifierComponent = proxy.getComponentName();
+18 −15
Original line number Diff line number Diff line
@@ -2719,15 +2719,16 @@ final class InstallPackageHelper {
                            installerPackageName, null /*finishedReceiver*/,
                            updateUserIds, instantUserIds, null /* broadcastAllowList */, null);
                }
                // if the required verifier is defined, but, is not the installer of record
                // for the package, it gets notified
                final boolean notifyVerifier = mPm.mRequiredVerifierPackage != null
                        && !mPm.mRequiredVerifierPackage.equals(installerPackageName);
                if (notifyVerifier) {
                // Notify required verifier(s) that are not the installer of record for the package.
                for (String verifierPackageName : mPm.mRequiredVerifierPackages) {
                    if (verifierPackageName != null && !verifierPackageName.equals(
                            installerPackageName)) {
                        mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
                                extras, 0 /*flags*/,
                            mPm.mRequiredVerifierPackage, null /*finishedReceiver*/,
                            updateUserIds, instantUserIds, null /* broadcastAllowList */, null);
                                verifierPackageName, null /*finishedReceiver*/,
                                updateUserIds, instantUserIds, null /* broadcastAllowList */,
                                null);
                    }
                }
                // If package installer is defined, notify package installer about new
                // app installed
@@ -2752,12 +2753,14 @@ final class InstallPackageHelper {
                                updateUserIds, instantUserIds, null /*broadcastAllowList*/,
                                null);
                    }
                    if (notifyVerifier) {
                        mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
                                extras, 0 /*flags*/,
                                mPm.mRequiredVerifierPackage, null /*finishedReceiver*/,
                                updateUserIds, instantUserIds, null /*broadcastAllowList*/,
                                null);
                    for (String verifierPackageName : mPm.mRequiredVerifierPackages) {
                        if (verifierPackageName != null && !verifierPackageName.equals(
                                installerPackageName)) {
                            mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
                                    packageName, extras, 0 /*flags*/, verifierPackageName,
                                    null /*finishedReceiver*/, updateUserIds, instantUserIds,
                                    null /*broadcastAllowList*/, null);
                        }
                    }
                    mPm.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
                            null /*package*/, null /*extras*/, 0 /*flags*/,
+4 −4
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ public final class KnownPackages {
    private final String mRequiredInstallerPackage;
    private final String mRequiredUninstallerPackage;
    private final String mSetupWizardPackage;
    private final String mRequiredVerifierPackage;
    private final String[] mRequiredVerifierPackages;
    private final String mDefaultTextClassifierPackage;
    private final String mSystemTextClassifierPackageName;
    private final String mRequiredPermissionControllerPackage;
@@ -94,7 +94,7 @@ public final class KnownPackages {

    KnownPackages(DefaultAppProvider defaultAppProvider, String requiredInstallerPackage,
            String requiredUninstallerPackage, String setupWizardPackage,
            String requiredVerifierPackage, String defaultTextClassifierPackage,
            String[] requiredVerifierPackages, String defaultTextClassifierPackage,
            String systemTextClassifierPackageName, String requiredPermissionControllerPackage,
            String configuratorPackage, String incidentReportApproverPackage,
            String ambientContextDetectionPackage, String appPredictionServicePackage,
@@ -104,7 +104,7 @@ public final class KnownPackages {
        mRequiredInstallerPackage = requiredInstallerPackage;
        mRequiredUninstallerPackage = requiredUninstallerPackage;
        mSetupWizardPackage = setupWizardPackage;
        mRequiredVerifierPackage = requiredVerifierPackage;
        mRequiredVerifierPackages = requiredVerifierPackages;
        mDefaultTextClassifierPackage = defaultTextClassifierPackage;
        mSystemTextClassifierPackageName = systemTextClassifierPackageName;
        mRequiredPermissionControllerPackage = requiredPermissionControllerPackage;
@@ -182,7 +182,7 @@ public final class KnownPackages {
            case PACKAGE_SYSTEM:
                return new String[]{"android"};
            case PACKAGE_VERIFIER:
                return snapshot.filterOnlySystemPackages(mRequiredVerifierPackage);
                return snapshot.filterOnlySystemPackages(mRequiredVerifierPackages);
            case PACKAGE_SYSTEM_TEXT_CLASSIFIER:
                return snapshot.filterOnlySystemPackages(
                        mDefaultTextClassifierPackage, mSystemTextClassifierPackageName);
+78 −37
Original line number Diff line number Diff line
@@ -238,6 +238,7 @@ import com.android.server.utils.Watcher;

import dalvik.system.VMRuntime;

import libcore.util.EmptyArray;
import libcore.util.HexEncoding;

import java.io.ByteArrayInputStream;
@@ -521,6 +522,9 @@ public class PackageManagerService implements PackageSender, TestUtilityService

    private static final String COMPANION_PACKAGE_NAME = "com.android.companiondevicemanager";

    // How many required verifiers can be on the system.
    private static final int REQUIRED_VERIFIERS_MAX_COUNT = 2;

    // Compilation reasons.
    public static final int REASON_FIRST_BOOT = 0;
    public static final int REASON_BOOT_AFTER_OTA = 1;
@@ -906,7 +910,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<>();
    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows

    final @Nullable String mRequiredVerifierPackage;
    final @NonNull String[] mRequiredVerifierPackages;
    final @NonNull String mRequiredInstallerPackage;
    final @NonNull String mRequiredUninstallerPackage;
    final @NonNull String mRequiredPermissionControllerPackage;
@@ -1642,7 +1646,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
        mProtectedPackages = testParams.protectedPackages;
        mSeparateProcesses = testParams.separateProcesses;
        mViewCompiler = testParams.viewCompiler;
        mRequiredVerifierPackage = testParams.requiredVerifierPackage;
        mRequiredVerifierPackages = testParams.requiredVerifierPackages;
        mRequiredInstallerPackage = testParams.requiredInstallerPackage;
        mRequiredUninstallerPackage = testParams.requiredUninstallerPackage;
        mRequiredPermissionControllerPackage = testParams.requiredPermissionControllerPackage;
@@ -2126,7 +2130,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
                    SystemClock.uptimeMillis());

            mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr(computer);
            mRequiredVerifierPackages = getRequiredButNotReallyRequiredVerifiersLPr(computer);
            mRequiredInstallerPackage = getRequiredInstallerLPr(computer);
            mRequiredUninstallerPackage = getRequiredUninstallerLPr(computer);
            ComponentName intentFilterVerifierComponent =
@@ -2265,8 +2269,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
                "persist.pm.mock-upgrade", false /* default */);
    }

    @Nullable
    private String getRequiredButNotReallyRequiredVerifierLPr(@NonNull Computer computer) {
    @NonNull
    private String[] getRequiredButNotReallyRequiredVerifiersLPr(@NonNull Computer computer) {
        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);

        final List<ResolveInfo> matches =
@@ -2274,13 +2278,23 @@ public class PackageManagerService implements PackageSender, TestUtilityService
                        PACKAGE_MIME_TYPE,
                        MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
                        UserHandle.USER_SYSTEM, Binder.getCallingUid());
        if (matches.size() == 1) {
            return matches.get(0).getComponentInfo().packageName;
        } else if (matches.size() == 0) {
        final int size = matches.size();
        if (size == 0) {
            Log.w(TAG, "There should probably be a verifier, but, none were found");
            return null;
            return EmptyArray.STRING;
        } else if (size <= REQUIRED_VERIFIERS_MAX_COUNT) {
            String[] verifiers = new String[size];
            for (int i = 0; i < size; ++i) {
                verifiers[i] = matches.get(i).getComponentInfo().packageName;
                if (TextUtils.isEmpty(verifiers[i])) {
                    throw new RuntimeException("Invalid verifier: " + matches);
                }
            }
            return verifiers;
        }
        throw new RuntimeException("There must be exactly one verifier; found " + matches);
        throw new RuntimeException(
                "There must be no more than " + REQUIRED_VERIFIERS_MAX_COUNT + " verifiers; found "
                        + matches);
    }

    @NonNull
@@ -3153,8 +3167,12 @@ public class PackageManagerService implements PackageSender, TestUtilityService

    boolean isCallerVerifier(@NonNull Computer snapshot, int callingUid) {
        final int callingUserId = UserHandle.getUserId(callingUid);
        return mRequiredVerifierPackage != null && callingUid == snapshot.getPackageUid(
                mRequiredVerifierPackage, 0, callingUserId);
        for (String requiredVerifierPackage : mRequiredVerifierPackages) {
            if (callingUid == snapshot.getPackageUid(requiredVerifierPackage, 0, callingUserId)) {
                return true;
            }
        }
        return false;
    }

    public boolean isPackageDeviceAdminOnAnyUser(@NonNull Computer snapshot, String packageName) {
@@ -4665,15 +4683,28 @@ public class PackageManagerService implements PackageSender, TestUtilityService
        }

        @Override
        public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
        public void extendVerificationTimeout(int verificationId, int verificationCodeAtTimeout,
                long millisecondsToDelay) {
            // Negative ids correspond to testing verifiers and will be silently enforced in
            // the handler thread.
            if (verificationId >= 0) {
                mContext.enforceCallingOrSelfPermission(
                        Manifest.permission.PACKAGE_VERIFICATION_AGENT,
                        "Only package verification agents can extend verification timeouts");
            }
            final int callingUid = Binder.getCallingUid();

            mHandler.post(() -> {
                final int id = verificationId >= 0 ? verificationId : -verificationId;
                final PackageVerificationState state = mPendingVerification.get(id);
                if (state == null || state.timeoutExtended() || !state.checkRequiredVerifierUid(
                        callingUid)) {
                    // Only allow calls from required verifiers.
                    return;
                }

                state.extendTimeout();

                final PackageVerificationResponse response = new PackageVerificationResponse(
                        verificationCodeAtTimeout, callingUid);

@@ -4685,14 +4716,10 @@ public class PackageManagerService implements PackageSender, TestUtilityService
                    delay = 0;
                }

                if ((state != null) && !state.timeoutExtended()) {
                    state.extendTimeout();

                final Message msg = mHandler.obtainMessage(PackageManagerService.PACKAGE_VERIFIED);
                msg.arg1 = id;
                msg.obj = response;
                mHandler.sendMessageDelayed(msg, delay);
                }
            });
        }

@@ -5862,18 +5889,32 @@ public class PackageManagerService implements PackageSender, TestUtilityService
        }

        @Override
        public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
        public void verifyPendingInstall(int verificationId, int verificationCode)
                throws RemoteException {
            // Negative ids correspond to testing verifiers and will be silently enforced in
            // the handler thread.
            if (verificationId >= 0) {
                mContext.enforceCallingOrSelfPermission(
                        Manifest.permission.PACKAGE_VERIFICATION_AGENT,
                        "Only package verification agents can verify applications");
            }
            final int callingUid = Binder.getCallingUid();

            mHandler.post(() -> {
                final int id = verificationId >= 0 ? verificationId : -verificationId;
                final PackageVerificationState state = mPendingVerification.get(id);
                if (state == null || !state.checkRequiredVerifierUid(callingUid)) {
                    // Only allow calls from required verifiers.
                    return;
                }

                final Message msg = mHandler.obtainMessage(PackageManagerService.PACKAGE_VERIFIED);
                final PackageVerificationResponse response = new PackageVerificationResponse(
                        verificationCode, callingUid);
                msg.arg1 = id;
                msg.obj = response;
                mHandler.sendMessage(msg);
            });
        }

        @Override
@@ -5928,7 +5969,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
                    mRequiredInstallerPackage,
                    mRequiredUninstallerPackage,
                    mSetupWizardPackage,
                    mRequiredVerifierPackage,
                    mRequiredVerifierPackages,
                    mDefaultTextClassifierPackage,
                    mSystemTextClassifierPackageName,
                    mRequiredPermissionControllerPackage,
@@ -5949,7 +5990,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
                protectedBroadcasts = new ArraySet<>(mProtectedBroadcasts);
            }
            new DumpHelper(mPermissionManager, mStorageEventHelper,
                    mDomainVerificationManager, mInstallerService, mRequiredVerifierPackage,
                    mDomainVerificationManager, mInstallerService, mRequiredVerifierPackages,
                    knownPackages, mChangedPackagesTracker, availableFeatures, protectedBroadcasts,
                    getPerUidReadTimeouts(snapshot)
            ).doDump(snapshot, fd, pw, args);
@@ -6956,7 +6997,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
                mRequiredInstallerPackage,
                mRequiredUninstallerPackage,
                mSetupWizardPackage,
                mRequiredVerifierPackage,
                mRequiredVerifierPackages,
                mDefaultTextClassifierPackage,
                mSystemTextClassifierPackageName,
                mRequiredPermissionControllerPackage,
Loading