-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a new target to fuzz parsing and executing virtio-blk requests from descriptor chains. This new target mimicks some aspects of the virtio-vsock one. It uses a memfd file to simulate an actual backend for the device, using the backend-stdio feature of the crate. Signed-off-by: Carlos López <carlos.lopez@suse.com>
- virtio-vsock-v0.8.0
- virtio-vsock-v0.7.0
- virtio-vsock-v0.6.0
- virtio-vsock-v0.5.0
- virtio-queue-v0.14.0
- virtio-queue-v0.13.0
- virtio-queue-v0.12.0
- virtio-queue-v0.11.0
- virtio-queue-v0.10.0
- virtio-queue-ser-v0.11.0
- virtio-queue-ser-v0.10.0
- virtio-queue-ser-v0.9.0
- virtio-queue-ser-v0.8.0
- virtio-queue-ser-v0.7.0
- virtio-bindings-v0.2.4
- virtio-bindings-v0.2.3
- virtio-bindings-v0.2.2
Showing
5 changed files
with
69 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
use crate::FuzzingDescriptor; | ||
use serde::{Deserialize, Serialize}; | ||
|
||
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] | ||
pub struct BlkInput { | ||
pub descriptors: Vec<FuzzingDescriptor>, | ||
pub guestmem: Vec<(u64, Vec<u8>)>, | ||
pub features: u64, | ||
pub device_id: Option<[u8; 20]>, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#![no_main] | ||
|
||
use common::blk::BlkInput; | ||
use common::virtio_queue::DEFAULT_QUEUE_SIZE; | ||
use libfuzzer_sys::fuzz_target; | ||
use std::hint::black_box; | ||
use virtio_blk::request::Request; | ||
use virtio_blk::stdio_executor::StdIoBackend; | ||
use virtio_queue::{mock::MockSplitQueue, Descriptor}; | ||
use vm_memory::{Bytes, GuestAddress, GuestMemoryMmap}; | ||
|
||
fuzz_target!(|data: &[u8]| { | ||
let Ok(fuzz_input) = bincode::deserialize::<BlkInput>(data) else { | ||
return; | ||
}; | ||
|
||
let start_addr = GuestAddress(0x1000); | ||
// Create and randomly populate the guest memory | ||
let m = GuestMemoryMmap::<()>::from_ranges(&[(start_addr, 0x11000)]).unwrap(); | ||
for (addr, mem) in fuzz_input.guestmem.iter() { | ||
let _ = m.write_slice(mem, GuestAddress(*addr)); | ||
} | ||
|
||
let vq = MockSplitQueue::create(&m, start_addr, DEFAULT_QUEUE_SIZE); | ||
|
||
let descriptors: Vec<Descriptor> = fuzz_input | ||
.descriptors | ||
.iter() | ||
.map(|desc| (*desc).into()) | ||
.collect(); | ||
|
||
// A backing in-memory file | ||
let memfile = memfd::MemfdOptions::default() | ||
.create("fuzzfile") | ||
.unwrap() | ||
.into_file(); | ||
|
||
// A backend that can execute a virtio-blk request | ||
let mut backend = StdIoBackend::new(memfile, fuzz_input.features).unwrap(); | ||
if let Some(id) = fuzz_input.device_id { | ||
backend = backend.with_device_id(id); | ||
} | ||
|
||
// Build a descriptor chain, parse and execute a request | ||
if let Ok(mut chain) = vq.build_desc_chain(&descriptors) { | ||
if let Ok(req) = Request::parse(&mut chain) { | ||
// Ensure the compiler does not optimize the request away | ||
let _ = black_box(backend.process_request(&m, &req)); | ||
}; | ||
} | ||
}); |