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

Commit a1111ffe authored by Nikita Ioffe's avatar Nikita Ioffe
Browse files

Allow RollbackManager to downgrade apks on user builds

- If running on a debug build, same behaviour is preserved.
- In case of a user build, INSTALL_ALLOW_DOWNGRADE flag is respected
  only if it's system_server who commits the session.

Test: atest RollbackTest on user build
Test: manually tried to downgrade apk on a user build, it failed.
Bug: 125657835
Change-Id: I469f6513831cc727fc7e62ce1ff4f6ef472ab5e9
parent c20b41f5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1343,6 +1343,7 @@ public class PackageInstaller {
         */
        public boolean areHiddenOptionsSet() {
            return (installFlags & (PackageManager.INSTALL_ALLOW_DOWNGRADE
                    | PackageManager.INSTALL_RESPECT_ALLOW_DOWNGRADE
                    | PackageManager.INSTALL_DONT_KILL_APP
                    | PackageManager.INSTALL_INSTANT_APP
                    | PackageManager.INSTALL_FULL_APP
+10 −0
Original line number Diff line number Diff line
@@ -721,6 +721,7 @@ public abstract class PackageManager {
            INSTALL_VIRTUAL_PRELOAD,
            INSTALL_APEX,
            INSTALL_ENABLE_ROLLBACK,
            INSTALL_RESPECT_ALLOW_DOWNGRADE,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface InstallFlags {}
@@ -865,6 +866,15 @@ public abstract class PackageManager {
     */
    public static final int INSTALL_DISABLE_VERIFICATION = 0x00080000;

    /**
     * Flag parameter for {@link #installPackage} to indicate that
     * {@link #INSTALL_ALLOW_DOWNGRADE} should be respected.
     *
     * @hide
     */
    // TODO(b/127322579): rename
    public static final int INSTALL_RESPECT_ALLOW_DOWNGRADE = 0x00100000;

    /** @hide */
    @IntDef(flag = true, prefix = { "DONT_KILL_APP" }, value = {
            DONT_KILL_APP
+6 −0
Original line number Diff line number Diff line
@@ -481,6 +481,12 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
            }
        }

        if (callingUid == Process.SYSTEM_UID) {
            params.installFlags |= PackageManager.INSTALL_RESPECT_ALLOW_DOWNGRADE;
        } else {
            params.installFlags &= ~PackageManager.INSTALL_RESPECT_ALLOW_DOWNGRADE;
        }

        boolean isApex = (params.installFlags & PackageManager.INSTALL_APEX) != 0;
        if (params.isStaged || isApex) {
            mContext.enforceCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES, TAG);
+14 −5
Original line number Diff line number Diff line
@@ -806,7 +806,7 @@ public class PackageManagerServiceUtils {
     */
    public static boolean isDowngradePermitted(int installFlags, int applicationFlags) {
        // If installed, the package will get access to data left on the device by its
        // predecessor. As a security measure, this is permited only if this is not a
        // predecessor. As a security measure, this is permitted only if this is not a
        // version downgrade or if the predecessor package is marked as debuggable and
        // a downgrade is explicitly requested.
        //
@@ -818,12 +818,21 @@ public class PackageManagerServiceUtils {
        // installFlags. This is because we aim to keep the behavior of debuggable
        // platform builds as close as possible to the behavior of non-debuggable
        // platform builds.
        //
        // In case of user builds, downgrade is permitted only for the system server initiated
        // sessions. This is enforced by INSTALL_RESPECT_ALLOW_DOWNGRADE flag parameter.
        final boolean downgradeRequested =
                (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
        final boolean packageDebuggable =
                (applicationFlags
                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
        return (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
        if (!downgradeRequested) {
            return false;
        }
        final boolean isDebuggable =
                Build.IS_DEBUGGABLE || ((applicationFlags
                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
        if (isDebuggable) {
            return true;
        }
        return (installFlags & PackageManager.INSTALL_RESPECT_ALLOW_DOWNGRADE) != 0;
    }

    /**