From d163351b15f82dfbcad7c0d6a5e08cee30b94b96 Mon Sep 17 00:00:00 2001 From: Victor Hsieh Date: Tue, 13 Dec 2022 10:04:15 -0800 Subject: [PATCH] Support fs-verity setup with null/no signature This is a partial cherry-pick from ag/20131484 (Enable fs-verity to all APKs on install), where the change to InstallPackageHelper.java is excluded to avoid the complexity of diverged code base in package manager. This is safe because: 1. The function signature does not change. 2. The caller isn't giving it a null signature in AOSP yet, so it won't break existing package manager use case. This partial cherry-pick is desired in order to unblock some work across internal and AOSP branches. Bug: 258538225 Test: atest CtsAppSecurityHostTestCases:android.appsecurity.cts.ApkVerityInstallTest Merged-In: I119e5189603af888dfa1ece2bee9e7635120854b Change-Id: Ie0001bb74a0b7dffd9f6a3d2a23f5c66f381bea7 --- .../internal/security/VerityUtils.java | 24 ++++++++++++------- ..._android_internal_security_VerityUtils.cpp | 18 +++++++++----- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/core/java/com/android/internal/security/VerityUtils.java b/core/java/com/android/internal/security/VerityUtils.java index 7f45c098daba8..3ab11a8b91114 100644 --- a/core/java/com/android/internal/security/VerityUtils.java +++ b/core/java/com/android/internal/security/VerityUtils.java @@ -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); + } + rawSignature = Files.readAllBytes(path); } - setUpFsverity(filePath, Files.readAllBytes(Paths.get(signaturePath))); + 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); diff --git a/core/jni/com_android_internal_security_VerityUtils.cpp b/core/jni/com_android_internal_security_VerityUtils.cpp index c5b3d8ae936c5..5553d28db0668 100644 --- a/core/jni/com_android_internal_security_VerityUtils.cpp +++ b/core/jni/com_android_internal_security_VerityUtils.cpp @@ -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(nullptr); - arg.sig_size = signature_bytes.size(); - arg.sig_ptr = reinterpret_cast(signature_bytes.get()); + + 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(signature_bytes.get()); + } else { + arg.sig_size = 0; + arg.sig_ptr = reinterpret_cast(nullptr); + } if (ioctl(rfd.get(), FS_IOC_ENABLE_VERITY, &arg) < 0) { return errno;