pvmfw: avb: Locate AVB footer field safely
Replace the unsafe pointer arithmetic with a safe index computation.
Replace the use of `as` with `.try_into().unwrap()` for stability.
Test: m libpvmfw_avb.integration_test
Change-Id: I8d10142f09b7c626ed1aca6d1c886b207bff7f3a
diff --git a/pvmfw/avb/tests/api_test.rs b/pvmfw/avb/tests/api_test.rs
index c6f26ac..8683e69 100644
--- a/pvmfw/avb/tests/api_test.rs
+++ b/pvmfw/avb/tests/api_test.rs
@@ -20,7 +20,11 @@
use avb::{DescriptorError, SlotVerifyError};
use avb_bindgen::{AvbFooter, AvbVBMetaImageHeader};
use pvmfw_avb::{verify_payload, Capability, DebugLevel, PvmfwVerifyError, VerifiedBootData};
-use std::{fs, mem::size_of, ptr};
+use std::{
+ fs,
+ mem::{offset_of, size_of},
+ ptr,
+};
use utils::*;
const TEST_IMG_WITH_ONE_HASHDESC_PATH: &str = "test_image_with_one_hashdesc.img";
@@ -243,32 +247,20 @@
fn kernel_footer_with_vbmeta_offset_overwritten_fails_verification() -> Result<()> {
// Arrange.
let mut kernel = load_latest_signed_kernel()?;
- let total_len = kernel.len() as u64;
- let footer = extract_avb_footer(&kernel)?;
- assert!(footer.vbmeta_offset < total_len);
- // TODO: use core::mem::offset_of once stable.
- let footer_addr = ptr::addr_of!(footer) as *const u8;
- let vbmeta_offset_addr = ptr::addr_of!(footer.vbmeta_offset) as *const u8;
- let vbmeta_offset_start =
- // SAFETY:
- // - both raw pointers `vbmeta_offset_addr` and `footer_addr` are not null;
- // - they are both derived from the `footer` object;
- // - the offset is known from the struct definition to be a small positive number of bytes.
- unsafe { vbmeta_offset_addr.offset_from(footer_addr) };
- let footer_start = kernel.len() - size_of::<AvbFooter>();
- let vbmeta_offset_start = footer_start + usize::try_from(vbmeta_offset_start)?;
+ let footer_offset = get_avb_footer_offset(&kernel)?;
+ let vbmeta_offset_offset = footer_offset + offset_of!(AvbFooter, vbmeta_offset);
+ let vbmeta_offset_bytes = vbmeta_offset_offset..(vbmeta_offset_offset + size_of::<u64>());
- let wrong_offsets = [total_len, u64::MAX];
- for &wrong_offset in wrong_offsets.iter() {
+ let test_values = [kernel.len(), usize::MAX];
+ for value in test_values {
+ let value = u64::try_from(value).unwrap();
// Act.
- kernel[vbmeta_offset_start..(vbmeta_offset_start + size_of::<u64>())]
- .copy_from_slice(&wrong_offset.to_be_bytes());
+ kernel[vbmeta_offset_bytes.clone()].copy_from_slice(&value.to_be_bytes());
+ // footer is unaligned; copy vbmeta_offset to local variable
+ let vbmeta_offset = extract_avb_footer(&kernel)?.vbmeta_offset;
+ assert_eq!(vbmeta_offset, value);
// Assert.
- let footer = extract_avb_footer(&kernel)?;
- // footer is unaligned; copy vbmeta_offset to local variable
- let vbmeta_offset = footer.vbmeta_offset;
- assert_eq!(wrong_offset, vbmeta_offset);
assert_payload_verification_with_initrd_fails(
&kernel,
&load_latest_initrd_normal()?,