summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/security/VerityUtils.java24
-rw-r--r--core/jni/com_android_internal_security_VerityUtils.cpp18
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java34
3 files changed, 46 insertions, 30 deletions
diff --git a/core/java/com/android/internal/security/VerityUtils.java b/core/java/com/android/internal/security/VerityUtils.java
index 7f45c098daba..3ab11a8b9111 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 8305bd087bfd..dabee6938e5b 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<uintptr_t>(nullptr);
- arg.sig_size = signature_bytes.size();
- arg.sig_ptr = reinterpret_cast<uintptr_t>(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<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;
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 7ea0c04562e2..e4b11ed05c6b 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -1399,7 +1399,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,
@@ -1796,13 +1796,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;
@@ -1837,17 +1834,22 @@ final class InstallPackageHelper {
}
for (Map.Entry<String, String> entry : fsverityCandidates.entrySet()) {
- final String filePath = entry.getKey();
- final String signaturePath = entry.getValue();
+ try {
+ final String filePath = entry.getKey();
+ 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);
- } catch (IOException e) {
- throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
- "Failed to enable fs-verity: " + e);
+ // 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);
}
}
}