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

Commit e7334975 authored by Adam Lesinski's avatar Adam Lesinski
Browse files

PackageManager: allow overlays to be installed when signature matches platform cert

Test: With ag/3486152, run
Test: atest OverlayHostTests
Change-Id: I5ca4b0ca00dc21c4c0adb9a7680d2be866391b2e
parent 262cdf0f
Loading
Loading
Loading
Loading
+6 −29
Original line number Diff line number Diff line
@@ -16,14 +16,10 @@

package android.content.pm;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Overall information about the contents of a package.  This corresponds
 * to all of the information collected from AndroidManifest.xml.
@@ -335,28 +331,9 @@ public class PackageInfo implements Parcelable {
    public int overlayPriority;

    /**
     * Flag for use with {@link #mOverlayFlags}. Marks the overlay as static, meaning it cannot
     * be enabled/disabled at runtime.
     */
    static final int FLAG_OVERLAY_STATIC = 1 << 1;

    /**
     * Flag for use with {@link #mOverlayFlags}. Marks the overlay as trusted (not 3rd party).
     */
    static final int FLAG_OVERLAY_TRUSTED = 1 << 2;

    @IntDef(flag = true, prefix = "FLAG_OVERLAY_", value = {
            FLAG_OVERLAY_STATIC,
            FLAG_OVERLAY_TRUSTED
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface OverlayFlags {}

    /**
     * Modifiers that affect the state of this overlay. See {@link #FLAG_OVERLAY_STATIC},
     * {@link #FLAG_OVERLAY_TRUSTED}.
     * Whether the overlay is static, meaning it cannot be enabled/disabled at runtime.
     */
    @OverlayFlags int mOverlayFlags;
    boolean mOverlayIsStatic;

    /**
     * The user-visible SDK version (ex. 26) of the framework against which the application claims
@@ -389,7 +366,7 @@ public class PackageInfo implements Parcelable {
     * @hide
     */
    public boolean isOverlayPackage() {
        return overlayTarget != null && (mOverlayFlags & FLAG_OVERLAY_TRUSTED) != 0;
        return overlayTarget != null;
    }

    /**
@@ -398,7 +375,7 @@ public class PackageInfo implements Parcelable {
     * @hide
     */
    public boolean isStaticOverlayPackage() {
        return overlayTarget != null && (mOverlayFlags & FLAG_OVERLAY_STATIC) != 0;
        return overlayTarget != null && mOverlayIsStatic;
    }

    @Override
@@ -453,7 +430,7 @@ public class PackageInfo implements Parcelable {
        dest.writeString(requiredAccountType);
        dest.writeString(overlayTarget);
        dest.writeInt(overlayPriority);
        dest.writeInt(mOverlayFlags);
        dest.writeBoolean(mOverlayIsStatic);
        dest.writeInt(compileSdkVersion);
        dest.writeString(compileSdkVersionCodename);
    }
@@ -508,7 +485,7 @@ public class PackageInfo implements Parcelable {
        requiredAccountType = source.readString();
        overlayTarget = source.readString();
        overlayPriority = source.readInt();
        mOverlayFlags = source.readInt();
        mOverlayIsStatic = source.readBoolean();
        compileSdkVersion = source.readInt();
        compileSdkVersionCodename = source.readString();

+5 −16
Original line number Diff line number Diff line
@@ -679,15 +679,7 @@ public class PackageParser {
        pi.requiredAccountType = p.mRequiredAccountType;
        pi.overlayTarget = p.mOverlayTarget;
        pi.overlayPriority = p.mOverlayPriority;

        if (p.mIsStaticOverlay) {
            pi.mOverlayFlags |= PackageInfo.FLAG_OVERLAY_STATIC;
        }

        if (p.mTrustedOverlay) {
            pi.mOverlayFlags |= PackageInfo.FLAG_OVERLAY_TRUSTED;
        }

        pi.mOverlayIsStatic = p.mOverlayIsStatic;
        pi.compileSdkVersion = p.mCompileSdkVersion;
        pi.compileSdkVersionCodename = p.mCompileSdkVersionCodename;
        pi.firstInstallTime = firstInstallTime;
@@ -2058,7 +2050,7 @@ public class PackageParser {
                pkg.mOverlayPriority = sa.getInt(
                        com.android.internal.R.styleable.AndroidManifestResourceOverlay_priority,
                        0);
                pkg.mIsStaticOverlay = sa.getBoolean(
                pkg.mOverlayIsStatic = sa.getBoolean(
                        com.android.internal.R.styleable.AndroidManifestResourceOverlay_isStatic,
                        false);
                final String propName = sa.getString(
@@ -6062,8 +6054,7 @@ public class PackageParser {

        public String mOverlayTarget;
        public int mOverlayPriority;
        public boolean mIsStaticOverlay;
        public boolean mTrustedOverlay;
        public boolean mOverlayIsStatic;

        public int mCompileSdkVersion;
        public String mCompileSdkVersionCodename;
@@ -6593,8 +6584,7 @@ public class PackageParser {
            mRequiredAccountType = dest.readString();
            mOverlayTarget = dest.readString();
            mOverlayPriority = dest.readInt();
            mIsStaticOverlay = (dest.readInt() == 1);
            mTrustedOverlay = (dest.readInt() == 1);
            mOverlayIsStatic = (dest.readInt() == 1);
            mCompileSdkVersion = dest.readInt();
            mCompileSdkVersionCodename = dest.readString();
            mUpgradeKeySets = (ArraySet<String>) dest.readArraySet(boot);
@@ -6717,8 +6707,7 @@ public class PackageParser {
            dest.writeString(mRequiredAccountType);
            dest.writeString(mOverlayTarget);
            dest.writeInt(mOverlayPriority);
            dest.writeInt(mIsStaticOverlay ? 1 : 0);
            dest.writeInt(mTrustedOverlay ? 1 : 0);
            dest.writeInt(mOverlayIsStatic ? 1 : 0);
            dest.writeInt(mCompileSdkVersion);
            dest.writeString(mCompileSdkVersionCodename);
            dest.writeArraySet(mUpgradeKeySets);
+55 −8
Original line number Diff line number Diff line
@@ -50,11 +50,9 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_L
import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
import static android.content.pm.PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE;
import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
import static android.content.pm.PackageManager.INSTALL_INTERNAL;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
@@ -446,7 +444,6 @@ public class PackageManagerService extends IPackageManager.Stub
    static final int SCAN_NEW_INSTALL = 1<<2;
    static final int SCAN_UPDATE_TIME = 1<<3;
    static final int SCAN_BOOTING = 1<<4;
    static final int SCAN_TRUSTED_OVERLAY = 1<<5;
    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<6;
    static final int SCAN_REQUIRE_KNOWN = 1<<7;
    static final int SCAN_MOVE = 1<<8;
@@ -469,7 +466,6 @@ public class PackageManagerService extends IPackageManager.Stub
            SCAN_NEW_INSTALL,
            SCAN_UPDATE_TIME,
            SCAN_BOOTING,
            SCAN_TRUSTED_OVERLAY,
            SCAN_DELETE_DATA_ON_FAILURES,
            SCAN_REQUIRE_KNOWN,
            SCAN_MOVE,
@@ -772,7 +768,7 @@ public class PackageManagerService extends IPackageManager.Stub
                Collection<PackageParser.Package> allPackages, String targetPackageName) {
            List<PackageParser.Package> overlayPackages = null;
            for (PackageParser.Package p : allPackages) {
                if (targetPackageName.equals(p.mOverlayTarget) && p.mIsStaticOverlay) {
                if (targetPackageName.equals(p.mOverlayTarget) && p.mOverlayIsStatic) {
                    if (overlayPackages == null) {
                        overlayPackages = new ArrayList<PackageParser.Package>();
                    }
@@ -856,7 +852,7 @@ public class PackageManagerService extends IPackageManager.Stub
        void findStaticOverlayPackages() {
            synchronized (mPackages) {
                for (PackageParser.Package p : mPackages.values()) {
                    if (p.mIsStaticOverlay) {
                    if (p.mOverlayIsStatic) {
                        if (mOverlayPackages == null) {
                            mOverlayPackages = new ArrayList<PackageParser.Package>();
                        }
@@ -2556,7 +2552,7 @@ public class PackageManagerService extends IPackageManager.Stub
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_TRUSTED_OVERLAY,
                    | SCAN_AS_VENDOR,
                    0);
            mParallelPackageParserCallback.findStaticOverlayPackages();
@@ -10520,7 +10516,6 @@ Slog.e("TODD",
                }
            }
        }
        pkg.mTrustedOverlay = (scanFlags & SCAN_TRUSTED_OVERLAY) != 0;
        if ((scanFlags & SCAN_AS_PRIVILEGED) != 0) {
            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
@@ -10542,6 +10537,14 @@ Slog.e("TODD",
        }
    }
    private static @NonNull <T> T assertNotNull(@Nullable T object, String message)
            throws PackageManagerException {
        if (object == null) {
            throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, message);
        }
        return object;
    }
    /**
     * Asserts the parsed package is valid according to the given policy. If the
     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
@@ -10815,6 +10818,50 @@ Slog.e("TODD",
                    }
                }
            }
            // Apply policies specific for runtime resource overlays (RROs).
            if (pkg.mOverlayTarget != null) {
                // System overlays have some restrictions on their use of the 'static' state.
                if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
                    // We are scanning a system overlay. This can be the first scan of the
                    // system/vendor/oem partition, or an update to the system overlay.
                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
                        // This must be an update to a system overlay.
                        final PackageSetting previousPkg = assertNotNull(
                                mSettings.getPackageLPr(pkg.packageName),
                                "previous package state not present");
                        // Static overlays cannot be updated.
                        if (previousPkg.pkg.mOverlayIsStatic) {
                            throw new PackageManagerException("Overlay " + pkg.packageName +
                                    " is static and cannot be upgraded.");
                        // Non-static overlays cannot be converted to static overlays.
                        } else if (pkg.mOverlayIsStatic) {
                            throw new PackageManagerException("Overlay " + pkg.packageName +
                                    " cannot be upgraded into a static overlay.");
                        }
                    }
                } else {
                    // The overlay is a non-system overlay. Non-system overlays cannot be static.
                    if (pkg.mOverlayIsStatic) {
                        throw new PackageManagerException("Overlay " + pkg.packageName +
                                " is static but not pre-installed.");
                    }
                    // The only case where we allow installation of a non-system overlay is when
                    // its signature is signed with the platform certificate.
                    PackageSetting platformPkgSetting = mSettings.getPackageLPr("android");
                    if ((platformPkgSetting.signatures.mSigningDetails
                            != PackageParser.SigningDetails.UNKNOWN)
                            && (compareSignatures(
                                    platformPkgSetting.signatures.mSigningDetails.signatures,
                                    pkg.mSigningDetails.signatures)
                                            != PackageManager.SIGNATURE_MATCH)) {
                        throw new PackageManagerException("Overlay " + pkg.packageName +
                                " must be signed with the platform certificate.");
                    }
                }
            }
        }
    }
+0 −2
Original line number Diff line number Diff line
@@ -195,7 +195,6 @@ public class PackageParserTest {
        assertEquals(a.installLocation, b.installLocation);
        assertEquals(a.coreApp, b.coreApp);
        assertEquals(a.mRequiredForAllUsers, b.mRequiredForAllUsers);
        assertEquals(a.mTrustedOverlay, b.mTrustedOverlay);
        assertEquals(a.mCompileSdkVersion, b.mCompileSdkVersion);
        assertEquals(a.mCompileSdkVersionCodename, b.mCompileSdkVersionCodename);
        assertEquals(a.use32bitAbi, b.use32bitAbi);
@@ -429,7 +428,6 @@ public class PackageParserTest {
        pkg.installLocation = 100;
        pkg.coreApp = true;
        pkg.mRequiredForAllUsers = true;
        pkg.mTrustedOverlay = true;
        pkg.use32bitAbi = true;
        pkg.packageName = "foo";
        pkg.splitNames = new String[] { "foo2" };