pvmfw: Don't panic on extra VBMeta properties
Remove the assumption that the image should contain a single property
descriptor (the descriptors should NOT be re-used after pvmfw, and extra
descriptors are safe to ignore) and update libpvmfw_avb.integration_test
to prevent a verification error.
Bug: 339779843
Bug: 339782511
Bug: 378673494
Test: atest libpvmfw_avb.integration_test
Change-Id: Iacf7efc2278354eda10e50a2a1f2122815dedab3
diff --git a/guest/pvmfw/avb/src/verify.rs b/guest/pvmfw/avb/src/verify.rs
index c85d886..2a7eed2 100644
--- a/guest/pvmfw/avb/src/verify.rs
+++ b/guest/pvmfw/avb/src/verify.rs
@@ -17,11 +17,10 @@
use crate::ops::{Ops, Payload};
use crate::partition::PartitionName;
use crate::PvmfwVerifyError;
-use alloc::vec;
use alloc::vec::Vec;
use avb::{
- Descriptor, DescriptorError, DescriptorResult, HashDescriptor, PartitionData,
- PropertyDescriptor, SlotVerifyError, SlotVerifyNoDataResult, VbmetaData,
+ Descriptor, DescriptorError, DescriptorResult, HashDescriptor, PartitionData, SlotVerifyError,
+ SlotVerifyNoDataResult, VbmetaData,
};
// We use this for the rollback_index field if SlotVerifyData has empty rollback_indexes
@@ -93,14 +92,14 @@
/// Returns the capabilities indicated in `descriptor`, or error if the descriptor has
/// unexpected contents.
- fn get_capabilities(descriptor: &PropertyDescriptor) -> Result<Vec<Self>, PvmfwVerifyError> {
- if descriptor.key != Self::KEY {
- return Err(PvmfwVerifyError::UnknownVbmetaProperty);
- }
+ fn get_capabilities(vbmeta_data: &VbmetaData) -> Result<Vec<Self>, PvmfwVerifyError> {
+ let Some(value) = vbmeta_data.get_property_value(Self::KEY) else {
+ return Ok(Vec::new());
+ };
let mut res = Vec::new();
- for v in descriptor.value.split(|b| *b == Self::SEPARATOR) {
+ for v in value.split(|b| *b == Self::SEPARATOR) {
let cap = match v {
Self::REMOTE_ATTEST => Self::RemoteAttest,
Self::TRUSTY_SECURITY_VM => Self::TrustySecurityVm,
@@ -155,30 +154,6 @@
}
}
-/// Verifies that the vbmeta contains at most one property descriptor and it indicates the
-/// vm type is service VM.
-fn verify_property_and_get_capabilities(
- descriptors: &[Descriptor],
-) -> Result<Vec<Capability>, PvmfwVerifyError> {
- let mut iter = descriptors.iter().filter_map(|d| match d {
- Descriptor::Property(p) => Some(p),
- _ => None,
- });
-
- let descriptor = match iter.next() {
- // No property descriptors -> no capabilities.
- None => return Ok(vec![]),
- Some(d) => d,
- };
-
- // Multiple property descriptors -> error.
- if iter.next().is_some() {
- return Err(DescriptorError::InvalidContents.into());
- }
-
- Capability::get_capabilities(descriptor)
-}
-
/// Hash descriptors extracted from a vbmeta image.
///
/// We always have a kernel hash descriptor and may have initrd normal or debug descriptors.
@@ -280,7 +255,7 @@
verify_vbmeta_is_from_kernel_partition(vbmeta_image)?;
let descriptors = vbmeta_image.descriptors()?;
let hash_descriptors = HashDescriptors::get(&descriptors)?;
- let capabilities = verify_property_and_get_capabilities(&descriptors)?;
+ let capabilities = Capability::get_capabilities(vbmeta_image)?;
let page_size = None; // TODO(ptosi): Read from payload.
if initrd.is_none() {