Change qemu_cmin to use snapshots (#2939)
* Change qemu_cmin to use snapshots * Use features to support both fork and snapshot modes --------- Co-authored-by: Your Name <you@example.com>
This commit is contained in:
parent
b7fcfdd192
commit
4cb4b6df77
@ -15,7 +15,9 @@ edition = "2021"
|
||||
debug = true
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
default = ["std", "snapshot"]
|
||||
fork = []
|
||||
snapshot = []
|
||||
std = []
|
||||
be = ["libafl_qemu/be"]
|
||||
arm = ["libafl_qemu/arm"]
|
||||
|
@ -2,12 +2,14 @@
|
||||
//!
|
||||
#[cfg(feature = "i386")]
|
||||
use core::mem::size_of;
|
||||
#[cfg(feature = "snapshot")]
|
||||
use core::time::Duration;
|
||||
use std::{env, fmt::Write, io, path::PathBuf, process, ptr::NonNull};
|
||||
|
||||
use clap::{builder::Str, Parser};
|
||||
use libafl::{
|
||||
corpus::{Corpus, InMemoryOnDiskCorpus, NopCorpus},
|
||||
events::{EventRestarter, SendExiting, SimpleRestartingEventManager},
|
||||
events::{SendExiting, SimpleRestartingEventManager},
|
||||
executors::ExitKind,
|
||||
feedbacks::MaxMapFeedback,
|
||||
fuzzer::StdFuzzer,
|
||||
@ -26,13 +28,20 @@ use libafl_bolts::{
|
||||
tuples::tuple_list,
|
||||
AsSlice, AsSliceMut,
|
||||
};
|
||||
#[cfg(feature = "fork")]
|
||||
use libafl_qemu::QemuForkExecutor;
|
||||
use libafl_qemu::{
|
||||
elf::EasyElf, modules::edges::StdEdgeCoverageChildModule, ArchExtras, CallingConvention,
|
||||
Emulator, GuestAddr, GuestReg, MmapPerms, QemuExitError, QemuExitReason, QemuForkExecutor,
|
||||
QemuShutdownCause, Regs,
|
||||
Emulator, GuestAddr, GuestReg, MmapPerms, QemuExitError, QemuExitReason, QemuShutdownCause,
|
||||
Regs,
|
||||
};
|
||||
#[cfg(feature = "snapshot")]
|
||||
use libafl_qemu::{modules::SnapshotModule, QemuExecutor};
|
||||
use libafl_targets::{EDGES_MAP_DEFAULT_SIZE, EDGES_MAP_PTR};
|
||||
|
||||
#[cfg(all(feature = "fork", feature = "snapshot"))]
|
||||
compile_error!("Cannot enable both 'fork' and 'snapshot' features at the same time.");
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Version;
|
||||
|
||||
@ -130,10 +139,19 @@ pub fn fuzz() -> Result<(), Error> {
|
||||
))
|
||||
};
|
||||
|
||||
#[cfg(feature = "fork")]
|
||||
let modules = tuple_list!(StdEdgeCoverageChildModule::builder()
|
||||
.const_map_observer(edges_observer.as_mut())
|
||||
.build()?);
|
||||
|
||||
#[cfg(feature = "snapshot")]
|
||||
let modules = tuple_list!(
|
||||
StdEdgeCoverageChildModule::builder()
|
||||
.const_map_observer(edges_observer.as_mut())
|
||||
.build()?,
|
||||
SnapshotModule::new()
|
||||
);
|
||||
|
||||
let emulator = Emulator::empty()
|
||||
.qemu_parameters(options.args)
|
||||
.modules(modules)
|
||||
@ -198,6 +216,7 @@ pub fn fuzz() -> Result<(), Error> {
|
||||
let scheduler = QueueScheduler::new();
|
||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||
|
||||
#[cfg(feature = "fork")]
|
||||
let mut harness = |_emulator: &mut Emulator<_, _, _, _, _, _, _>, input: &BytesInput| {
|
||||
let target = input.target_bytes();
|
||||
let mut buf = target.as_slice();
|
||||
@ -232,6 +251,43 @@ pub fn fuzz() -> Result<(), Error> {
|
||||
ExitKind::Ok
|
||||
};
|
||||
|
||||
#[cfg(feature = "snapshot")]
|
||||
let mut harness =
|
||||
|_emulator: &mut Emulator<_, _, _, _, _, _, _>, _state: &mut _, input: &BytesInput| {
|
||||
let target = input.target_bytes();
|
||||
let mut buf = target.as_slice();
|
||||
let mut len = buf.len();
|
||||
if len > MAX_INPUT_SIZE {
|
||||
buf = &buf[0..MAX_INPUT_SIZE];
|
||||
len = MAX_INPUT_SIZE;
|
||||
}
|
||||
let len = len as GuestReg;
|
||||
|
||||
unsafe {
|
||||
qemu.write_mem(input_addr, buf).expect("qemu write failed.");
|
||||
|
||||
qemu.write_reg(Regs::Pc, test_one_input_ptr).unwrap();
|
||||
qemu.write_reg(Regs::Sp, stack_ptr).unwrap();
|
||||
qemu.write_return_address(ret_addr).unwrap();
|
||||
qemu.write_function_argument(CallingConvention::Cdecl, 0, input_addr)
|
||||
.unwrap();
|
||||
qemu.write_function_argument(CallingConvention::Cdecl, 1, len)
|
||||
.unwrap();
|
||||
|
||||
match qemu.run() {
|
||||
Ok(QemuExitReason::Breakpoint(_)) => {}
|
||||
Ok(QemuExitReason::End(QemuShutdownCause::HostSignal(
|
||||
Signal::SigInterrupt,
|
||||
))) => process::exit(0),
|
||||
Err(QemuExitError::UnexpectedExit) => return ExitKind::Crash,
|
||||
_ => panic!("Unexpected QEMU exit."),
|
||||
}
|
||||
}
|
||||
|
||||
ExitKind::Ok
|
||||
};
|
||||
|
||||
#[cfg(feature = "fork")]
|
||||
let mut executor = QemuForkExecutor::new(
|
||||
emulator,
|
||||
&mut harness,
|
||||
@ -243,6 +299,17 @@ pub fn fuzz() -> Result<(), Error> {
|
||||
core::time::Duration::from_millis(5000),
|
||||
)?;
|
||||
|
||||
#[cfg(feature = "snapshot")]
|
||||
let mut executor = QemuExecutor::new(
|
||||
emulator,
|
||||
&mut harness,
|
||||
tuple_list!(edges_observer),
|
||||
&mut fuzzer,
|
||||
&mut state,
|
||||
&mut mgr,
|
||||
Duration::from_millis(5000),
|
||||
)?;
|
||||
|
||||
println!("Importing {} seeds...", files.len());
|
||||
|
||||
if state.must_load_initial_inputs() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user