diff --git a/fuzzers/wcet_qemu_sys/.gitignore b/fuzzers/wcet_qemu_sys/.gitignore index 456d0151b4..0daf8ec693 100644 --- a/fuzzers/wcet_qemu_sys/.gitignore +++ b/fuzzers/wcet_qemu_sys/.gitignore @@ -3,3 +3,4 @@ demo *.ron *.bsp +tmp* diff --git a/fuzzers/wcet_qemu_sys/Cargo.toml b/fuzzers/wcet_qemu_sys/Cargo.toml index 7eba5fb3ab..75f939db12 100644 --- a/fuzzers/wcet_qemu_sys/Cargo.toml +++ b/fuzzers/wcet_qemu_sys/Cargo.toml @@ -7,7 +7,6 @@ edition = "2021" [features] default = ["std"] std = [] -showmap = [] [profile.release] debug = true diff --git a/fuzzers/wcet_qemu_sys/fuzzer.sh b/fuzzers/wcet_qemu_sys/fuzzer.sh new file mode 100755 index 0000000000..319fc1c1e9 --- /dev/null +++ b/fuzzers/wcet_qemu_sys/fuzzer.sh @@ -0,0 +1,4 @@ +mkdir -p tmp/test_in tmp/test_out +[ ! -f tmp/test_in/test ] && echo " !test" > tmp/test_in/test +[ ! -f tmp/dummy.qcow2 ] && qemu-img create -f qcow2 tmp/dummy.qcow2 32M +LD_LIBRARY_PATH=target/debug target/debug/fuzzer --libafl-snapshot tmp/dummy.qcow2 --libafl-out tmp/test_out --libafl-in tmp/test_in --libafl-kernel $@ diff --git a/fuzzers/wcet_qemu_sys/showmap.sh b/fuzzers/wcet_qemu_sys/showmap.sh new file mode 100755 index 0000000000..9cba846cdb --- /dev/null +++ b/fuzzers/wcet_qemu_sys/showmap.sh @@ -0,0 +1,4 @@ +mkdir -p tmp/test_in tmp/test_out +[ ! -f tmp/test_in/test ] && echo " !test" > tmp/test_in/test +[ ! -f tmp/dummy.qcow2 ] && qemu-img create -f qcow2 tmp/dummy.qcow2 32M +LD_LIBRARY_PATH=target/debug target/debug/showmap --libafl-snapshot tmp/dummy.qcow2 --libafl-out tmp/test_out --libafl-in tmp/test_in --libafl-kernel $@ diff --git a/fuzzers/wcet_qemu_sys/src/bin/fuzzer.rs b/fuzzers/wcet_qemu_sys/src/bin/fuzzer.rs index a71e55aa98..48eac07ef9 100644 --- a/fuzzers/wcet_qemu_sys/src/bin/fuzzer.rs +++ b/fuzzers/wcet_qemu_sys/src/bin/fuzzer.rs @@ -1,11 +1,6 @@ //! A singlethreaded QEMU fuzzer that can auto-restart. -use libafl::mutators::ByteFlipMutator; -use libafl::mutators::BitFlipMutator; -use wcet_qemu_sys::worst::LenTimeMaximizerCorpusScheduler; -use libafl::corpus::MinimizerCorpusScheduler; use hashbrown::HashMap; -use libafl::events::SimpleEventManager; use clap::{App, Arg}; use core::{cell::RefCell, time::Duration}; #[cfg(unix)] @@ -28,7 +23,7 @@ use libafl::{ tuples::{tuple_list, Merge}, }, corpus::{ - Corpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, PowerQueueCorpusScheduler, + Corpus, OnDiskCorpus, PowerQueueCorpusScheduler, }, executors::{ExitKind, ShadowExecutor, TimeoutExecutor}, feedback_or, @@ -40,13 +35,14 @@ use libafl::{ scheduled::havoc_mutations, token_mutations::I2SRandReplace, tokens_mutations, StdMOptMutator, StdScheduledMutator, Tokens, }, - observers::{TimeObserver, VariableMapObserver}, + observers::{VariableMapObserver}, stages::{ calibrate::CalibrationStage, power::{PowerMutationalStage, PowerSchedule}, ShadowTracingStage, StdMutationalStage, }, state::{HasCorpus, HasMetadata, StdState}, + events::SimpleEventManager, Error, }; use libafl_qemu::{ @@ -65,7 +61,7 @@ use libafl_qemu::{ clock::ClockFeedback, clock::QemuClockIncreaseFeedback }; -use wcet_qemu_sys::worst::{HitFeedback,HitcountsMapObserver,HitImprovingFeedback}; +use wcet_qemu_sys::worst::{HitFeedback,HitcountsMapObserver,HitImprovingFeedback,LenTimeMaximizerCorpusScheduler}; /// The fuzzer main @@ -121,6 +117,13 @@ pub fn main() { .long("libafl-edges") .takes_value(true), ) + .arg( + Arg::new("snapshot") + .help("The qcow2 file used for snapshots") + .long("libafl-snapshot") + .required(true) + .takes_value(true), + ) .try_get_matches_from(filter_qemu_args()) { Ok(res) => res, @@ -178,7 +181,9 @@ pub fn main() { None => None }; - fuzz(out_dir, crashes, in_dir, tokens, logfile, timeout, kernel, edges) + let snapshot = PathBuf::from(res.value_of("snapshot").unwrap().to_string()); + + fuzz(out_dir, crashes, in_dir, tokens, logfile, timeout, kernel, edges, snapshot) .expect("An error occurred while fuzzing"); } @@ -205,6 +210,7 @@ fn fuzz( timeout: Duration, kernel: PathBuf, dump_edges: Option, + snapshot: PathBuf, ) -> Result<(), Error> { env::remove_var("LD_LIBRARY_PATH"); @@ -217,7 +223,7 @@ fn fuzz( "--semihosting-config", "enable=on,target=native", "-kernel", kernel.to_str().unwrap(), "-serial", "stdio", "-nographic", - "-snapshot", "-drive", "if=none,format=qcow2,file=dummy.qcow2", + "-snapshot", "-drive", format!("if=none,format=qcow2,file={}",snapshot.to_string_lossy()).as_str(), "-icount", "shift=auto,align=off,sleep=off", "-S" ].iter().map(|x| x.to_string()).collect(); @@ -373,10 +379,8 @@ fn fuzz( unsafe { emu.write_mem(test_length_ptr,&(len as u32).to_le_bytes()); emu.write_mem(input_addr,buf); - // println!("{:#?}",edges_copy); emu.run(); - // println!("{:#?}",edges_copy); } ExitKind::Ok diff --git a/fuzzers/wcet_qemu_sys/src/bin/showmap.rs b/fuzzers/wcet_qemu_sys/src/bin/showmap.rs index ae692202fe..5baeb16cff 100644 --- a/fuzzers/wcet_qemu_sys/src/bin/showmap.rs +++ b/fuzzers/wcet_qemu_sys/src/bin/showmap.rs @@ -1,16 +1,9 @@ //! A singlethreaded QEMU fuzzer that can auto-restart. -use wcet_qemu_sys::worst::DumpMapFeedback; -use wcet_qemu_sys::worst::DummyFeedback; -use libafl_qemu::QemuInstrumentationFilter; -use wcet_qemu_sys::system_trace::QemuSystemStateHelper; -use libafl_qemu::QemuExecutor; -use libafl::Evaluator; -use libafl::inputs::Input; -use libafl::corpus::InMemoryCorpus; -use libafl::events::SimpleEventManager; -use libafl::stats::SimpleStats; -use wcet_qemu_sys::worst::HitcountsMapObserver; +use wcet_qemu_sys::{ + worst::{DumpMapFeedback,DummyFeedback,HitcountsMapObserver}, + system_trace::QemuSystemStateHelper, +}; use clap::{App, Arg}; use std::{ env, @@ -24,21 +17,26 @@ use libafl::{ rands::StdRand, tuples::{tuple_list}, }, - corpus::{QueueCorpusScheduler}, + corpus::{InMemoryCorpus,QueueCorpusScheduler}, executors::{ExitKind}, fuzzer::{StdFuzzer}, - inputs::{BytesInput, HasTargetBytes}, + inputs::{Input,BytesInput, HasTargetBytes}, observers::{VariableMapObserver}, state::{StdState}, Error, + Evaluator, + stats::SimpleStats, + events::SimpleEventManager, }; use libafl_qemu::{ edges, edges::QemuEdgeCoverageHelper, emu::Emulator, filter_qemu_args, - snapshot_sys::QemuSysSnapshotHelper, elf::EasyElf, + snapshot_sys::QemuSysSnapshotHelper, clock::{QemuClockObserver}, + QemuInstrumentationFilter, + QemuExecutor, }; @@ -90,6 +88,13 @@ pub fn main() { .long("libafl-edges") .takes_value(true), ) + .arg( + Arg::new("snapshot") + .help("The qcow2 file used for snapshots") + .long("libafl-snapshot") + .required(true) + .takes_value(true), + ) .try_get_matches_from(filter_qemu_args()) { Ok(res) => res, @@ -135,8 +140,9 @@ pub fn main() { None => None }; + let snapshot = PathBuf::from(res.value_of("snapshot").unwrap().to_string()); - fuzz(in_dir, kernel, edges) + fuzz(in_dir, kernel, edges, snapshot) .expect("An error occurred while fuzzing"); } @@ -158,6 +164,7 @@ fn fuzz( seed_dir: PathBuf, kernel: PathBuf, dump_edges: Option, + snapshot: PathBuf, ) -> Result<(), Error> { //=========== Setup emulator let mut env: Vec<(String, String)> = env::vars().collect(); @@ -169,7 +176,7 @@ fn fuzz( "--semihosting-config", "enable=on,target=native", "-kernel", kernel.to_str().unwrap(), "-serial", "stdio", "-nographic", - "-snapshot", "-drive", "if=none,format=qcow2,file=dummy.qcow2", + "-snapshot", "-drive", format!("if=none,format=qcow2,file={}",snapshot.to_string_lossy()).as_str(), "-icount", "shift=auto,align=off,sleep=off", "-S" ].iter().map(|x| x.to_string()).collect(); diff --git a/fuzzers/wcet_qemu_sys/src/worst.rs b/fuzzers/wcet_qemu_sys/src/worst.rs index 165694c599..45257d7fe2 100644 --- a/fuzzers/wcet_qemu_sys/src/worst.rs +++ b/fuzzers/wcet_qemu_sys/src/worst.rs @@ -175,8 +175,6 @@ where EM: EventFirer, OT: ObserversTuple, { - // TODO Replace with match_name_type when stable - // let observer = _observers.match_name::>("edges").expect("SelectedEdgeObserver not found"); let observer = _observers.match_name::>>("edges") .expect("HitcountsMapObserver not found"); if self.target_map.len() == 0 { return Ok(true) }; @@ -190,8 +188,8 @@ where } let mean_sum_of_squares = (sum_of_square_difference as f64) / (self.target_map.len() as f64); let hit_target = mean_sum_of_squares <= self.target_msd; - // eprintln!("hit target: {} {} {:?}",hit_target,mean_sum_of_squares, _input); if hit_target { + #[cfg(debug_assertions)] eprintln!("Hit Feedback trigger"); Ok(true) } else { Ok(false) @@ -305,8 +303,6 @@ where EM: EventFirer, OT: ObserversTuple, { - // TODO Replace with match_name_type when stable - // let observer = _observers.match_name::>("edges").expect("SelectedEdgeObserver not found"); let observer = _observers.match_name::>>("edges") .expect("HitcountsMapObserver not found"); if self.target_map.len() == 0 { return Ok(true) }; @@ -320,9 +316,8 @@ where } let mean_sum_of_squares = (sum_of_square_difference as f64) / (self.target_map.len() as f64); let hit_target = mean_sum_of_squares < self.best_msd; - // eprintln!("improving: {}",hit_target); if hit_target { - // println!("Hit Improving: {}",mean_sum_of_squares); + #[cfg(debug_assertions)] eprintln!("Hit Improving: {}",mean_sum_of_squares); self.best_msd = mean_sum_of_squares; Ok(true) } else { @@ -383,7 +378,7 @@ where fs::write(s,ron::to_string(&observer.edgemap).expect("Error serializing hashmap")).expect("Can not dump to file"); self.dumpfile = None }, - None => ()//println!("{:#?}",observer.edgemap), + None => println!("{:?}",observer.edgemap), }; Ok(true) } @@ -507,7 +502,6 @@ where I: Input + HasLen, { fn compute(entry: &mut Testcase) -> Result { - // TODO maybe enforce entry.exec_time().is_some() let execs_per_hour = (3600.0/entry.exec_time().expect("testcase.exec_time is needed for scheduler").as_secs_f64()) as u64; let execs_times_length_per_hour = execs_per_hour*entry.cached_len()? as u64; Ok(execs_times_length_per_hour) diff --git a/fuzzers/wcet_qemu_sys/starter.sh b/fuzzers/wcet_qemu_sys/starter.sh deleted file mode 100755 index a933fd629c..0000000000 --- a/fuzzers/wcet_qemu_sys/starter.sh +++ /dev/null @@ -1,3 +0,0 @@ -mkdir -p target/test_in target/test_out -[ ! -f target/test_in/test ] && echo " !test" > target/test_in/test -LD_LIBRARY_PATH=target/debug target/debug/wcet_qemu_sys --libafl-out target/test_out --libafl-in target/test_in --libafl-kernel $@