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

Commit 0bfcc656 authored by JW Wang's avatar JW Wang
Browse files

Add a one-off shell command to disable verification

The package verification is provided by Play whose behavior
is not controlled by framework. For CTS, such verification
is unnecessary because we have dedicated GTS for that. We add
a shell command to disable verification when installing packages
in CTS to avoid unexpected behavior caused by external entities
to improve stableness of tests.

There is no reduction in safety:
1. This feature is only available to apps with shell
   permissions. Such apps can already skip verification
   by changing a settings value.
2. The command works in a one-off manner. This command
   will only allow the next created session to bypass verification.
   This command requires a uid which prevents accidentally granting
   the ability to other apps.

Bug: 264963480
Test: atest CtsStagedInstallHostTestCases
Change-Id: I26e60837139007e98e99f44aeb0eb13716d91523
parent 18bd9c45
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -65,6 +65,8 @@ interface IPackageInstaller {

    void bypassNextAllowedApexUpdateCheck(boolean value);

    void disableVerificationForUid(int uid);

    void setAllowUnlimitedSilentUpdates(String installerPackageName);
    void setSilentUpdatesThrottleTime(long throttleTimeInSeconds);
    void checkInstallConstraints(String installerPackageName, in List<String> packageNames,
+19 −1
Original line number Diff line number Diff line
@@ -184,6 +184,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
    private volatile boolean mOkToSendBroadcasts = false;
    private volatile boolean mBypassNextStagedInstallerCheck = false;
    private volatile boolean mBypassNextAllowedApexUpdateCheck = false;
    private volatile int mDisableVerificationForUid = INVALID_UID;

    /**
     * File storing persisted {@link #mSessions} metadata.
@@ -712,7 +713,16 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
            params.installFlags &= ~PackageManager.INSTALL_REQUEST_DOWNGRADE;
        }

        if ((params.installFlags & ADB_DEV_MODE) != ADB_DEV_MODE) {
        if (mDisableVerificationForUid != INVALID_UID) {
            if (callingUid == mDisableVerificationForUid) {
                params.installFlags |= PackageManager.INSTALL_DISABLE_VERIFICATION;
            } else {
                // Clear the flag if current calling uid doesn't match the requested uid.
                params.installFlags &= ~PackageManager.INSTALL_DISABLE_VERIFICATION;
            }
            // Reset the field as this is a one-off request.
            mDisableVerificationForUid = INVALID_UID;
        } else if ((params.installFlags & ADB_DEV_MODE) != ADB_DEV_MODE) {
            // Only tools under specific conditions (test app installed through ADB, and
            // verification disabled flag specified) can disable verification.
            params.installFlags &= ~PackageManager.INSTALL_DISABLE_VERIFICATION;
@@ -1367,6 +1377,14 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
        mBypassNextAllowedApexUpdateCheck = value;
    }

    @Override
    public void disableVerificationForUid(int uid) {
        if (!isCalledBySystemOrShell(Binder.getCallingUid())) {
            throw new SecurityException("Operation not allowed for caller");
        }
        mDisableVerificationForUid = uid;
    }

    /**
     * Set an installer to allow for the unlimited silent updates.
     */
+25 −0
Original line number Diff line number Diff line
@@ -342,6 +342,8 @@ class PackageManagerShellCommand extends ShellCommand {
                    return runBypassStagedInstallerCheck();
                case "bypass-allowed-apex-update-check":
                    return runBypassAllowedApexUpdateCheck();
                case "disable-verification-for-uid":
                    return runDisableVerificationForUid();
                case "set-silent-updates-policy":
                    return runSetSilentUpdatesPolicy();
                default: {
@@ -514,6 +516,29 @@ class PackageManagerShellCommand extends ShellCommand {
        }
    }

    private int runDisableVerificationForUid() {
        final PrintWriter pw = getOutPrintWriter();
        try {
            int uid = Integer.parseInt(getNextArgRequired());
            var amInternal = LocalServices.getService(ActivityManagerInternal.class);
            boolean isInstrumented =
                    amInternal.getInstrumentationSourceUid(uid) != Process.INVALID_UID;
            if (isInstrumented) {
                mInterface.getPackageInstaller().disableVerificationForUid(uid);
                return 0;
            } else {
                // Only available for testing
                pw.println("Error: must specify an instrumented uid");
                return -1;
            }
        } catch (RemoteException e) {
            pw.println("Failure ["
                    + e.getClass().getName() + " - "
                    + e.getMessage() + "]");
            return -1;
        }
    }

    private int uninstallSystemUpdates(String packageName) {
        final PrintWriter pw = getOutPrintWriter();
        boolean failedUninstalls = false;
+5 −2
Original line number Diff line number Diff line
@@ -680,12 +680,15 @@ final class VerifyingSession {
        }

        final int installerUid = mVerificationInfo == null ? -1 : mVerificationInfo.mInstallerUid;
        final boolean requestedDisableVerification =
                (mInstallFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0;

        // Check if installing from ADB
        if ((mInstallFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
            boolean requestedDisableVerification =
                    (mInstallFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0;
            return isAdbVerificationEnabled(pkgInfoLite, userId, requestedDisableVerification);
        } else if (requestedDisableVerification) {
            // Skip verification for non-adb installs
            return false;
        }

        // only when not installed from ADB, skip verification for instant apps when