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