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

Commit 16da32b0 authored by Yifan Hong's avatar Yifan Hong
Browse files

recovery: Delete internal verifyPackageCompatibility.

Non-A/B has been deprecated for long. During non-A/B updates,
compatibility.zip is checked with VintfObject.verify(), which
is another deprecated function that always returns compatible
if a list of package VINTF XMLs are supplied. (see below.) Hence, the private
RecoverySystem.verifyPackageCompatibility was just useless code
that unconditionally returns true except for invalid ZIP file.
Remove it. Replace the public RecoverySystem.verifyPackageCompatibility
and make it return true unconditonally.

VintfObject.verify() with OTA XMLs are deprecated per
http://b/139300422 [VINTF] Delete OTA vintf checking code
in http://r.android.com/1194233 ("Delete VINTF compatibility checks
during OTA."), in 2019. We had decided that compatibility checks
during OTA should be removed, and moved to OTA generation time instead.
Using an old libvintf on the device to check against new libvintf
metadata required forward compatibility of libvintf, which cannot be
achieved. Instead, the device should verify the signature of the OTA to
verify its source.

Test: TH
Bug: 270169217
Bug: 139300422
Change-Id: I775d29e4cd1d165233e07cfb820d1fe343fa4757
parent 31b247f8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -10925,7 +10925,7 @@ package android.os {
    method @RequiresPermission(anyOf={android.Manifest.permission.RECOVERY, android.Manifest.permission.REBOOT}) public static int rebootAndApply(@NonNull android.content.Context, @NonNull String, boolean) throws java.io.IOException;
    method @RequiresPermission(allOf={android.Manifest.permission.RECOVERY, android.Manifest.permission.REBOOT}) public static void rebootWipeAb(android.content.Context, java.io.File, String) throws java.io.IOException;
    method @RequiresPermission(android.Manifest.permission.RECOVERY) public static void scheduleUpdateOnBoot(android.content.Context, java.io.File) throws java.io.IOException;
    method public static boolean verifyPackageCompatibility(java.io.File) throws java.io.IOException;
    method @Deprecated public static boolean verifyPackageCompatibility(java.io.File) throws java.io.IOException;
    field public static final int RESUME_ON_REBOOT_REBOOT_ERROR_INVALID_PACKAGE_NAME = 2000; // 0x7d0
    field public static final int RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED = 3000; // 0xbb8
    field public static final int RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE = 5000; // 0x1388
+18 −53
Original line number Diff line number Diff line
@@ -18,8 +18,6 @@ package android.os;

import static android.view.Display.DEFAULT_DISPLAY;

import static java.nio.charset.StandardCharsets.UTF_8;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -47,11 +45,8 @@ import android.text.format.DateFormat;
import android.util.Log;
import android.view.Display;

import libcore.io.Streams;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
@@ -73,7 +68,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

import sun.security.pkcs.PKCS7;
import sun.security.pkcs.SignerInfo;
@@ -423,72 +417,43 @@ public class RecoverySystem {
        } finally {
            raf.close();
        }

        // Additionally verify the package compatibility.
        if (!readAndVerifyPackageCompatibilityEntry(packageFile)) {
            throw new SignatureException("package compatibility verification failed");
        }
    }

    /**
     * Verifies the compatibility entry from an {@link InputStream}.
     *
     * @return the verification result.
     * @param inputStream The stream that contains the package compatibility info.
     * @throws IOException Never.
     * @return {@code true}.
     * @deprecated This function no longer checks {@code inputStream} and
     *   unconditionally returns true. Instead, check compatibility when the
     *   OTA package is generated.
     */
    @UnsupportedAppUsage
    @Deprecated
    @UnsupportedAppUsage(
            publicAlternatives = "Use {@code true} directly",
            maxTargetSdk = Build.VERSION_CODES.VANILLA_ICE_CREAM)
    private static boolean verifyPackageCompatibility(InputStream inputStream) throws IOException {
        ArrayList<String> list = new ArrayList<>();
        ZipInputStream zis = new ZipInputStream(inputStream);
        ZipEntry entry;
        while ((entry = zis.getNextEntry()) != null) {
            long entrySize = entry.getSize();
            if (entrySize > Integer.MAX_VALUE || entrySize < 0) {
                throw new IOException(
                        "invalid entry size (" + entrySize + ") in the compatibility file");
            }
            byte[] bytes = new byte[(int) entrySize];
            Streams.readFully(zis, bytes);
            list.add(new String(bytes, UTF_8));
        }
        if (list.isEmpty()) {
            throw new IOException("no entries found in the compatibility file");
        }
        return (VintfObject.verify(list.toArray(new String[list.size()])) == 0);
    }

    /**
     * Reads and verifies the compatibility entry in an OTA zip package. The compatibility entry is
     * a zip file (inside the OTA package zip).
     *
     * @return {@code true} if the entry doesn't exist or verification passes.
     */
    private static boolean readAndVerifyPackageCompatibilityEntry(File packageFile)
            throws IOException {
        try (ZipFile zip = new ZipFile(packageFile)) {
            ZipEntry entry = zip.getEntry("compatibility.zip");
            if (entry == null) {
        return true;
    }
            InputStream inputStream = zip.getInputStream(entry);
            return verifyPackageCompatibility(inputStream);
        }
    }

    /**
     * Verifies the package compatibility info against the current system.
     *
     * @param compatibilityFile the {@link File} that contains the package compatibility info.
     * @throws IOException if there were any errors reading the compatibility file.
     * @return the compatibility verification result.
     * @throws IOException Never.
     * @return {@code true}
     * @deprecated This function no longer checks {@code compatibilityFile} and
     *   unconditionally returns true. Instead, check compatibility when the
     *   OTA package is generated.
     *
     * {@hide}
     */
    @Deprecated
    @SystemApi
    @SuppressLint("RequiresPermission")
    public static boolean verifyPackageCompatibility(File compatibilityFile) throws IOException {
        try (InputStream inputStream = new FileInputStream(compatibilityFile)) {
            return verifyPackageCompatibility(inputStream);
        }
        return true;
    }

    /**