diff --git a/fuzzers/FRET/Cargo.toml b/fuzzers/FRET/Cargo.toml index 6d47060df7..dbd105cb40 100644 --- a/fuzzers/FRET/Cargo.toml +++ b/fuzzers/FRET/Cargo.toml @@ -62,6 +62,7 @@ debug = true [dependencies] libafl = { path = "../../libafl/", features = ["multipart_inputs", "prelude"] } libafl_bolts = { path = "../../libafl_bolts/" } +libafl_targets = { path = "../../libafl_targets/" } libafl_qemu = { path = "../../libafl_qemu/", features = ["arm", "systemmode"], default-features = false } serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib serde_json = { version = "1.0", default-features = false, features = ["alloc"] } diff --git a/fuzzers/FRET/src/fuzzer.rs b/fuzzers/FRET/src/fuzzer.rs index ae4f8d4b17..f25ae9b4ae 100644 --- a/fuzzers/FRET/src/fuzzer.rs +++ b/fuzzers/FRET/src/fuzzer.rs @@ -10,8 +10,9 @@ use libafl::{ common::{HasMetadata, HasNamedMetadata}, corpus::{Corpus, InMemoryCorpus, OnDiskCorpus}, events::{launcher::Launcher, EventConfig}, executors::ExitKind, feedback_or, feedback_or_fast, feedbacks::{CrashFeedback, MaxMapFeedback, TimeoutFeedback}, fuzzer::{Fuzzer, StdFuzzer}, inputs::{multi::MultipartInput, BytesInput, HasTargetBytes, Input}, monitors::MultiMonitor, observers::{CanTrack, VariableMapObserver}, prelude::{havoc_mutations, minimizer::TopRatedsMetadata, CorpusId, Generator, HitcountsMapObserver, RandBytesGenerator, SimpleEventManager, SimpleMonitor, SimplePrintingMonitor, SimpleRestartingEventManager, StdScheduledMutator}, schedulers::QueueScheduler, stages::StdMutationalStage, state::{HasCorpus, StdState}, Error, Evaluator }; use libafl_qemu::{ -elf::EasyElf, emu::Emulator, modules::{edges::{self}, FilterList}, GuestAddr, GuestPhysAddr, QemuExecutor, QemuExitReason, QemuHooks, Regs +elf::EasyElf, emu::Emulator, modules::{edges::{self}, EdgeCoverageModule, FilterList, StdAddressFilter, StdEdgeCoverageModule}, GuestAddr, GuestPhysAddr, QemuExecutor, QemuExitReason, QemuHooks, Regs }; +use libafl_targets::{edges_map_mut_ptr, EDGES_MAP_DEFAULT_SIZE, MAX_EDGES_FOUND}; use rand::{SeedableRng, StdRng, Rng}; use crate::{ config::{get_target_ranges, get_target_symbols}, systemstate::{self, feedbacks::{DumpSystraceFeedback, SystraceErrorFeedback}, helpers::{get_function_range, load_symbol, try_load_symbol}, mutational::{input_bytes_to_interrupt_times, InterruptShiftStage, STGSnippetStage}, observers::QemuSystemStateObserver, schedulers::{GenerationScheduler, LongestTraceScheduler}, stg::{stg_map_mut_slice, GraphMaximizerCorpusScheduler, STGEdge, STGNode, StgFeedback, MAX_STG_NUM}, target_os::freertos::{config::get_range_groups, qemu_module::FreeRTOSSystemStateHelper, FreeRTOSSystem}}, time::{ @@ -199,7 +200,7 @@ if let Ok(seed) = env::var("SEED_RANDOM") { let denylist: Vec<_> = TARGET_GROUPS["ISR_FN"].values().map(|x| x.clone()).collect(); -let denylist = FilterList::DenyList(denylist); // do not count isr jumps, which are useless +let denylist = StdAddressFilter::deny_list(denylist); // do not count isr jumps, which are useless /// Setup the interrupt inputs. Noop if interrupts are not fuzzed fn setup_interrupt_inputs(mut input : MultipartInput, interrupt_config : &Vec<(usize,u32)>, mut random: Option<&mut StdRng>) -> MultipartInput { @@ -325,13 +326,15 @@ let run_client = |state: Option<_>, mut mgr, _core_id| { // Create an observation channel using the coverage map #[cfg(feature = "observe_edges")] - let edges_observer = unsafe { VariableMapObserver::from_mut_slice( + let mut edges_observer = unsafe { VariableMapObserver::from_mut_slice( "edges", - OwnedMutSlice::from_raw_parts_mut(edges_map_mut_ptr(), EDGES_MAP_SIZE_IN_USE), + OwnedMutSlice::from_raw_parts_mut(edges_map_mut_ptr(), EDGES_MAP_DEFAULT_SIZE), addr_of_mut!(MAX_EDGES_FOUND), - )}.track_indices(); + )}; #[cfg(feature = "observe_hitcounts")] - let edges_observer = HitcountsMapObserver::new(edges_observer).track_indices(); + let mut edges_observer = HitcountsMapObserver::new(edges_observer); + #[cfg(feature = "observe_edges")] + let mut edges_observer = edges_observer.track_indices(); #[cfg(feature = "observe_systemstate")] let stg_coverage_observer = unsafe { VariableMapObserver::from_mut_slice( @@ -370,7 +373,7 @@ let run_client = |state: Option<_>, mut mgr, _core_id| { #[cfg(all(feature = "observe_systemstate"))] let mut feedback = feedback_or!( feedback, - DumpSystraceFeedback::::with_dump(if cli.dump_traces {cli.dump_name.clone().map(|x| x.with_extension("trace.ron"))} else {None}) + DumpSystraceFeedback::::with_dump(if cli.dump_traces {cli.dump_name.clone().map(|x| x.with_extension("trace.ron"))} else {None}, &cli.select_task) ); #[cfg(feature = "trace_stg")] let mut feedback = feedback_or!( @@ -426,7 +429,12 @@ let run_client = |state: Option<_>, mut mgr, _core_id| { #[cfg(feature = "observe_systemstate")] let qhelpers = (FreeRTOSSystemStateHelper::new(&TARGET_SYMBOLS,&TARGET_RANGES,&TARGET_GROUPS), qhelpers); #[cfg(feature = "observe_edges")] - let qhelpers = (QemuEdgeCoverageHelper::new(denylist, QemuFilterList::None), qhelpers); + let qhelpers = ( + StdEdgeCoverageModule::builder() + .map_observer(edges_observer.as_mut()) + .address_filter(denylist) + .build() + .unwrap(), qhelpers);//StdEdgeCoverageModule::new(denylist, FilterList::None), qhelpers); let qhelpers = (QemuStateRestoreHelper::with_fast(initial_snap), qhelpers); let emulator = Emulator::empty().qemu(qemu).modules(qhelpers).build().unwrap(); diff --git a/fuzzers/FRET/src/systemstate/feedbacks.rs b/fuzzers/FRET/src/systemstate/feedbacks.rs index ffbe67d227..19b7870a61 100644 --- a/fuzzers/FRET/src/systemstate/feedbacks.rs +++ b/fuzzers/FRET/src/systemstate/feedbacks.rs @@ -350,13 +350,13 @@ where } } #[allow(unused)] - pub fn with_dump(dumpfile: Option) -> Self { + pub fn with_dump(dumpfile: Option, select_task: &Option) -> Self { Self { name: Cow::from("Dumpsystemstate".to_string()), dumpfile: dumpfile, dump_metadata: false, phantom: PhantomData, - select_task: None, + select_task: select_task.clone(), } } #[allow(unused)] diff --git a/fuzzers/FRET/src/systemstate/stg.rs b/fuzzers/FRET/src/systemstate/stg.rs index b550a21e18..5dcc4a7065 100644 --- a/fuzzers/FRET/src/systemstate/stg.rs +++ b/fuzzers/FRET/src/systemstate/stg.rs @@ -322,8 +322,8 @@ impl HasRefCnt for STGNodeMetadata { libafl_bolts::impl_serdeany!(STGNodeMetadata); -pub type GraphMaximizerCorpusScheduler = - MinimizerScheduler,STGNodeMetadata,O>; +pub type GraphMaximizerCorpusScheduler = + MinimizerScheduler; // AI generated, human verified /// Count the occurrences of each element in a vector, assumes the vector is sorted diff --git a/fuzzers/FRET/src/time/worst.rs b/fuzzers/FRET/src/time/worst.rs index 3d9e41ad42..2e4744754b 100644 --- a/fuzzers/FRET/src/time/worst.rs +++ b/fuzzers/FRET/src/time/worst.rs @@ -45,21 +45,18 @@ use std::borrow::Cow; //=========================== Scheduler pub type TimeMaximizerCorpusScheduler = - MinimizerScheduler::State>, MapIndexesMetadata, O>; + MinimizerScheduler; /// Multiply the testcase size with the execution time. /// This favors small and quick testcases. #[derive(Debug, Clone)] -pub struct MaxTimeFavFactor -where - S: HasCorpus + HasMetadata, +pub struct MaxTimeFavFactor { - phantom: PhantomData, } -impl TestcaseScore for MaxTimeFavFactor +impl TestcaseScore for MaxTimeFavFactor where - S: HasCorpus + HasMetadata, + S: HasCorpus, { fn compute(state: &S, entry: &mut Testcase<::Input> ) -> Result { // TODO maybe enforce entry.exec_time().is_some() @@ -73,7 +70,7 @@ pub type LenTimeMaximizerCorpusScheduler = MinimizerScheduler::State>, MapIndexesMetadata, O>; pub type TimeStateMaximizerCorpusScheduler = - MinimizerScheduler::State>, ::TraceData, O>; + MinimizerScheduler::TraceData, O>; /// Multiply the testcase size with the execution time. /// This favors small and quick testcases. @@ -433,7 +430,7 @@ pub type TimeProbMassScheduler = #[derive(Debug, Clone)] pub struct TimeProbFactor where - S: HasCorpus + HasMetadata, + S: HasCorpus, { phantom: PhantomData, } @@ -444,7 +441,7 @@ where impl TestcaseScore for TimeProbFactor where - S: HasCorpus + HasMetadata, + S: HasCorpus, { fn compute(_state: &S, entry: &mut Testcase<::Input>) -> Result { // TODO maybe enforce entry.exec_time().is_some()