diff --git a/fuzz/fuzz_targets/balloon.rs b/fuzz/fuzz_targets/balloon.rs index e241e66a5..b745cf618 100644 --- a/fuzz/fuzz_targets/balloon.rs +++ b/fuzz/fuzz_targets/balloon.rs @@ -7,7 +7,7 @@ use std::os::unix::io::{AsRawFd, FromRawFd}; use std::sync::Arc; -use libfuzzer_sys::fuzz_target; +use libfuzzer_sys::{fuzz_target, Corpus}; use seccompiler::SeccompAction; use virtio_devices::{VirtioDevice, VirtioInterrupt, VirtioInterruptType}; use virtio_queue::{Queue, QueueT}; @@ -37,11 +37,11 @@ const AVAIL_RING_SIZE: u64 = 6_u64 + 2 * QUEUE_SIZE as u64; // Used ring size const USED_RING_SIZE: u64 = 6_u64 + 8 * QUEUE_SIZE as u64; -fuzz_target!(|bytes| { +fuzz_target!(|bytes: &[u8]| -> Corpus { if bytes.len() < QUEUE_DATA_SIZE * QUEUE_NUM || bytes.len() > (QUEUE_DATA_SIZE * QUEUE_NUM + MEM_SIZE) { - return; + return Corpus::Reject; } let mut balloon = virtio_devices::Balloon::new( @@ -61,7 +61,7 @@ fuzz_target!(|bytes| { // Setup the guest memory with the input bytes let mem = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), MEM_SIZE)]).unwrap(); if mem.write_slice(mem_bytes, GuestAddress(0 as u64)).is_err() { - return; + return Corpus::Reject; } let guest_memory = GuestMemoryAtomic::new(mem); @@ -108,6 +108,8 @@ fuzz_target!(|bytes| { // Wait for the events to finish and balloon device worker thread to return balloon.wait_for_epoll_threads(); + + Corpus::Keep }); pub struct NoopVirtioInterrupt {} diff --git a/fuzz/fuzz_targets/block.rs b/fuzz/fuzz_targets/block.rs index 3cc8d1eaa..c06f0dea2 100644 --- a/fuzz/fuzz_targets/block.rs +++ b/fuzz/fuzz_targets/block.rs @@ -17,7 +17,7 @@ use std::{ffi, io}; use block::async_io::DiskFile; use block::raw_sync::RawFileDiskSync; -use libfuzzer_sys::fuzz_target; +use libfuzzer_sys::{fuzz_target, Corpus}; use seccompiler::SeccompAction; use virtio_devices::{Block, VirtioDevice, VirtioInterrupt, VirtioInterruptType}; use virtio_queue::{Queue, QueueT}; @@ -40,9 +40,9 @@ const AVAIL_RING_SIZE: u64 = 6_u64 + 2 * QUEUE_SIZE as u64; // Guest physical address for used ring (requires to 4-bytes aligned) const USED_RING_ADDR: u64 = (AVAIL_RING_ADDR + AVAIL_RING_SIZE + 3) & !3_u64; -fuzz_target!(|bytes| { +fuzz_target!(|bytes: &[u8]| -> Corpus { if bytes.len() < QUEUE_DATA_SIZE || bytes.len() > (QUEUE_DATA_SIZE + MEM_SIZE) { - return; + return Corpus::Reject; } let queue_data = &bytes[..QUEUE_DATA_SIZE]; @@ -76,7 +76,7 @@ fuzz_target!(|bytes| { // Setup the guest memory with the input bytes let mem = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), MEM_SIZE)]).unwrap(); if mem.write_slice(mem_bytes, GuestAddress(0 as u64)).is_err() { - return; + return Corpus::Reject; } let guest_memory = GuestMemoryAtomic::new(mem); @@ -96,6 +96,8 @@ fuzz_target!(|bytes| { // Wait for the events to finish and block device worker thread to return block.wait_for_epoll_threads(); + + Corpus::Keep }); fn memfd_create(name: &ffi::CStr, flags: u32) -> Result { diff --git a/fuzz/fuzz_targets/cmos.rs b/fuzz/fuzz_targets/cmos.rs index 07d745b30..9ae5b59da 100644 --- a/fuzz/fuzz_targets/cmos.rs +++ b/fuzz/fuzz_targets/cmos.rs @@ -5,14 +5,14 @@ #![no_main] use devices::legacy::Cmos; use libc::EFD_NONBLOCK; -use libfuzzer_sys::fuzz_target; +use libfuzzer_sys::{fuzz_target, Corpus}; use vm_device::BusDevice; use vmm_sys_util::eventfd::EventFd; -fuzz_target!(|bytes| { +fuzz_target!(|bytes: &[u8]| -> Corpus { // Need at least 16 bytes for the test if bytes.len() < 16 { - return; + return Corpus::Reject; } let mut below_4g = [0u8; 8]; @@ -46,4 +46,6 @@ fuzz_target!(|bytes| { cmos.write(0, offset, &data); } } + + Corpus::Keep }); diff --git a/fuzz/fuzz_targets/console.rs b/fuzz/fuzz_targets/console.rs index 7b62715fe..4b3a49df9 100644 --- a/fuzz/fuzz_targets/console.rs +++ b/fuzz/fuzz_targets/console.rs @@ -9,7 +9,7 @@ use std::io::Write; use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; use std::sync::Arc; -use libfuzzer_sys::fuzz_target; +use libfuzzer_sys::{fuzz_target, Corpus}; use seccompiler::SeccompAction; use virtio_devices::{VirtioDevice, VirtioInterrupt, VirtioInterruptType}; use virtio_queue::{Queue, QueueT}; @@ -54,12 +54,12 @@ const QUEUE_BYTES_SIZE: usize = align!( DESC_TABLE_ALIGN_SIZE ) as usize; -fuzz_target!(|bytes| { +fuzz_target!(|bytes: &[u8]| -> Corpus { if bytes.len() < (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE) * QUEUE_NUM + CONSOLE_INPUT_SIZE || bytes.len() > (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE) * QUEUE_NUM + CONSOLE_INPUT_SIZE + MEM_SIZE { - return; + return Corpus::Reject; } let (pipe_rx, mut pipe_tx) = create_pipe().unwrap(); @@ -108,10 +108,10 @@ fuzz_target!(|bytes| { .write_slice(queue_bytes, GuestAddress(BASE_VIRT_QUEUE_ADDR)) .is_err() { - return; + return Corpus::Reject; } if mem.write_slice(mem_bytes, GuestAddress(0 as u64)).is_err() { - return; + return Corpus::Reject; } let guest_memory = GuestMemoryAtomic::new(mem); @@ -137,6 +137,8 @@ fuzz_target!(|bytes| { // Wait for the events to finish and console device worker thread to return console.wait_for_epoll_threads(); + + Corpus::Keep }); pub struct NoopVirtioInterrupt {} diff --git a/fuzz/fuzz_targets/http_api.rs b/fuzz/fuzz_targets/http_api.rs index c9d2559fd..c1edbf9b1 100644 --- a/fuzz/fuzz_targets/http_api.rs +++ b/fuzz/fuzz_targets/http_api.rs @@ -8,7 +8,7 @@ use std::path::PathBuf; use std::sync::mpsc::{channel, Receiver}; use std::thread; -use libfuzzer_sys::fuzz_target; +use libfuzzer_sys::{fuzz_target, Corpus}; use micro_http::Request; use once_cell::sync::Lazy; use vm_migration::MigratableError; @@ -27,9 +27,9 @@ use vmm_sys_util::eventfd::EventFd; static ROUTES: Lazy>> = Lazy::new(|| HTTP_ROUTES.routes.values().collect()); -fuzz_target!(|bytes| { +fuzz_target!(|bytes: &[u8]| -> Corpus { if bytes.len() < 2 { - return; + return Corpus::Reject; } let route = ROUTES[bytes[0] as usize % ROUTES.len()]; @@ -53,6 +53,8 @@ fuzz_target!(|bytes| { exit_evt.write(1).ok(); http_receiver_thread.join().unwrap(); }; + + Corpus::Keep }); fn generate_request(bytes: &[u8]) -> Option { diff --git a/fuzz/fuzz_targets/iommu.rs b/fuzz/fuzz_targets/iommu.rs index 95d6ca56b..a93097d6c 100644 --- a/fuzz/fuzz_targets/iommu.rs +++ b/fuzz/fuzz_targets/iommu.rs @@ -7,7 +7,7 @@ use std::os::unix::io::{AsRawFd, FromRawFd}; use std::sync::Arc; -use libfuzzer_sys::fuzz_target; +use libfuzzer_sys::{fuzz_target, Corpus}; use seccompiler::SeccompAction; use virtio_devices::{VirtioDevice, VirtioInterrupt, VirtioInterruptType}; use virtio_queue::{Queue, QueueT}; @@ -54,11 +54,11 @@ const USED_RING_ADDR: u64 = align!(AVAIL_RING_ADDR + AVAIL_RING_SIZE, USED_RING_ // Virtio-queue size in bytes const QUEUE_BYTES_SIZE: usize = (USED_RING_ADDR + USED_RING_SIZE - DESC_TABLE_ADDR) as usize; -fuzz_target!(|bytes| { +fuzz_target!(|bytes: &[u8]| -> Corpus { if bytes.len() < (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE) || bytes.len() > (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE + MEM_SIZE) { - return; + return Corpus::Reject; } let (mut iommu, _) = virtio_devices::Iommu::new( @@ -91,10 +91,10 @@ fuzz_target!(|bytes| { .write_slice(queue_bytes, GuestAddress(DESC_TABLE_ADDR)) .is_err() { - return; + return Corpus::Reject; } if mem.write_slice(mem_bytes, GuestAddress(0 as u64)).is_err() { - return; + return Corpus::Reject; } let guest_memory = GuestMemoryAtomic::new(mem); @@ -118,6 +118,8 @@ fuzz_target!(|bytes| { // Wait for the events to finish and vIOMMU device worker thread to return iommu.wait_for_epoll_threads(); + + Corpus::Keep }); pub struct NoopVirtioInterrupt {} diff --git a/fuzz/fuzz_targets/linux_loader_cmdline.rs b/fuzz/fuzz_targets/linux_loader_cmdline.rs index 561b5eabd..c27185f51 100644 --- a/fuzz/fuzz_targets/linux_loader_cmdline.rs +++ b/fuzz/fuzz_targets/linux_loader_cmdline.rs @@ -8,7 +8,7 @@ #![no_main] -use libfuzzer_sys::fuzz_target; +use libfuzzer_sys::{fuzz_target, Corpus}; use vm_memory::bitmap::AtomicBitmap; use vm_memory::GuestAddress; @@ -18,7 +18,7 @@ const MEM_SIZE: usize = 256 * 1024 * 1024; // From 'arch::x86_64::layout::CMDLINE_START' const CMDLINE_START: GuestAddress = GuestAddress(0x20000); -fuzz_target!(|bytes| { +fuzz_target!(|bytes: &[u8]| -> Corpus { let payload_config = vmm::vm_config::PayloadConfig { firmware: None, kernel: None, @@ -29,9 +29,11 @@ fuzz_target!(|bytes| { }; let kernel_cmdline = match vmm::vm::Vm::generate_cmdline(&payload_config) { Ok(cmdline) => cmdline, - _ => return, + _ => return Corpus::Reject, }; let guest_memory = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), MEM_SIZE)]).unwrap(); linux_loader::loader::load_cmdline(&guest_memory, CMDLINE_START, &kernel_cmdline).ok(); + + Corpus::Keep }); diff --git a/fuzz/fuzz_targets/mem.rs b/fuzz/fuzz_targets/mem.rs index e6ea24926..57fc9a91d 100644 --- a/fuzz/fuzz_targets/mem.rs +++ b/fuzz/fuzz_targets/mem.rs @@ -7,7 +7,7 @@ use std::os::unix::io::{AsRawFd, FromRawFd}; use std::sync::{Arc, Mutex}; -use libfuzzer_sys::fuzz_target; +use libfuzzer_sys::{fuzz_target, Corpus}; use seccompiler::SeccompAction; use virtio_devices::{BlocksState, Mem, VirtioDevice, VirtioInterrupt, VirtioInterruptType}; use virtio_queue::{Queue, QueueT}; @@ -57,11 +57,11 @@ const USED_RING_ADDR: u64 = align!(AVAIL_RING_ADDR + AVAIL_RING_SIZE, USED_RING_ // Virtio-queue size in bytes const QUEUE_BYTES_SIZE: usize = (USED_RING_ADDR + USED_RING_SIZE - DESC_TABLE_ADDR) as usize; -fuzz_target!(|bytes| { +fuzz_target!(|bytes: &[u8]| -> Corpus { if bytes.len() < VIRTIO_MEM_DATA_SIZE + QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE || bytes.len() > (VIRTIO_MEM_DATA_SIZE + QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE + MEM_SIZE) { - return; + return Corpus::Reject; } let virtio_mem_data = &bytes[..VIRTIO_MEM_DATA_SIZE]; @@ -86,7 +86,7 @@ fuzz_target!(|bytes| { .write_slice(queue_bytes, GuestAddress(DESC_TABLE_ADDR)) .is_err() { - return; + return Corpus::Reject; } // Add the memory region for the virtio-mem device let mem = mem.insert_region(virtio_mem_region).unwrap(); @@ -94,7 +94,7 @@ fuzz_target!(|bytes| { .write_slice(mem_bytes, GuestAddress(VIRTIO_MEM_REGION_ADDRESS)) .is_err() { - return; + return Corpus::Reject; } let guest_memory = GuestMemoryAtomic::new(mem); @@ -114,6 +114,8 @@ fuzz_target!(|bytes| { // Wait for the events to finish and virtio-mem device worker thread to return virtio_mem.wait_for_epoll_threads(); + + return Corpus::Keep; }); pub struct NoopVirtioInterrupt {} diff --git a/fuzz/fuzz_targets/net.rs b/fuzz/fuzz_targets/net.rs index 305c2b041..30968d2a4 100644 --- a/fuzz/fuzz_targets/net.rs +++ b/fuzz/fuzz_targets/net.rs @@ -9,7 +9,7 @@ use std::io::{Read, Write}; use std::os::unix::io::{AsRawFd, FromRawFd}; use std::sync::Arc; -use libfuzzer_sys::fuzz_target; +use libfuzzer_sys::{fuzz_target, Corpus}; use seccompiler::SeccompAction; use virtio_devices::{VirtioDevice, VirtioInterrupt, VirtioInterruptType}; use virtio_queue::{Queue, QueueT}; @@ -55,12 +55,12 @@ const QUEUE_BYTES_SIZE: usize = align!( DESC_TABLE_ALIGN_SIZE ) as usize; -fuzz_target!(|bytes| { +fuzz_target!(|bytes: &[u8]| -> Corpus { if bytes.len() < TAP_INPUT_SIZE + (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE) * QUEUE_NUM || bytes.len() > TAP_INPUT_SIZE + (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE) * QUEUE_NUM + MEM_SIZE { - return; + return Corpus::Reject; } let (dummy_tap_frontend, dummy_tap_backend) = create_socketpair().unwrap(); @@ -111,10 +111,10 @@ fuzz_target!(|bytes| { .write_slice(queue_bytes, GuestAddress(BASE_VIRT_QUEUE_ADDR)) .is_err() { - return; + return Corpus::Reject; } if mem.write_slice(mem_bytes, GuestAddress(0 as u64)).is_err() { - return; + return Corpus::Reject; } let guest_memory = GuestMemoryAtomic::new(mem); @@ -155,6 +155,8 @@ fuzz_target!(|bytes| { // Terminate the thread for the dummy tap backend exit_evt.write(1).ok(); tap_backend_thread.join().unwrap(); + + return Corpus::Keep; }); pub struct NoopVirtioInterrupt {} diff --git a/fuzz/fuzz_targets/pmem.rs b/fuzz/fuzz_targets/pmem.rs index d0b165a7b..e8cb488e7 100644 --- a/fuzz/fuzz_targets/pmem.rs +++ b/fuzz/fuzz_targets/pmem.rs @@ -10,7 +10,7 @@ use std::sync::Arc; use std::{ffi, io}; use libc::{MAP_NORESERVE, MAP_PRIVATE, PROT_READ, PROT_WRITE}; -use libfuzzer_sys::fuzz_target; +use libfuzzer_sys::{fuzz_target, Corpus}; use seccompiler::SeccompAction; use virtio_devices::{Pmem, UserspaceMapping, VirtioDevice, VirtioInterrupt, VirtioInterruptType}; use virtio_queue::{Queue, QueueT}; @@ -35,9 +35,9 @@ const AVAIL_RING_SIZE: u64 = 6_u64 + 2 * QUEUE_SIZE as u64; // Guest physical address for used ring (requires to 4-bytes aligned) const USED_RING_ADDR: u64 = (AVAIL_RING_ADDR + AVAIL_RING_SIZE + 3) & !3_u64; -fuzz_target!(|bytes| { +fuzz_target!(|bytes: &[u8]| -> Corpus { if bytes.len() < QUEUE_DATA_SIZE || bytes.len() > (QUEUE_DATA_SIZE + MEM_SIZE) { - return; + return Corpus::Reject; } let mut pmem = create_dummy_pmem(); @@ -50,7 +50,7 @@ fuzz_target!(|bytes| { // Setup the guest memory with the input bytes let mem = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), MEM_SIZE)]).unwrap(); if mem.write_slice(mem_bytes, GuestAddress(0 as u64)).is_err() { - return; + return Corpus::Reject; } let guest_memory = GuestMemoryAtomic::new(mem); @@ -69,6 +69,8 @@ fuzz_target!(|bytes| { // Wait for the events to finish and pmem device worker thread to return pmem.wait_for_epoll_threads(); + + Corpus::Keep }); fn memfd_create_with_size(name: &ffi::CStr, flags: u32, size: usize) -> Result { diff --git a/fuzz/fuzz_targets/qcow.rs b/fuzz/fuzz_targets/qcow.rs index 0a7c64fa2..900d24f9b 100644 --- a/fuzz/fuzz_targets/qcow.rs +++ b/fuzz/fuzz_targets/qcow.rs @@ -12,14 +12,14 @@ use std::mem::size_of; use std::os::unix::io::{FromRawFd, RawFd}; use block::qcow::{QcowFile, RawFile}; -use libfuzzer_sys::fuzz_target; +use libfuzzer_sys::{fuzz_target, Corpus}; // Take the first 64 bits of data as an address and the next 64 bits as data to // store there. The rest of the data is used as a qcow image. -fuzz_target!(|bytes| { +fuzz_target!(|bytes: &[u8]| -> Corpus { if bytes.len() < 16 { // Need an address and data, each are 8 bytes. - return; + return Corpus::Reject; } let mut disk_image = Cursor::new(bytes); let addr = read_u64(&mut disk_image); @@ -33,6 +33,8 @@ fuzz_target!(|bytes| { let _ = qcow.write_all(&value.to_le_bytes()); } } + + Corpus::Keep }); fn read_u64(readable: &mut T) -> u64 { diff --git a/fuzz/fuzz_targets/rng.rs b/fuzz/fuzz_targets/rng.rs index a002cd2a0..8d5ffe35b 100644 --- a/fuzz/fuzz_targets/rng.rs +++ b/fuzz/fuzz_targets/rng.rs @@ -7,7 +7,7 @@ use std::os::unix::io::{AsRawFd, FromRawFd}; use std::sync::Arc; -use libfuzzer_sys::fuzz_target; +use libfuzzer_sys::{fuzz_target, Corpus}; use seccompiler::SeccompAction; use virtio_devices::{VirtioDevice, VirtioInterrupt, VirtioInterruptType}; use virtio_queue::{Queue, QueueT}; @@ -52,11 +52,11 @@ const USED_RING_ADDR: u64 = align!(AVAIL_RING_ADDR + AVAIL_RING_SIZE, USED_RING_ // Virtio-queue size in bytes const QUEUE_BYTES_SIZE: usize = (USED_RING_ADDR + USED_RING_SIZE - DESC_TABLE_ADDR) as usize; -fuzz_target!(|bytes| { +fuzz_target!(|bytes: &[u8]| -> Corpus { if bytes.len() < (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE) || bytes.len() > (QUEUE_DATA_SIZE + QUEUE_BYTES_SIZE + MEM_SIZE) { - return; + return Corpus::Reject; } let mut rng = virtio_devices::Rng::new( @@ -86,10 +86,10 @@ fuzz_target!(|bytes| { .write_slice(queue_bytes, GuestAddress(DESC_TABLE_ADDR)) .is_err() { - return; + return Corpus::Reject; } if mem.write_slice(mem_bytes, GuestAddress(0 as u64)).is_err() { - return; + return Corpus::Reject; } let guest_memory = GuestMemoryAtomic::new(mem); @@ -108,6 +108,8 @@ fuzz_target!(|bytes| { // Wait for the events to finish and rng device worker thread to return rng.wait_for_epoll_threads(); + + Corpus::Keep }); pub struct NoopVirtioInterrupt {} diff --git a/fuzz/fuzz_targets/watchdog.rs b/fuzz/fuzz_targets/watchdog.rs index 0dec9ede7..f203a228f 100644 --- a/fuzz/fuzz_targets/watchdog.rs +++ b/fuzz/fuzz_targets/watchdog.rs @@ -7,7 +7,7 @@ use std::os::unix::io::{AsRawFd, FromRawFd}; use std::sync::Arc; -use libfuzzer_sys::fuzz_target; +use libfuzzer_sys::{fuzz_target, Corpus}; use seccompiler::SeccompAction; use virtio_devices::{VirtioDevice, VirtioInterrupt, VirtioInterruptType}; use virtio_queue::{Queue, QueueT}; @@ -30,9 +30,9 @@ const AVAIL_RING_SIZE: u64 = 6_u64 + 2 * QUEUE_SIZE as u64; // Guest physical address for used ring (requires to 4-bytes aligned) const USED_RING_ADDR: u64 = (AVAIL_RING_ADDR + AVAIL_RING_SIZE + 3) & !3_u64; -fuzz_target!(|bytes| { +fuzz_target!(|bytes: &[u8]| -> Corpus { if bytes.len() < QUEUE_DATA_SIZE || bytes.len() > (QUEUE_DATA_SIZE + MEM_SIZE) { - return; + return Corpus::Reject; } let mut watchdog = virtio_devices::Watchdog::new( @@ -53,7 +53,7 @@ fuzz_target!(|bytes| { // Setup the guest memory with the input bytes let mem = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), MEM_SIZE)]).unwrap(); if mem.write_slice(mem_bytes, GuestAddress(0 as u64)).is_err() { - return; + return Corpus::Reject; } let guest_memory = GuestMemoryAtomic::new(mem); @@ -73,6 +73,8 @@ fuzz_target!(|bytes| { // Wait for the events to finish and watchdog device worker thread to return watchdog.wait_for_epoll_threads(); + + Corpus::Keep }); pub struct NoopVirtioInterrupt {}