1 // Copyright 2023, The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #![allow(missing_docs)] 16 #![no_main] 17 18 use avb_bindgen::{ 19 AvbFooter, AvbVBMetaImageHeader, AVB_FOOTER_MAGIC, AVB_FOOTER_MAGIC_LEN, AVB_MAGIC, 20 AVB_MAGIC_LEN, AVB_VERSION_MAJOR, AVB_VERSION_MINOR, 21 }; 22 use libfuzzer_sys::fuzz_target; 23 use pvmfw_avb::verify_payload; 24 use std::mem::{size_of, transmute}; 25 26 fuzz_target!(|kernel_and_vbmeta: &[u8]| { 27 // This fuzzer is mostly supposed to catch the memory corruption in 28 // VBMeta parsing. It is unlikely that the randomly generated 29 // kernel can pass the kernel verification, so the value of `initrd` 30 // is not so important as we won't reach initrd verification with 31 // this fuzzer. 32 const VBMETA_SIZE: usize = size_of::<AvbVBMetaImageHeader>(); 33 const RESERVED_REGION_SIZE: usize = 28; 34 35 if kernel_and_vbmeta.len() < VBMETA_SIZE { 36 return; 37 } 38 let kernel_size = kernel_and_vbmeta.len() - VBMETA_SIZE; 39 let avb_footer = AvbFooter { 40 magic: AVB_FOOTER_MAGIC[..(AVB_FOOTER_MAGIC_LEN as usize)].try_into().unwrap(), 41 version_major: AVB_VERSION_MAJOR.to_be(), 42 version_minor: AVB_VERSION_MINOR.to_be(), 43 original_image_size: (kernel_size as u64).to_be(), 44 vbmeta_offset: (kernel_size as u64).to_be(), 45 vbmeta_size: (VBMETA_SIZE as u64).to_be(), 46 reserved: [0u8; RESERVED_REGION_SIZE], 47 }; 48 // SAFETY: It is safe as avb_footer is a valid AvbFooter struct. 49 let avb_footer = unsafe { transmute::<AvbFooter, [u8; size_of::<AvbFooter>()]>(avb_footer) }; 50 51 let mut modified_kernel = vec![0u8; kernel_and_vbmeta.len() + size_of::<AvbFooter>()]; 52 modified_kernel[..kernel_and_vbmeta.len()].copy_from_slice(kernel_and_vbmeta); 53 // Sets the magic for AvbVBMetaImageHeader. 54 modified_kernel[kernel_size..(kernel_size + AVB_MAGIC_LEN as usize)] 55 .copy_from_slice(&AVB_MAGIC[..(AVB_MAGIC_LEN as usize)]); 56 modified_kernel[kernel_and_vbmeta.len()..].copy_from_slice(&avb_footer); 57 58 let _ = verify_payload(&modified_kernel, /*initrd=*/ None, &[0u8; 64]); 59 }); 60