[avb] Test footer with vbmeta offset overwritten fails verification

Bug: 256148034
Test: atest libpvmfw_avb.integration_test
Change-Id: I93e81b11d04a4dc2a41501a83efaac650e6eafeb
diff --git a/pvmfw/avb/tests/api_test.rs b/pvmfw/avb/tests/api_test.rs
index 2bd46d5..6b98dfb 100644
--- a/pvmfw/avb/tests/api_test.rs
+++ b/pvmfw/avb/tests/api_test.rs
@@ -145,6 +145,39 @@
 }
 
 #[test]
+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);
+    let vbmeta_offset_addr = ptr::addr_of!(footer.vbmeta_offset) as *const u8;
+    // SAFETY: It is safe as both raw pointers `vbmeta_offset_addr` and `footer` are not null.
+    let vbmeta_offset_start =
+        unsafe { vbmeta_offset_addr.offset_from(ptr::addr_of!(footer) as *const u8) };
+    let footer_start = kernel.len() - size_of::<AvbFooter>();
+    let vbmeta_offset_start = footer_start + usize::try_from(vbmeta_offset_start)?;
+
+    let wrong_offsets = [total_len, u64::MAX];
+    for &wrong_offset in wrong_offsets.iter() {
+        // Act.
+        kernel[vbmeta_offset_start..(vbmeta_offset_start + size_of::<u64>())]
+            .copy_from_slice(&wrong_offset.to_be_bytes());
+
+        // Assert.
+        let footer = extract_avb_footer(&kernel)?;
+        assert_eq!(wrong_offset, footer.vbmeta_offset as u64);
+        assert_payload_verification_with_initrd_eq(
+            &kernel,
+            &load_latest_initrd_normal()?,
+            &load_trusted_public_key()?,
+            Err(AvbSlotVerifyError::Io),
+        )?;
+    }
+    Ok(())
+}
+
+#[test]
 fn tampered_kernel_footer_fails_verification() -> Result<()> {
     let mut kernel = load_latest_signed_kernel()?;
     let avb_footer_index = kernel.len() - size_of::<AvbFooter>() + RANDOM_FOOTER_POS;