/src/cloud-hypervisor/fuzz/fuzz_targets/qcow.rs
Line | Count | Source |
1 | | // Copyright 2018 The Chromium OS Authors. All rights reserved. |
2 | | // Use of this source code is governed by a BSD-style license that can be |
3 | | // found in the LICENSE-BSD-3-Clause file. |
4 | | // |
5 | | // SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause |
6 | | |
7 | | #![no_main] |
8 | | use std::ffi; |
9 | | use std::fs::File; |
10 | | use std::io::{self, Cursor, Read, Seek, SeekFrom, Write}; |
11 | | use std::mem::size_of; |
12 | | use std::os::unix::io::{FromRawFd, RawFd}; |
13 | | |
14 | | use block::qcow::{QcowFile, RawFile}; |
15 | | use libfuzzer_sys::{fuzz_target, Corpus}; |
16 | | |
17 | | // Take the first 64 bits of data as an address and the next 64 bits as data to |
18 | | // store there. The rest of the data is used as a qcow image. |
19 | | fuzz_target!(|bytes: &[u8]| -> Corpus { |
20 | | if bytes.len() < 16 { |
21 | | // Need an address and data, each are 8 bytes. |
22 | | return Corpus::Reject; |
23 | | } |
24 | | let mut disk_image = Cursor::new(bytes); |
25 | | let addr = read_u64(&mut disk_image); |
26 | | let value = read_u64(&mut disk_image); |
27 | | let shm = memfd_create(&ffi::CString::new("fuzz").unwrap(), 0).unwrap(); |
28 | | let mut disk_file: File = unsafe { File::from_raw_fd(shm) }; |
29 | | disk_file.write_all(&bytes[16..]).unwrap(); |
30 | | disk_file.seek(SeekFrom::Start(0)).unwrap(); |
31 | | if let Ok(mut qcow) = QcowFile::from(RawFile::new(disk_file, false)) { |
32 | | if qcow.seek(SeekFrom::Start(addr)).is_ok() { |
33 | | let _ = qcow.write_all(&value.to_le_bytes()); |
34 | | } |
35 | | } |
36 | | |
37 | | Corpus::Keep |
38 | | }); |
39 | | |
40 | 4.29k | fn read_u64<T: Read>(readable: &mut T) -> u64 { |
41 | 4.29k | let mut buf = [0u8; size_of::<u64>()]; |
42 | 4.29k | readable.read_exact(&mut buf[..]).unwrap(); |
43 | 4.29k | u64::from_le_bytes(buf) |
44 | 4.29k | } |
45 | | |
46 | 2.14k | fn memfd_create(name: &ffi::CStr, flags: u32) -> Result<RawFd, io::Error> { |
47 | 2.14k | let res = unsafe { libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags) }; |
48 | | |
49 | 2.14k | if res < 0 { |
50 | 0 | Err(io::Error::last_os_error()) |
51 | | } else { |
52 | 2.14k | Ok(res as RawFd) |
53 | | } |
54 | 2.14k | } |