diff --git a/fuzzers/wcet_qemu_sys/Cargo.toml b/fuzzers/wcet_qemu_sys/Cargo.toml index 11875ac0da..d6dd0056bd 100644 --- a/fuzzers/wcet_qemu_sys/Cargo.toml +++ b/fuzzers/wcet_qemu_sys/Cargo.toml @@ -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 = [] diff --git a/fuzzers/wcet_qemu_sys/src/bin/fuzzer.rs b/fuzzers/wcet_qemu_sys/src/bin/fuzzer.rs index 3c2f1bd41e..255000666f 100644 --- a/fuzzers/wcet_qemu_sys/src/bin/fuzzer.rs +++ b/fuzzers/wcet_qemu_sys/src/bin/fuzzer.rs @@ -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> = Some(vec![]);