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