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

Commit 92ebd389 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Enable fs-verity to all APKs on install"

parents 288e135f 314dd4c0
Loading
Loading
Loading
Loading
+16 −8
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.internal.security;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Build;
import android.os.SystemProperties;
import android.system.Os;
@@ -41,6 +42,7 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
@@ -77,17 +79,23 @@ public abstract class VerityUtils {
        return filePath + FSVERITY_SIGNATURE_FILE_EXTENSION;
    }

    /** Enables fs-verity for the file with a PKCS#7 detached signature file. */
    public static void setUpFsverity(@NonNull String filePath, @NonNull String signaturePath)
    /** Enables fs-verity for the file with an optional PKCS#7 detached signature file. */
    public static void setUpFsverity(@NonNull String filePath, @Nullable String signaturePath)
            throws IOException {
        if (Files.size(Paths.get(signaturePath)) > MAX_SIGNATURE_FILE_SIZE_BYTES) {
            throw new SecurityException("Signature file is unexpectedly large: " + signaturePath);
        byte[] rawSignature = null;
        if (signaturePath != null) {
            Path path = Paths.get(signaturePath);
            if (Files.size(path) > MAX_SIGNATURE_FILE_SIZE_BYTES) {
                throw new SecurityException("Signature file is unexpectedly large: "
                        + signaturePath);
            }
        setUpFsverity(filePath, Files.readAllBytes(Paths.get(signaturePath)));
            rawSignature = Files.readAllBytes(path);
        }
        setUpFsverity(filePath, rawSignature);
    }

    /** Enables fs-verity for the file with a PKCS#7 detached signature bytes. */
    public static void setUpFsverity(@NonNull String filePath, @NonNull byte[] pkcs7Signature)
    /** Enables fs-verity for the file with an optional PKCS#7 detached signature bytes. */
    public static void setUpFsverity(@NonNull String filePath, @Nullable byte[] pkcs7Signature)
            throws IOException {
        // This will fail if the public key is not already in .fs-verity kernel keyring.
        int errno = enableFsverityNative(filePath, pkcs7Signature);
@@ -227,7 +235,7 @@ public abstract class VerityUtils {
    }

    private static native int enableFsverityNative(@NonNull String filePath,
            @NonNull byte[] pkcs7Signature);
            @Nullable byte[] pkcs7Signature);
    private static native int measureFsverityNative(@NonNull String filePath,
            @NonNull byte[] digest);
    private static native int statxForFsverityNative(@NonNull String filePath);
+12 −6
Original line number Diff line number Diff line
@@ -48,10 +48,6 @@ int enableFsverity(JNIEnv *env, jobject /* clazz */, jstring filePath, jbyteArra
    if (rfd.get() < 0) {
        return errno;
    }
    ScopedByteArrayRO signature_bytes(env, signature);
    if (signature_bytes.get() == nullptr) {
        return EINVAL;
    }

    fsverity_enable_arg arg = {};
    arg.version = 1;
@@ -59,8 +55,18 @@ int enableFsverity(JNIEnv *env, jobject /* clazz */, jstring filePath, jbyteArra
    arg.block_size = 4096;
    arg.salt_size = 0;
    arg.salt_ptr = reinterpret_cast<uintptr_t>(nullptr);

    if (signature != nullptr) {
        ScopedByteArrayRO signature_bytes(env, signature);
        if (signature_bytes.get() == nullptr) {
            return EINVAL;
        }
        arg.sig_size = signature_bytes.size();
        arg.sig_ptr = reinterpret_cast<uintptr_t>(signature_bytes.get());
    } else {
        arg.sig_size = 0;
        arg.sig_ptr = reinterpret_cast<uintptr_t>(nullptr);
    }

    if (ioctl(rfd.get(), FS_IOC_ENABLE_VERITY, &arg) < 0) {
        return errno;
+18 −16
Original line number Diff line number Diff line
@@ -1403,7 +1403,7 @@ final class InstallPackageHelper {
            doRenameLI(request, parsedPackage);

            try {
                setUpFsVerityIfPossible(parsedPackage);
                setUpFsVerity(parsedPackage);
            } catch (Installer.InstallerException | IOException | DigestException
                    | NoSuchAlgorithmException e) {
                throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
@@ -1800,13 +1800,10 @@ final class InstallPackageHelper {
    }

    /**
     * Set up fs-verity for the given package if possible.  This requires a feature flag of system
     * property to be enabled only if the kernel supports fs-verity.
     *
     * <p>When the feature flag is set to legacy mode, only APK is supported (with some experimental
     * kernel patches). In normal mode, all file format can be supported.
     * Set up fs-verity for the given package. For older devices that do not support fs-verity,
     * this is a no-op.
     */
    private void setUpFsVerityIfPossible(AndroidPackage pkg) throws Installer.InstallerException,
    private void setUpFsVerity(AndroidPackage pkg) throws Installer.InstallerException,
            PrepareFailure, IOException, DigestException, NoSuchAlgorithmException {
        if (!PackageManagerServiceUtils.isApkVerityEnabled()) {
            return;
@@ -1841,20 +1838,25 @@ final class InstallPackageHelper {
        }

        for (Map.Entry<String, String> entry : fsverityCandidates.entrySet()) {
            try {
                final String filePath = entry.getKey();
            final String signaturePath = entry.getValue();
                if (VerityUtils.hasFsverity(filePath)) {
                    continue;
                }

            // fs-verity is optional for now.  Only set up if signature is provided.
            if (new File(signaturePath).exists() && !VerityUtils.hasFsverity(filePath)) {
                try {
                    VerityUtils.setUpFsverity(filePath, signaturePath);
                // Set up fs-verity with optional signature.
                final String signaturePath = entry.getValue();
                String optionalSignaturePath = null;
                if (new File(signaturePath).exists()) {
                    optionalSignaturePath = signaturePath;
                }
                VerityUtils.setUpFsverity(filePath, optionalSignaturePath);
            } catch (IOException e) {
                throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
                        "Failed to enable fs-verity: " + e);
            }
        }
    }
    }

    private PackageFreezer freezePackageForInstall(String packageName, int installFlags,
            String killReason) {