add random generator fuzzer

This commit is contained in:
Alwin Berger 2022-06-08 02:21:17 +02:00
parent 4dabfc5f00
commit 6969b5de5a
2 changed files with 32 additions and 10 deletions

View File

@ -10,6 +10,7 @@ std = []
multicore = []
fuzz_interrupt = [] # use the first bytes of the input for a timed interrupts
fuzz_random = [] # just process random inputs
# select which feedbacks to use. enable at least one.
feed_known_edges = []

View File

@ -1,4 +1,6 @@
//! A singlethreaded QEMU fuzzer that can auto-restart.
use libafl::Evaluator;
use libafl::generators::Generator;
use core::cmp::min;
use wcet_qemu_sys::sysstate::mutators::InterruptShifterMutator;
use wcet_qemu_sys::sysstate::IRQ_INPUT_OFFSET;
@ -43,6 +45,7 @@ use wcet_qemu_sys::minimizer::QemuCaseMinimizerStage;
use hashbrown::HashMap;
use clap::{App, Arg};
use core::{cell::RefCell, time::Duration};
use std::time::SystemTime;
#[cfg(unix)]
use nix::{self, unistd::dup};
#[cfg(unix)]
@ -441,6 +444,8 @@ fn fuzz(
let feedback = ClockFeedback::new_with_observer(&clock_observer);
#[cfg(all(not(feature = "feed_state"), feature = "dump_infos"))] // for diagnostic purposes it's necessary to collect the state in any case
let feedback = feedback_or!(feedback, DumpSystraceFeedback::metadata_only());
#[cfg(all(feature = "obj_collect", feature = "fuzz_random"))] // random fuzzing does not trigger objective feedbacks
let feedback = feedback_or!(feedback, ExecTimeCollectorFeedback::new());
#[cfg(feature = "dump_infos")] // for diagnostic purposes it's necessary to collect the state in any case
let feedback = feedback_or!(feedback, DumpMapFeedback::metadata_only(&edges_observer));
#[cfg(feature = "feed_known_edges")]
@ -456,7 +461,7 @@ fn fuzz(
// A feedback to choose if an input is a solution or not
let objective = DummyFeedback::new(false);
#[cfg(feature = "obj_collect")]
#[cfg(all(feature = "obj_collect",not(feature = "fuzz_random")))]
let objective = ExecTimeCollectorFeedback::new();
#[cfg(feature = "obj_trace")]
let objective = feedback_or!(HitSysStateFeedback::new(target_trace));
@ -599,6 +604,7 @@ fn fuzz(
}
}
#[cfg(not(feature = "fuzz_random"))]
if state.corpus().count() < 1 {
if _core_id == 0 && state.load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &[seed_dir.clone()]).is_ok() {
// println!("We imported {} inputs from disk.", state.corpus().count());
@ -632,14 +638,30 @@ fn fuzz(
dup2(null_fd, io::stderr().as_raw_fd())?;
}
match fuzztime {
Some(t) => fuzzer
.fuzz_for_solution_or_n(&mut stages, &mut executor, &mut state, &mut mgr, t)
.expect("Error in the fuzzing loop"),
None => fuzzer
.fuzz_for_solution(&mut stages, &mut executor, &mut state, &mut mgr)
.expect("Error in the fuzzing loop"),
};
#[cfg(not(feature = "fuzz_random"))]
{
match fuzztime {
Some(t) => fuzzer
.fuzz_for_solution_or_n(&mut stages, &mut executor, &mut state, &mut mgr, t)
.expect("Error in the fuzzing loop"),
None => fuzzer
.fuzz_for_solution(&mut stages, &mut executor, &mut state, &mut mgr)
.expect("Error in the fuzzing loop"),
};
}
#[cfg(feature = "fuzz_random")]
{
let mut generator = RandBytesGenerator::new(32);
let target_duration = Duration::from_secs(fuzztime.expect("Random fuzzing needs target time"));
let start_time = SystemTime::now();
while start_time.elapsed().unwrap() < target_duration {
let inp = generator.generate(&mut state).unwrap();
fuzzer.evaluate_input(&mut state, &mut executor, &mut mgr, inp);
}
match fuzzer.fuzz_for_solution_or_n(&mut stages, &mut executor, &mut state, &mut mgr, 0) {
_ => (),
} // Just here for the typecheker
}
#[cfg(not(feature = "benchmark"))]
@ -676,7 +698,6 @@ fn fuzz(
#[cfg(feature = "dump_infos")]
{
println!("Start dumping {}", state.corpus().count());
let c = if state.solutions().count()>0 { state.solutions() } else { state.corpus() };
let mut worst = Duration::new(0,0);
let mut worst_input : Option<Vec<u8>> = Some(vec![]);