xref: /cloud-hypervisor/fuzz/fuzz_targets/vhdx.rs (revision f67b3f79ea19c9a66e04074cbbf5d292f6529e43)
1 // Copyright © 2021 Intel Corporation
2 //
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #![no_main]
6 use libfuzzer_sys::fuzz_target;
7 use std::ffi;
8 use std::fs::File;
9 use std::io::{self, Read, Seek, SeekFrom, Write};
10 use std::os::unix::io::{FromRawFd, RawFd};
11 use vhdx::vhdx::Vhdx;
12 
13 // Populate the corpus directory with a test file:
14 // truncate -s 16M /tmp/source
15 // qemu-img convert -O vhdx /tmp/source fuzz/corpus/vhdx/test.vhdx
16 // Run with:
17 // cargo fuzz run vhdx -j 32 -- -max_len=16777216
18 fuzz_target!(|bytes| {
19     let shm = memfd_create(&ffi::CString::new("fuzz").unwrap(), 0).unwrap();
20     let mut disk_file: File = unsafe { File::from_raw_fd(shm) };
21     disk_file.write_all(&bytes[..]).unwrap();
22     disk_file.seek(SeekFrom::Start(0)).unwrap();
23 
24     if let Ok(mut vhdx) = Vhdx::new(disk_file) {
25         if vhdx.seek(SeekFrom::Start(0)).is_ok() {
26             let mut offset = 0;
27             while offset < bytes.len() {
28                 let mut data = vec![0; 8192];
29                 vhdx.read_exact(&mut data).ok();
30                 offset += data.len();
31             }
32         }
33 
34         if vhdx.seek(SeekFrom::Start(0)).is_ok() {
35             let mut offset = 0;
36             while offset < bytes.len() {
37                 let data = vec![0; 8192];
38                 vhdx.write_all(&data).ok();
39                 offset += data.len();
40             }
41         }
42     }
43 });
44 
45 fn memfd_create(name: &ffi::CStr, flags: u32) -> Result<RawFd, io::Error> {
46     let res = unsafe { libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags) };
47 
48     if res < 0 {
49         Err(io::Error::last_os_error())
50     } else {
51         Ok(res as RawFd)
52     }
53 }
54