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
|
debug = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std", "snapshot"]
|
||||||
|
fork = []
|
||||||
|
snapshot = []
|
||||||
std = []
|
std = []
|
||||||
be = ["libafl_qemu/be"]
|
be = ["libafl_qemu/be"]
|
||||||
arm = ["libafl_qemu/arm"]
|
arm = ["libafl_qemu/arm"]
|
||||||
|
@ -2,12 +2,14 @@
|
|||||||
//!
|
//!
|
||||||
#[cfg(feature = "i386")]
|
#[cfg(feature = "i386")]
|
||||||
use core::mem::size_of;
|
use core::mem::size_of;
|
||||||
|
#[cfg(feature = "snapshot")]
|
||||||
|
use core::time::Duration;
|
||||||
use std::{env, fmt::Write, io, path::PathBuf, process, ptr::NonNull};
|
use std::{env, fmt::Write, io, path::PathBuf, process, ptr::NonNull};
|
||||||
|
|
||||||
use clap::{builder::Str, Parser};
|
use clap::{builder::Str, Parser};
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{Corpus, InMemoryOnDiskCorpus, NopCorpus},
|
corpus::{Corpus, InMemoryOnDiskCorpus, NopCorpus},
|
||||||
events::{EventRestarter, SendExiting, SimpleRestartingEventManager},
|
events::{SendExiting, SimpleRestartingEventManager},
|
||||||
executors::ExitKind,
|
executors::ExitKind,
|
||||||
feedbacks::MaxMapFeedback,
|
feedbacks::MaxMapFeedback,
|
||||||
fuzzer::StdFuzzer,
|
fuzzer::StdFuzzer,
|
||||||
@ -26,13 +28,20 @@ use libafl_bolts::{
|
|||||||
tuples::tuple_list,
|
tuples::tuple_list,
|
||||||
AsSlice, AsSliceMut,
|
AsSlice, AsSliceMut,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "fork")]
|
||||||
|
use libafl_qemu::QemuForkExecutor;
|
||||||
use libafl_qemu::{
|
use libafl_qemu::{
|
||||||
elf::EasyElf, modules::edges::StdEdgeCoverageChildModule, ArchExtras, CallingConvention,
|
elf::EasyElf, modules::edges::StdEdgeCoverageChildModule, ArchExtras, CallingConvention,
|
||||||
Emulator, GuestAddr, GuestReg, MmapPerms, QemuExitError, QemuExitReason, QemuForkExecutor,
|
Emulator, GuestAddr, GuestReg, MmapPerms, QemuExitError, QemuExitReason, QemuShutdownCause,
|
||||||
QemuShutdownCause, Regs,
|
Regs,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "snapshot")]
|
||||||
|
use libafl_qemu::{modules::SnapshotModule, QemuExecutor};
|
||||||
use libafl_targets::{EDGES_MAP_DEFAULT_SIZE, EDGES_MAP_PTR};
|
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)]
|
#[derive(Default)]
|
||||||
pub struct Version;
|
pub struct Version;
|
||||||
|
|
||||||
@ -130,10 +139,19 @@ pub fn fuzz() -> Result<(), Error> {
|
|||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "fork")]
|
||||||
let modules = tuple_list!(StdEdgeCoverageChildModule::builder()
|
let modules = tuple_list!(StdEdgeCoverageChildModule::builder()
|
||||||
.const_map_observer(edges_observer.as_mut())
|
.const_map_observer(edges_observer.as_mut())
|
||||||
.build()?);
|
.build()?);
|
||||||
|
|
||||||
|
#[cfg(feature = "snapshot")]
|
||||||
|
let modules = tuple_list!(
|
||||||
|
StdEdgeCoverageChildModule::builder()
|
||||||
|
.const_map_observer(edges_observer.as_mut())
|
||||||
|
.build()?,
|
||||||
|
SnapshotModule::new()
|
||||||
|
);
|
||||||
|
|
||||||
let emulator = Emulator::empty()
|
let emulator = Emulator::empty()
|
||||||
.qemu_parameters(options.args)
|
.qemu_parameters(options.args)
|
||||||
.modules(modules)
|
.modules(modules)
|
||||||
@ -198,6 +216,7 @@ pub fn fuzz() -> Result<(), Error> {
|
|||||||
let scheduler = QueueScheduler::new();
|
let scheduler = QueueScheduler::new();
|
||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
|
#[cfg(feature = "fork")]
|
||||||
let mut harness = |_emulator: &mut Emulator<_, _, _, _, _, _, _>, input: &BytesInput| {
|
let mut harness = |_emulator: &mut Emulator<_, _, _, _, _, _, _>, input: &BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let mut buf = target.as_slice();
|
let mut buf = target.as_slice();
|
||||||
@ -232,6 +251,43 @@ pub fn fuzz() -> Result<(), Error> {
|
|||||||
ExitKind::Ok
|
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(
|
let mut executor = QemuForkExecutor::new(
|
||||||
emulator,
|
emulator,
|
||||||
&mut harness,
|
&mut harness,
|
||||||
@ -243,6 +299,17 @@ pub fn fuzz() -> Result<(), Error> {
|
|||||||
core::time::Duration::from_millis(5000),
|
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());
|
println!("Importing {} seeds...", files.len());
|
||||||
|
|
||||||
if state.must_load_initial_inputs() {
|
if state.must_load_initial_inputs() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user