From 5b7d307a6a6397f3d33e41ea22bd4bb7a93872e2 Mon Sep 17 00:00:00 2001 From: "Dongjia \"toka\" Zhang" Date: Wed, 18 Sep 2024 17:57:40 +0200 Subject: [PATCH] Add avoid_crash option to scheduler (#2530) * chg * add avoid_crash * a * clp * just use .00 at this point * libafl-fuzz chg --- fuzzers/fuzzbench/fuzzbench/src/lib.rs | 6 +- fuzzers/fuzzbench/fuzzbench_ctx/src/lib.rs | 6 +- .../fuzzbench_fork_qemu/src/fuzzer.rs | 2 +- .../fuzzbench_forkserver/src/main.rs | 2 +- .../fuzzbench_forkserver_cmplog/src/main.rs | 2 +- .../fuzzbench/fuzzbench_qemu/src/fuzzer.rs | 2 +- fuzzers/fuzzbench/fuzzbench_text/src/lib.rs | 4 +- fuzzers/libpng/libfuzzer_libpng/src/lib.rs | 6 +- .../libpng/libfuzzer_libpng_cmin/src/lib.rs | 6 +- .../libfuzzer_libpng_tcp_manager/src/lib.rs | 6 +- fuzzers/others/dynamic_analysis/src/lib.rs | 6 +- fuzzers/others/libafl-fuzz/src/fuzzer.rs | 9 +- fuzzers/others/libafl-fuzz/src/hooks.rs | 6 -- fuzzers/others/libafl-fuzz/src/main.rs | 4 +- .../others/libfuzzer_windows_asan/src/lib.rs | 6 +- fuzzers/others/tutorial/src/lib.rs | 2 +- fuzzers/qemu/qemu_launcher/src/instance.rs | 2 +- libafl/src/schedulers/powersched.rs | 96 ++++++++++++++++++- libafl/src/schedulers/testcase_score.rs | 46 +++++---- libafl/src/schedulers/weighted.rs | 27 +++--- libafl_libfuzzer/runtime/src/lib.rs | 2 +- 21 files changed, 189 insertions(+), 59 deletions(-) diff --git a/fuzzers/fuzzbench/fuzzbench/src/lib.rs b/fuzzers/fuzzbench/fuzzbench/src/lib.rs index 9b162a48e3..cf09c342e5 100644 --- a/fuzzers/fuzzbench/fuzzbench/src/lib.rs +++ b/fuzzers/fuzzbench/fuzzbench/src/lib.rs @@ -310,7 +310,11 @@ fn fuzz( // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new( &edges_observer, - StdWeightedScheduler::with_schedule(&mut state, &edges_observer, Some(PowerSchedule::FAST)), + StdWeightedScheduler::with_schedule( + &mut state, + &edges_observer, + Some(PowerSchedule::fast()), + ), ); // A fuzzer with feedbacks and a corpus scheduler diff --git a/fuzzers/fuzzbench/fuzzbench_ctx/src/lib.rs b/fuzzers/fuzzbench/fuzzbench_ctx/src/lib.rs index b407fd01af..531f40df20 100644 --- a/fuzzers/fuzzbench/fuzzbench_ctx/src/lib.rs +++ b/fuzzers/fuzzbench/fuzzbench_ctx/src/lib.rs @@ -320,7 +320,11 @@ fn fuzz( // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new( &edges_observer, - StdWeightedScheduler::with_schedule(&mut state, &edges_observer, Some(PowerSchedule::FAST)), + StdWeightedScheduler::with_schedule( + &mut state, + &edges_observer, + Some(PowerSchedule::fast()), + ), ); // A fuzzer with feedbacks and a corpus scheduler diff --git a/fuzzers/fuzzbench/fuzzbench_fork_qemu/src/fuzzer.rs b/fuzzers/fuzzbench/fuzzbench_fork_qemu/src/fuzzer.rs index c6a9ceea1a..ee259748d7 100644 --- a/fuzzers/fuzzbench/fuzzbench_fork_qemu/src/fuzzer.rs +++ b/fuzzers/fuzzbench/fuzzbench_fork_qemu/src/fuzzer.rs @@ -313,7 +313,7 @@ fn fuzz( // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new( &edges_observer, - PowerQueueScheduler::new(&mut state, &edges_observer, PowerSchedule::FAST), + PowerQueueScheduler::new(&mut state, &edges_observer, PowerSchedule::fast()), ); // A fuzzer with feedbacks and a corpus scheduler diff --git a/fuzzers/fuzzbench/fuzzbench_forkserver/src/main.rs b/fuzzers/fuzzbench/fuzzbench_forkserver/src/main.rs index ffa2b903f2..c5185f62de 100644 --- a/fuzzers/fuzzbench/fuzzbench_forkserver/src/main.rs +++ b/fuzzers/fuzzbench/fuzzbench_forkserver/src/main.rs @@ -308,7 +308,7 @@ fn fuzz( StdWeightedScheduler::with_schedule( &mut state, &edges_observer, - Some(PowerSchedule::EXPLORE), + Some(PowerSchedule::explore()), ), ); diff --git a/fuzzers/fuzzbench/fuzzbench_forkserver_cmplog/src/main.rs b/fuzzers/fuzzbench/fuzzbench_forkserver_cmplog/src/main.rs index 79e1568e1b..52c1cafbad 100644 --- a/fuzzers/fuzzbench/fuzzbench_forkserver_cmplog/src/main.rs +++ b/fuzzers/fuzzbench/fuzzbench_forkserver_cmplog/src/main.rs @@ -309,7 +309,7 @@ fn fuzz( StdWeightedScheduler::with_schedule( &mut state, &edges_observer, - Some(PowerSchedule::EXPLORE), + Some(PowerSchedule::explore()), ), ); diff --git a/fuzzers/fuzzbench/fuzzbench_qemu/src/fuzzer.rs b/fuzzers/fuzzbench/fuzzbench_qemu/src/fuzzer.rs index 825fc3c410..1897d52ef2 100644 --- a/fuzzers/fuzzbench/fuzzbench_qemu/src/fuzzer.rs +++ b/fuzzers/fuzzbench/fuzzbench_qemu/src/fuzzer.rs @@ -319,7 +319,7 @@ fn fuzz( // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new( &edges_observer, - PowerQueueScheduler::new(&mut state, &edges_observer, PowerSchedule::FAST), + PowerQueueScheduler::new(&mut state, &edges_observer, PowerSchedule::fast()), ); // A fuzzer with feedbacks and a corpus scheduler diff --git a/fuzzers/fuzzbench/fuzzbench_text/src/lib.rs b/fuzzers/fuzzbench/fuzzbench_text/src/lib.rs index b8924015ca..a0230ddaf8 100644 --- a/fuzzers/fuzzbench/fuzzbench_text/src/lib.rs +++ b/fuzzers/fuzzbench/fuzzbench_text/src/lib.rs @@ -380,7 +380,7 @@ fn fuzz_binary( StdWeightedScheduler::with_schedule( &mut state, &edges_observer, - Some(PowerSchedule::EXPLORE), + Some(PowerSchedule::explore()), ), ); @@ -605,7 +605,7 @@ fn fuzz_text( StdWeightedScheduler::with_schedule( &mut state, &edges_observer, - Some(PowerSchedule::EXPLORE), + Some(PowerSchedule::explore()), ), ); diff --git a/fuzzers/libpng/libfuzzer_libpng/src/lib.rs b/fuzzers/libpng/libfuzzer_libpng/src/lib.rs index f1fff436c6..4ed929bc1f 100644 --- a/fuzzers/libpng/libfuzzer_libpng/src/lib.rs +++ b/fuzzers/libpng/libfuzzer_libpng/src/lib.rs @@ -149,7 +149,11 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new( &edges_observer, - StdWeightedScheduler::with_schedule(&mut state, &edges_observer, Some(PowerSchedule::FAST)), + StdWeightedScheduler::with_schedule( + &mut state, + &edges_observer, + Some(PowerSchedule::fast()), + ), ); // A fuzzer with feedbacks and a corpus scheduler diff --git a/fuzzers/libpng/libfuzzer_libpng_cmin/src/lib.rs b/fuzzers/libpng/libfuzzer_libpng_cmin/src/lib.rs index e024dcdbe8..4c568654fe 100644 --- a/fuzzers/libpng/libfuzzer_libpng_cmin/src/lib.rs +++ b/fuzzers/libpng/libfuzzer_libpng_cmin/src/lib.rs @@ -149,7 +149,11 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new( &edges_observer, - StdWeightedScheduler::with_schedule(&mut state, &edges_observer, Some(PowerSchedule::FAST)), + StdWeightedScheduler::with_schedule( + &mut state, + &edges_observer, + Some(PowerSchedule::fast()), + ), ); // A fuzzer with feedbacks and a corpus scheduler diff --git a/fuzzers/libpng/libfuzzer_libpng_tcp_manager/src/lib.rs b/fuzzers/libpng/libfuzzer_libpng_tcp_manager/src/lib.rs index 60dab533fa..5484bce799 100644 --- a/fuzzers/libpng/libfuzzer_libpng_tcp_manager/src/lib.rs +++ b/fuzzers/libpng/libfuzzer_libpng_tcp_manager/src/lib.rs @@ -147,7 +147,11 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new( &edges_observer, - StdWeightedScheduler::with_schedule(&mut state, &edges_observer, Some(PowerSchedule::FAST)), + StdWeightedScheduler::with_schedule( + &mut state, + &edges_observer, + Some(PowerSchedule::fast()), + ), ); // A fuzzer with feedbacks and a corpus scheduler diff --git a/fuzzers/others/dynamic_analysis/src/lib.rs b/fuzzers/others/dynamic_analysis/src/lib.rs index 472d8b4e36..f8503ce4a1 100644 --- a/fuzzers/others/dynamic_analysis/src/lib.rs +++ b/fuzzers/others/dynamic_analysis/src/lib.rs @@ -316,7 +316,11 @@ fn fuzz( // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new( &edges_observer, - StdWeightedScheduler::with_schedule(&mut state, &edges_observer, Some(PowerSchedule::FAST)), + StdWeightedScheduler::with_schedule( + &mut state, + &edges_observer, + Some(PowerSchedule::fast()), + ), ); // A fuzzer with feedbacks and a corpus scheduler diff --git a/fuzzers/others/libafl-fuzz/src/fuzzer.rs b/fuzzers/others/libafl-fuzz/src/fuzzer.rs index 4cc9b079a4..fd1c745838 100644 --- a/fuzzers/others/libafl-fuzz/src/fuzzer.rs +++ b/fuzzers/others/libafl-fuzz/src/fuzzer.rs @@ -16,8 +16,8 @@ use libafl::{ }, observers::{CanTrack, HitcountsMapObserver, StdMapObserver, TimeObserver}, schedulers::{ - powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, QueueScheduler, - StdWeightedScheduler, + powersched::{BaseSchedule, PowerSchedule}, + IndexesLenTimeMinimizerScheduler, QueueScheduler, StdWeightedScheduler, }, stages::{ mutational::MultiMutationalStage, CalibrationStage, ColorizationStage, IfStage, @@ -185,7 +185,7 @@ where ) }; let mutational_stage = TimeTrackingStageWrapper::::new(inner_mutational_stage); - let strategy = opt.power_schedule.unwrap_or(PowerSchedule::EXPLORE); + let strategy = opt.power_schedule.unwrap_or(BaseSchedule::EXPLORE); // Create our ColorizationStage let colorization = ColorizationStage::new(&edges_observer); @@ -197,8 +197,9 @@ where if opt.sequential_queue { scheduler = SupportedSchedulers::Queue(QueueScheduler::new(), PhantomData); } else { + let ps = PowerSchedule::new(strategy); let mut weighted_scheduler = - StdWeightedScheduler::with_schedule(&mut state, &edges_observer, Some(strategy)); + StdWeightedScheduler::with_schedule(&mut state, &edges_observer, Some(ps)); if opt.cycle_schedules { weighted_scheduler = weighted_scheduler.cycling_scheduler(); } diff --git a/fuzzers/others/libafl-fuzz/src/hooks.rs b/fuzzers/others/libafl-fuzz/src/hooks.rs index 27b6183bc2..454d9e9ac3 100644 --- a/fuzzers/others/libafl-fuzz/src/hooks.rs +++ b/fuzzers/others/libafl-fuzz/src/hooks.rs @@ -10,12 +10,6 @@ pub struct LibAflFuzzEventHook { exit_on_solution: bool, } -impl LibAflFuzzEventHook { - pub fn new(exit_on_solution: bool) -> Self { - Self { exit_on_solution } - } -} - impl EventManagerHook for LibAflFuzzEventHook where S: State + Stoppable, diff --git a/fuzzers/others/libafl-fuzz/src/main.rs b/fuzzers/others/libafl-fuzz/src/main.rs index 78dd1d8159..a093c3062f 100644 --- a/fuzzers/others/libafl-fuzz/src/main.rs +++ b/fuzzers/others/libafl-fuzz/src/main.rs @@ -25,7 +25,7 @@ use fuzzer::run_client; use libafl::{ events::{CentralizedLauncher, EventConfig}, monitors::MultiMonitor, - schedulers::powersched::PowerSchedule, + schedulers::powersched::BaseSchedule, Error, }; use libafl_bolts::{ @@ -126,7 +126,7 @@ struct Opt { rng_seed: Option, /// power schedules compute a seed's performance score: explore(default), fast, exploit, seek, rare, mmopt, coe, lin #[arg(short = 'p')] - power_schedule: Option, + power_schedule: Option, /// enable `CmpLog` by specifying a binary compiled for it. #[arg(short = 'c')] cmplog: Option, diff --git a/fuzzers/others/libfuzzer_windows_asan/src/lib.rs b/fuzzers/others/libfuzzer_windows_asan/src/lib.rs index 0d1401a8d5..0fedb32152 100644 --- a/fuzzers/others/libfuzzer_windows_asan/src/lib.rs +++ b/fuzzers/others/libfuzzer_windows_asan/src/lib.rs @@ -114,7 +114,11 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new( &edges_observer, - StdWeightedScheduler::with_schedule(&mut state, &edges_observer, Some(PowerSchedule::FAST)), + StdWeightedScheduler::with_schedule( + &mut state, + &edges_observer, + Some(PowerSchedule::fast()), + ), ); // A fuzzer with feedbacks and a corpus scheduler diff --git a/fuzzers/others/tutorial/src/lib.rs b/fuzzers/others/tutorial/src/lib.rs index b60b44eeed..c2f8d2778f 100644 --- a/fuzzers/others/tutorial/src/lib.rs +++ b/fuzzers/others/tutorial/src/lib.rs @@ -135,7 +135,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re // A minimization+queue policy to get testcasess from the corpus let scheduler = PacketLenMinimizerScheduler::new( &edges_observer, - PowerQueueScheduler::new(&mut state, &edges_observer, PowerSchedule::FAST), + PowerQueueScheduler::new(&mut state, &edges_observer, PowerSchedule::fast()), ); // A fuzzer with feedbacks and a corpus scheduler diff --git a/fuzzers/qemu/qemu_launcher/src/instance.rs b/fuzzers/qemu/qemu_launcher/src/instance.rs index b703b221c5..9c59d194fb 100644 --- a/fuzzers/qemu/qemu_launcher/src/instance.rs +++ b/fuzzers/qemu/qemu_launcher/src/instance.rs @@ -127,7 +127,7 @@ impl<'a, M: Monitor> Instance<'a, M> { // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new( &edges_observer, - PowerQueueScheduler::new(&mut state, &edges_observer, PowerSchedule::FAST), + PowerQueueScheduler::new(&mut state, &edges_observer, PowerSchedule::fast()), ); let observers = tuple_list!(edges_observer, time_observer); diff --git a/libafl/src/schedulers/powersched.rs b/libafl/src/schedulers/powersched.rs index 02f6439469..f85391a2fa 100644 --- a/libafl/src/schedulers/powersched.rs +++ b/libafl/src/schedulers/powersched.rs @@ -155,10 +155,104 @@ impl SchedulerMetadata { } } +/// The struct for the powerschedule algorithm +#[derive(Debug, Clone, Serialize, Deserialize, Copy)] +pub struct PowerSchedule { + base: BaseSchedule, + avoid_crash: bool, +} + +impl PowerSchedule { + #[must_use] + /// Constructor + pub fn new(base: BaseSchedule) -> Self { + Self { + base, + avoid_crash: false, + } + } + + /// Use `explore` power schedule + #[must_use] + pub fn explore() -> Self { + Self { + base: BaseSchedule::EXPLORE, + avoid_crash: false, + } + } + + /// Use `exploit` power schedule + #[must_use] + pub fn exploit() -> Self { + Self { + base: BaseSchedule::EXPLOIT, + avoid_crash: false, + } + } + + /// Use `fast` power schedule + #[must_use] + pub fn fast() -> Self { + Self { + base: BaseSchedule::FAST, + avoid_crash: false, + } + } + + /// Use `coe` power schedule + #[must_use] + pub fn coe() -> Self { + Self { + base: BaseSchedule::COE, + avoid_crash: false, + } + } + + /// Use `lin` power schedule + #[must_use] + pub fn lin() -> Self { + Self { + base: BaseSchedule::LIN, + avoid_crash: false, + } + } + + /// Use `quad` power schedule + #[must_use] + pub fn quad() -> Self { + Self { + base: BaseSchedule::QUAD, + avoid_crash: false, + } + } + + /// Getter to `avoid_crash` + #[must_use] + pub fn avoid_crash(&self) -> bool { + self.avoid_crash + } + + /// Avoid scheduling testcases that caused crashes + pub fn set_avoid_crash(&mut self) { + self.avoid_crash = true; + } + + /// Getter to the base scheduler + #[must_use] + pub fn base(&self) -> &BaseSchedule { + &self.base + } + + /// Setter to the base scheduler + pub fn set_base(&mut self, base: BaseSchedule) { + self.base = base; + } +} + /// The power schedule to use #[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq)] #[cfg_attr(feature = "clap", derive(clap::ValueEnum))] -pub enum PowerSchedule { +pub enum BaseSchedule { /// The `explore` power schedule EXPLORE, /// The `exploit` power schedule diff --git a/libafl/src/schedulers/testcase_score.rs b/libafl/src/schedulers/testcase_score.rs index 58be175b74..31d1fc0c93 100644 --- a/libafl/src/schedulers/testcase_score.rs +++ b/libafl/src/schedulers/testcase_score.rs @@ -9,7 +9,7 @@ use crate::{ feedbacks::MapIndexesMetadata, schedulers::{ minimizer::{IsFavoredMetadata, TopRatedsMetadata}, - powersched::{PowerSchedule, SchedulerMetadata}, + powersched::{BaseSchedule, SchedulerMetadata}, }, state::HasCorpus, Error, HasMetadata, @@ -71,7 +71,7 @@ where let psmeta = state.metadata::()?; let fuzz_mu = if let Some(strat) = psmeta.strat() { - if strat == PowerSchedule::COE { + if *strat.base() == BaseSchedule::COE { let corpus = state.corpus(); let mut n_paths = 0; let mut v = 0.0; @@ -175,14 +175,14 @@ where // COE and Fast schedule are fairly different from what are described in the original thesis, // This implementation follows the changes made in this pull request https://github.com/AFLplusplus/AFLplusplus/pull/568 if let Some(strat) = psmeta.strat() { - match strat { - PowerSchedule::EXPLORE => { + match strat.base() { + BaseSchedule::EXPLORE => { // Nothing happens in EXPLORE } - PowerSchedule::EXPLOIT => { + BaseSchedule::EXPLOIT => { factor = MAX_FACTOR; } - PowerSchedule::COE => { + BaseSchedule::COE => { if libm::log2(f64::from(psmeta.n_fuzz()[tcmeta.n_fuzz_entry()])) > fuzz_mu && !favored { @@ -190,7 +190,7 @@ where factor = 0.0; } } - PowerSchedule::FAST => { + BaseSchedule::FAST => { if entry.scheduled_count() != 0 { let lg = libm::log2(f64::from(psmeta.n_fuzz()[tcmeta.n_fuzz_entry()])); @@ -229,11 +229,11 @@ where } } } - PowerSchedule::LIN => { + BaseSchedule::LIN => { factor = (entry.scheduled_count() as f64) / f64::from(psmeta.n_fuzz()[tcmeta.n_fuzz_entry()] + 1); } - PowerSchedule::QUAD => { + BaseSchedule::QUAD => { factor = ((entry.scheduled_count() * entry.scheduled_count()) as f64) / f64::from(psmeta.n_fuzz()[tcmeta.n_fuzz_entry()] + 1); } @@ -241,7 +241,7 @@ where } if let Some(strat) = psmeta.strat() { - if strat != PowerSchedule::EXPLORE { + if *strat.base() != BaseSchedule::EXPLORE { if factor > MAX_FACTOR { factor = MAX_FACTOR; } @@ -252,7 +252,7 @@ where // Lower bound if the strat is not COE. if let Some(strat) = psmeta.strat() { - if strat == PowerSchedule::COE && perf_score < 1.0 { + if *strat.base() == BaseSchedule::COE && perf_score < 1.0 { perf_score = 1.0; } } @@ -262,6 +262,10 @@ where perf_score = HAVOC_MAX_MULT * 100.0; } + if entry.objectives_found() > 0 && psmeta.strat().map_or(false, |s| s.avoid_crash()) { + perf_score *= 0.00; + } + Ok(perf_score) } } @@ -303,13 +307,15 @@ where let q_bitmap_size = tcmeta.bitmap_size() as f64; - if let Some( - PowerSchedule::FAST | PowerSchedule::COE | PowerSchedule::LIN | PowerSchedule::QUAD, - ) = psmeta.strat() - { - let hits = psmeta.n_fuzz()[tcmeta.n_fuzz_entry()]; - if hits > 0 { - weight /= libm::log10(f64::from(hits)) + 1.0; + if let Some(ps) = psmeta.strat() { + match ps.base() { + BaseSchedule::FAST | BaseSchedule::COE | BaseSchedule::LIN | BaseSchedule::QUAD => { + let hits = psmeta.n_fuzz()[tcmeta.n_fuzz_entry()]; + if hits > 0 { + weight /= libm::log10(f64::from(hits)) + 1.0; + } + } + _ => (), } } @@ -333,6 +339,10 @@ where weight *= 2.0; } + if entry.objectives_found() > 0 && psmeta.strat().map_or(false, |s| s.avoid_crash()) { + weight *= 0.00; + } + assert!(weight.is_normal()); Ok(weight) diff --git a/libafl/src/schedulers/weighted.rs b/libafl/src/schedulers/weighted.rs index 6bcd9cf42d..83fe746b3e 100644 --- a/libafl/src/schedulers/weighted.rs +++ b/libafl/src/schedulers/weighted.rs @@ -13,13 +13,14 @@ use libafl_bolts::{ }; use serde::{Deserialize, Serialize}; +use super::powersched::PowerSchedule; use crate::{ corpus::{Corpus, CorpusId, HasTestcase, Testcase}, inputs::UsesInput, observers::{MapObserver, ObserversTuple}, random_corpus_id, schedulers::{ - powersched::{PowerSchedule, SchedulerMetadata}, + powersched::{BaseSchedule, SchedulerMetadata}, testcase_score::{CorpusWeightTestcaseScore, TestcaseScore}, AflScheduler, HasQueueCycles, RemovableScheduler, Scheduler, }, @@ -236,21 +237,23 @@ where } /// Cycles the strategy of the scheduler; tries to mimic AFL++'s cycling formula - fn cycle_schedule(&mut self, metadata: &mut SchedulerMetadata) -> Result { - let next_strat = match metadata.strat().ok_or(Error::illegal_argument( + fn cycle_schedule(&mut self, metadata: &mut SchedulerMetadata) -> Result<(), Error> { + let mut ps = metadata.strat().ok_or(Error::illegal_argument( "No strategy specified when initializing scheduler; cannot cycle!", - ))? { - PowerSchedule::EXPLORE => PowerSchedule::EXPLOIT, - PowerSchedule::COE => PowerSchedule::LIN, - PowerSchedule::LIN => PowerSchedule::QUAD, - PowerSchedule::FAST => PowerSchedule::COE, - PowerSchedule::QUAD => PowerSchedule::FAST, - PowerSchedule::EXPLOIT => PowerSchedule::EXPLORE, + ))?; + let new_base = match ps.base() { + BaseSchedule::EXPLORE => BaseSchedule::EXPLOIT, + BaseSchedule::COE => BaseSchedule::LIN, + BaseSchedule::LIN => BaseSchedule::QUAD, + BaseSchedule::FAST => BaseSchedule::COE, + BaseSchedule::QUAD => BaseSchedule::FAST, + BaseSchedule::EXPLOIT => BaseSchedule::EXPLORE, }; - metadata.set_strat(Some(next_strat)); + ps.set_base(new_base); + metadata.set_strat(Some(ps)); // We need to recalculate the scores of testcases. self.table_invalidated = true; - Ok(next_strat) + Ok(()) } } diff --git a/libafl_libfuzzer/runtime/src/lib.rs b/libafl_libfuzzer/runtime/src/lib.rs index 355e34b953..db4bf2e2b3 100644 --- a/libafl_libfuzzer/runtime/src/lib.rs +++ b/libafl_libfuzzer/runtime/src/lib.rs @@ -413,7 +413,7 @@ macro_rules! fuzz_with { let grimoire = IfStage::new(|_, _, _, _| Ok(grimoire.into()), (StdMutationalStage::transforming(grimoire_mutator), ())); // A minimization+queue policy to get testcasess from the corpus - let scheduler = IndexesLenTimeMinimizerScheduler::new(&edges_observer, PowerQueueScheduler::new(&mut state, &edges_observer, PowerSchedule::FAST)); + let scheduler = IndexesLenTimeMinimizerScheduler::new(&edges_observer, PowerQueueScheduler::new(&mut state, &edges_observer, PowerSchedule::fast())); // A fuzzer with feedbacks and a corpus scheduler let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);