diff --git a/fuzzers/others/push_stage_harness/src/main.rs b/fuzzers/others/push_stage_harness/src/main.rs index 4e90ac6b03..e1eb51e1ff 100644 --- a/fuzzers/others/push_stage_harness/src/main.rs +++ b/fuzzers/others/push_stage_harness/src/main.rs @@ -77,7 +77,7 @@ pub fn main() { let testcase = Testcase::new(BytesInput::new(b"aaaa".to_vec())); //self.feedback_mut().append_metadata(state, &mut testcase)?; let idx = state.corpus_mut().add(testcase).unwrap(); - scheduler.on_add(&mut state, idx).unwrap(); + >::on_add(&mut scheduler, &mut state, idx).unwrap(); // A fuzzer with feedbacks and a corpus scheduler let fuzzer = StdFuzzer::new(scheduler, feedback, objective); diff --git a/libafl/src/corpus/minimizer.rs b/libafl/src/corpus/minimizer.rs index 5fdb7afedf..1548cbaded 100644 --- a/libafl/src/corpus/minimizer.rs +++ b/libafl/src/corpus/minimizer.rs @@ -17,7 +17,6 @@ use crate::{ corpus::Corpus, events::{Event, EventFirer, LogSeverity}, executors::{Executor, HasObservers}, - inputs::UsesInput, monitors::{AggregatorOps, UserStats, UserStatsValue}, observers::{MapObserver, ObserversTuple}, schedulers::{LenTimeMulTestcaseScore, RemovableScheduler, Scheduler, TestcaseScore}, @@ -57,13 +56,7 @@ pub struct MapCorpusMinimizer { } /// Standard corpus minimizer, which weights inputs by length and time. -pub type StdCorpusMinimizer = MapCorpusMinimizer< - C, - E, - O, - T, - LenTimeMulTestcaseScore<::Input, ::State>, ->; +pub type StdCorpusMinimizer = MapCorpusMinimizer; impl MapCorpusMinimizer where diff --git a/libafl/src/corpus/testcase.rs b/libafl/src/corpus/testcase.rs index 2808c8a8e0..89d71ac391 100644 --- a/libafl/src/corpus/testcase.rs +++ b/libafl/src/corpus/testcase.rs @@ -15,11 +15,7 @@ use libafl_bolts::{serdeany::SerdeAnyMap, HasLen}; use serde::{Deserialize, Serialize}; use super::Corpus; -use crate::{ - corpus::CorpusId, - inputs::{Input, UsesInput}, - Error, HasMetadata, -}; +use crate::{corpus::CorpusId, inputs::UsesInput, Error, HasMetadata}; /// Shorthand to receive a [`Ref`] or [`RefMut`] to a stored [`Testcase`], by [`CorpusId`]. /// For a normal state, this should return a [`Testcase`] in the corpus, not the objectives. @@ -38,11 +34,7 @@ pub trait HasTestcase: UsesInput { /// An entry in the [`Testcase`] Corpus #[derive(Serialize, Deserialize, Clone, Debug)] -#[serde(bound = "I: serde::de::DeserializeOwned")] -pub struct Testcase -where - I: Input, -{ +pub struct Testcase { /// The [`Input`] of this [`Testcase`], or `None`, if it is not currently in memory input: Option, /// The filename for this [`Testcase`] @@ -77,10 +69,7 @@ where hit_objectives: Vec>, } -impl HasMetadata for Testcase -where - I: Input, -{ +impl HasMetadata for Testcase { /// Get all the metadata into an [`hashbrown::HashMap`] #[inline] fn metadata_map(&self) -> &SerdeAnyMap { @@ -95,10 +84,7 @@ where } /// Impl of a testcase -impl Testcase -where - I: Input, -{ +impl Testcase { /// Returns this [`Testcase`] with a loaded `Input`] pub fn load_input>(&mut self, corpus: &C) -> Result<&I, Error> { corpus.load_input_into(self)?; @@ -120,8 +106,7 @@ where /// Set the input #[inline] - pub fn set_input(&mut self, mut input: I) { - input.wrapped_as_testcase(); + pub fn set_input(&mut self, input: I) { self.input = Some(input); } @@ -249,8 +234,7 @@ where /// Create a new Testcase instance given an input #[inline] - pub fn new(mut input: I) -> Self { - input.wrapped_as_testcase(); + pub fn new(input: I) -> Self { Self { input: Some(input), filename: None, @@ -275,8 +259,7 @@ where /// Creates a testcase, attaching the id of the parent /// that this [`Testcase`] was derived from on creation - pub fn with_parent_id(mut input: I, parent_id: CorpusId) -> Self { - input.wrapped_as_testcase(); + pub fn with_parent_id(input: I, parent_id: CorpusId) -> Self { Testcase { input: Some(input), filename: None, @@ -299,10 +282,9 @@ where } } - /// Create a new Testcase instance given an [`Input`] and a `filename` + /// Create a new Testcase instance given an input and a `filename` #[inline] - pub fn with_filename(mut input: I, filename: String) -> Self { - input.wrapped_as_testcase(); + pub fn with_filename(input: I, filename: String) -> Self { Self { input: Some(input), filename: Some(filename), @@ -325,10 +307,9 @@ where } } - /// Create a new Testcase instance given an [`Input`] and the number of executions + /// Create a new Testcase instance given an input and the number of executions #[inline] - pub fn with_executions(mut input: I, executions: u64) -> Self { - input.wrapped_as_testcase(); + pub fn with_executions(input: I, executions: u64) -> Self { Self { input: Some(input), filename: None, @@ -378,10 +359,7 @@ where } } -impl Default for Testcase -where - I: Input, -{ +impl Default for Testcase { /// Create a new default Testcase #[inline] fn default() -> Self { @@ -411,7 +389,7 @@ where /// Impl of a testcase when the input has len impl Testcase where - I: Input + HasLen, + I: HasLen, { /// Get the cached `len`. Will `Error::EmptyOptional` if `len` is not yet cached. #[inline] @@ -441,10 +419,7 @@ where } /// Create a testcase from an input -impl From for Testcase -where - I: Input, -{ +impl From for Testcase { fn from(input: I) -> Self { Testcase::new(input) } @@ -563,10 +538,7 @@ impl SchedulerTestcaseMetadata { libafl_bolts::impl_serdeany!(SchedulerTestcaseMetadata); #[cfg(feature = "std")] -impl Drop for Testcase -where - I: Input, -{ +impl Drop for Testcase { fn drop(&mut self) { if let Some(filename) = &self.filename { let mut path = PathBuf::from(filename); diff --git a/libafl/src/inputs/mod.rs b/libafl/src/inputs/mod.rs index a82964c1f1..43fc9f806d 100644 --- a/libafl/src/inputs/mod.rs +++ b/libafl/src/inputs/mod.rs @@ -60,9 +60,6 @@ pub trait Input: Clone + Serialize + serde::de::DeserializeOwned + Debug { /// Generate a name for this input fn generate_name(&self, id: Option) -> String; - - /// An hook executed if the input is stored as `Testcase` - fn wrapped_as_testcase(&mut self) {} } /// An input for the target @@ -89,9 +86,6 @@ pub trait Input: Clone + Serialize + serde::de::DeserializeOwned + Debug { /// Generate a name for this input, the user is responsible for making each name of testcase unique. fn generate_name(&self, id: Option) -> String; - - /// An hook executed if the input is stored as `Testcase` - fn wrapped_as_testcase(&mut self) {} } /// Convert between two input types with a state diff --git a/libafl/src/schedulers/accounting.rs b/libafl/src/schedulers/accounting.rs index 6c8b1f8d3c..beae671f2c 100644 --- a/libafl/src/schedulers/accounting.rs +++ b/libafl/src/schedulers/accounting.rs @@ -7,17 +7,16 @@ use core::{ }; use hashbrown::HashMap; -use libafl_bolts::{rands::Rand, HasLen, HasRefCnt}; +use libafl_bolts::{rands::Rand, tuples::MatchName, HasLen, HasRefCnt}; use serde::{Deserialize, Serialize}; +use super::IndexesLenTimeMinimizerScheduler; use crate::{ corpus::{Corpus, CorpusId}, - feedbacks::MapIndexesMetadata, - inputs::Input, - observers::{CanTrack, ObserversTuple}, + observers::CanTrack, schedulers::{ minimizer::{IsFavoredMetadata, MinimizerScheduler, DEFAULT_SKIP_NON_FAVORED_PROB}, - LenTimeMulTestcaseScore, Scheduler, + Scheduler, }, state::{HasCorpus, HasRand}, Error, HasMetadata, @@ -105,17 +104,17 @@ impl TopAccountingMetadata { /// A minimizer scheduler using coverage accounting #[derive(Debug)] -pub struct CoverageAccountingScheduler<'a, CS, I, O, S> { +pub struct CoverageAccountingScheduler<'a, CS, O> { accounting_map: &'a [u32], skip_non_favored_prob: f64, - inner: MinimizerScheduler, I, MapIndexesMetadata, O, S>, + inner: IndexesLenTimeMinimizerScheduler, } -impl<'a, CS, I, O, S> Scheduler for CoverageAccountingScheduler<'a, CS, I, O, S> +impl<'a, CS, I, O, S> Scheduler for CoverageAccountingScheduler<'a, CS, O> where CS: Scheduler, - S: HasCorpus + HasMetadata + HasRand + Debug, - I: HasLen + Input, + S: HasCorpus + HasMetadata + HasRand, + I: HasLen, O: CanTrack, { fn on_add(&mut self, state: &mut S, id: CorpusId) -> Result<(), Error> { @@ -125,7 +124,7 @@ where fn on_evaluation(&mut self, state: &mut S, input: &I, observers: &OT) -> Result<(), Error> where - OT: ObserversTuple, + OT: MatchName, { self.inner.on_evaluation(state, input, observers) } @@ -169,17 +168,17 @@ where } } -impl<'a, CS, I, O, S> CoverageAccountingScheduler<'a, CS, I, O, S> +impl<'a, CS, O> CoverageAccountingScheduler<'a, CS, O> where - CS: Scheduler, - S: HasCorpus + HasMetadata + HasRand + Debug, - I: HasLen + Input, O: CanTrack, { /// Update the `Corpus` score #[allow(clippy::unused_self)] #[allow(clippy::cast_possible_wrap)] - pub fn update_accounting_score(&self, state: &mut S, id: CorpusId) -> Result<(), Error> { + pub fn update_accounting_score(&self, state: &mut S, id: CorpusId) -> Result<(), Error> + where + S: HasCorpus + HasMetadata, + { let mut indexes = vec![]; let mut new_favoreds = vec![]; { @@ -264,7 +263,10 @@ where /// Cull the `Corpus` #[allow(clippy::unused_self)] - pub fn accounting_cull(&self, state: &S) -> Result<(), Error> { + pub fn accounting_cull(&self, state: &S) -> Result<(), Error> + where + S: HasCorpus + HasMetadata, + { let Some(top_rated) = state.metadata_map().get::() else { return Ok(()); }; @@ -285,7 +287,10 @@ where /// and has a default probability to skip non-faved Testcases of [`DEFAULT_SKIP_NON_FAVORED_PROB`]. /// /// Provide the observer responsible for determining new indexes. - pub fn new(observer: &O, state: &mut S, base: CS, accounting_map: &'a [u32]) -> Self { + pub fn new(observer: &O, state: &mut S, base: CS, accounting_map: &'a [u32]) -> Self + where + S: HasMetadata, + { match state.metadata_map().get::() { Some(meta) => { if meta.max_accounting.len() != accounting_map.len() { @@ -307,13 +312,16 @@ where /// and has a non-default probability to skip non-faved Testcases using (`skip_non_favored_prob`). /// /// Provide the observer responsible for determining new indexes. - pub fn with_skip_prob( + pub fn with_skip_prob( observer: &O, state: &mut S, base: CS, skip_non_favored_prob: f64, accounting_map: &'a [u32], - ) -> Self { + ) -> Self + where + S: HasMetadata, + { match state.metadata_map().get::() { Some(meta) => { if meta.max_accounting.len() != accounting_map.len() { diff --git a/libafl/src/schedulers/minimizer.rs b/libafl/src/schedulers/minimizer.rs index 0232866f5b..f6bcaafa13 100644 --- a/libafl/src/schedulers/minimizer.rs +++ b/libafl/src/schedulers/minimizer.rs @@ -5,14 +5,13 @@ use alloc::vec::Vec; use core::{any::type_name, cmp::Ordering, marker::PhantomData}; use hashbrown::{HashMap, HashSet}; -use libafl_bolts::{rands::Rand, serdeany::SerdeAny, AsIter, HasRefCnt}; +use libafl_bolts::{rands::Rand, serdeany::SerdeAny, tuples::MatchName, AsIter, HasRefCnt}; use serde::{Deserialize, Serialize}; use crate::{ corpus::{Corpus, CorpusId, Testcase}, feedbacks::MapIndexesMetadata, - inputs::Input, - observers::{CanTrack, ObserversTuple}, + observers::CanTrack, require_index_tracking, schedulers::{LenTimeMulTestcaseScore, RemovableScheduler, Scheduler, TestcaseScore}, state::{HasCorpus, HasRand}, @@ -72,21 +71,19 @@ impl Default for TopRatedsMetadata { /// /// E.g., it can use all the coverage seen so far to prioritize [`Testcase`]`s` using a [`TestcaseScore`]. #[derive(Debug, Clone)] -pub struct MinimizerScheduler { +pub struct MinimizerScheduler { base: CS, skip_non_favored_prob: f64, remove_metadata: bool, - phantom: PhantomData<(F, I, M, O, S)>, + phantom: PhantomData<(F, M, S)>, } -impl RemovableScheduler for MinimizerScheduler +impl RemovableScheduler for MinimizerScheduler where CS: RemovableScheduler + Scheduler, - I: Input, F: TestcaseScore, M: for<'a> AsIter<'a, Item = usize> + SerdeAny + HasRefCnt, S: HasCorpus + HasMetadata + HasRand, - O: CanTrack, { /// Replaces the [`Testcase`] at the given [`CorpusId`] fn on_replace( @@ -188,14 +185,12 @@ where } } -impl Scheduler for MinimizerScheduler +impl Scheduler for MinimizerScheduler where CS: Scheduler, F: TestcaseScore, - I: Input, M: for<'a> AsIter<'a, Item = usize> + SerdeAny + HasRefCnt, S: HasCorpus + HasMetadata + HasRand, - O: CanTrack, { /// Called when a [`Testcase`] is added to the corpus fn on_add(&mut self, state: &mut S, id: CorpusId) -> Result<(), Error> { @@ -206,7 +201,7 @@ where /// An input has been evaluated fn on_evaluation(&mut self, state: &mut S, input: &I, observers: &OT) -> Result<(), Error> where - OT: ObserversTuple, + OT: MatchName, { self.base.on_evaluation(state, input, observers) } @@ -240,19 +235,18 @@ where } } -impl MinimizerScheduler +impl MinimizerScheduler where - CS: Scheduler, - F: TestcaseScore, - I: Input, M: for<'a> AsIter<'a, Item = usize> + SerdeAny + HasRefCnt, - S: HasCorpus + HasMetadata + HasRand, - O: CanTrack, { /// Update the [`Corpus`] score using the [`MinimizerScheduler`] #[allow(clippy::unused_self)] #[allow(clippy::cast_possible_wrap)] - pub fn update_score(&self, state: &mut S, id: CorpusId) -> Result<(), Error> { + pub fn update_score(&self, state: &mut S, id: CorpusId) -> Result<(), Error> + where + F: TestcaseScore, + S: HasCorpus + HasMetadata, + { // Create a new top rated meta if not existing if state.metadata_map().get::().is_none() { state.add_metadata(TopRatedsMetadata::new()); @@ -326,7 +320,10 @@ where /// Cull the [`Corpus`] using the [`MinimizerScheduler`] #[allow(clippy::unused_self)] - pub fn cull(&self, state: &S) -> Result<(), Error> { + pub fn cull(&self, state: &S) -> Result<(), Error> + where + S: HasCorpus + HasMetadata, + { let Some(top_rated) = state.metadata_map().get::() else { return Ok(()); }; @@ -352,7 +349,12 @@ where Ok(()) } +} +impl MinimizerScheduler +where + O: CanTrack, +{ /// Get a reference to the base scheduler pub fn base(&self) -> &CS { &self.base @@ -410,10 +412,10 @@ where } /// A [`MinimizerScheduler`] with [`LenTimeMulTestcaseScore`] to prioritize quick and small [`Testcase`]`s`. -pub type LenTimeMinimizerScheduler = - MinimizerScheduler, I, M, O, S>; +pub type LenTimeMinimizerScheduler = + MinimizerScheduler; /// A [`MinimizerScheduler`] with [`LenTimeMulTestcaseScore`] to prioritize quick and small [`Testcase`]`s` /// that exercise all the entries registered in the [`MapIndexesMetadata`]. -pub type IndexesLenTimeMinimizerScheduler = - MinimizerScheduler, I, MapIndexesMetadata, O, S>; +pub type IndexesLenTimeMinimizerScheduler = + MinimizerScheduler; diff --git a/libafl/src/schedulers/mod.rs b/libafl/src/schedulers/mod.rs index 7b7744a441..410e876b20 100644 --- a/libafl/src/schedulers/mod.rs +++ b/libafl/src/schedulers/mod.rs @@ -29,24 +29,20 @@ pub use weighted::{StdWeightedScheduler, WeightedScheduler}; pub mod tuneable; use libafl_bolts::{ rands::Rand, - tuples::{Handle, MatchNameRef}, + tuples::{Handle, MatchName, MatchNameRef}, }; pub use tuneable::*; use crate::{ corpus::{Corpus, CorpusId, HasTestcase, SchedulerTestcaseMetadata, Testcase}, - inputs::Input, - observers::{MapObserver, ObserversTuple}, + observers::MapObserver, random_corpus_id, - state::{HasCorpus, HasRand, State}, + state::{HasCorpus, HasRand}, Error, HasMetadata, }; /// The scheduler also implements `on_remove` and `on_replace` if it implements this stage. -pub trait RemovableScheduler -where - I: Input, -{ +pub trait RemovableScheduler { /// Removed the given entry from the corpus at the given index /// When you remove testcases, make sure that that testcase is not currently fuzzed one! fn on_remove( @@ -69,14 +65,96 @@ where } } -/// Defines the common metadata operations for the AFL-style schedulers -pub trait AflScheduler +/// Called when a [`Testcase`] is evaluated +pub fn on_add_metadata_default( + scheduler: &mut CS, + state: &mut S, + id: CorpusId, +) -> Result<(), Error> where - S: HasCorpus + HasMetadata + HasTestcase, - O: MapObserver, + CS: AflScheduler, + S: HasTestcase + HasCorpus, { + let current_id = *state.corpus().current(); + + let mut depth = match current_id { + Some(parent_idx) => state + .testcase(parent_idx)? + .metadata::()? + .depth(), + None => 0, + }; + + // TODO increase perf_score when finding new things like in AFL + // https://github.com/google/AFL/blob/master/afl-fuzz.c#L6547 + + // Attach a `SchedulerTestcaseMetadata` to the queue entry. + depth += 1; + let mut testcase = state.testcase_mut(id)?; + testcase.add_metadata(SchedulerTestcaseMetadata::with_n_fuzz_entry( + depth, + scheduler.last_hash(), + )); + testcase.set_parent_id_optional(current_id); + Ok(()) +} + +/// Called when a [`Testcase`] is evaluated +pub fn on_evaluation_metadata_default( + scheduler: &mut CS, + state: &mut S, + observers: &OT, +) -> Result<(), Error> +where + CS: AflScheduler, + CS::MapObserverRef: AsRef, + S: HasMetadata, + O: MapObserver, + OT: MatchName, +{ + let observer = observers + .get(scheduler.map_observer_handle()) + .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))? + .as_ref(); + + let mut hash = observer.hash_simple() as usize; + + let psmeta = state.metadata_mut::()?; + + hash %= psmeta.n_fuzz().len(); + // Update the path frequency + psmeta.n_fuzz_mut()[hash] = psmeta.n_fuzz()[hash].saturating_add(1); + + scheduler.set_last_hash(hash); + + Ok(()) +} + +/// Called when choosing the next [`Testcase`] +pub fn on_next_metadata_default(state: &mut S) -> Result<(), Error> +where + S: HasCorpus + HasTestcase, +{ + let current_id = *state.corpus().current(); + + if let Some(id) = current_id { + let mut testcase = state.testcase_mut(id)?; + let tcmeta = testcase.metadata_mut::()?; + + if tcmeta.handicap() >= 4 { + tcmeta.set_handicap(tcmeta.handicap() - 4); + } else if tcmeta.handicap() > 0 { + tcmeta.set_handicap(tcmeta.handicap() - 1); + } + } + + Ok(()) +} + +/// Defines the common metadata operations for the AFL-style schedulers +pub trait AflScheduler { /// The type of [`MapObserver`] that this scheduler will use as reference - type MapObserverRef: AsRef; + type MapObserverRef; /// Return the last hash fn last_hash(&self) -> usize; @@ -86,78 +164,6 @@ where /// Get the observer map observer name fn map_observer_handle(&self) -> &Handle; - - /// Called when a [`Testcase`] is added to the corpus - fn on_add_metadata(&self, state: &mut S, id: CorpusId) -> Result<(), Error> { - let current_id = *state.corpus().current(); - - let mut depth = match current_id { - Some(parent_idx) => state - .testcase(parent_idx)? - .metadata::()? - .depth(), - None => 0, - }; - - // TODO increase perf_score when finding new things like in AFL - // https://github.com/google/AFL/blob/master/afl-fuzz.c#L6547 - - // Attach a `SchedulerTestcaseMetadata` to the queue entry. - depth += 1; - let mut testcase = state.testcase_mut(id)?; - testcase.add_metadata(SchedulerTestcaseMetadata::with_n_fuzz_entry( - depth, - self.last_hash(), - )); - testcase.set_parent_id_optional(current_id); - Ok(()) - } - - /// Called when a [`Testcase`] is evaluated - fn on_evaluation_metadata( - &mut self, - state: &mut S, - _input: &I, - observers: &OT, - ) -> Result<(), Error> - where - OT: ObserversTuple, - { - let observer = observers - .get(self.map_observer_handle()) - .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))? - .as_ref(); - - let mut hash = observer.hash_simple() as usize; - - let psmeta = state.metadata_mut::()?; - - hash %= psmeta.n_fuzz().len(); - // Update the path frequency - psmeta.n_fuzz_mut()[hash] = psmeta.n_fuzz()[hash].saturating_add(1); - - self.set_last_hash(hash); - - Ok(()) - } - - /// Called when choosing the next [`Testcase`] - fn on_next_metadata(&mut self, state: &mut S, _next_id: Option) -> Result<(), Error> { - let current_id = *state.corpus().current(); - - if let Some(id) = current_id { - let mut testcase = state.testcase_mut(id)?; - let tcmeta = testcase.metadata_mut::()?; - - if tcmeta.handicap() >= 4 { - tcmeta.set_handicap(tcmeta.handicap() - 4); - } else if tcmeta.handicap() > 0 { - tcmeta.set_handicap(tcmeta.handicap() - 1); - } - } - - Ok(()) - } } /// Trait for Schedulers which track queue cycles @@ -168,10 +174,7 @@ pub trait HasQueueCycles { /// The scheduler define how the fuzzer requests a testcase from the corpus. /// It has hooks to corpus add/replace/remove to allow complex scheduling algorithms to collect data. -pub trait Scheduler -where - S: HasCorpus, -{ +pub trait Scheduler { /// Called when a [`Testcase`] is added to the corpus fn on_add(&mut self, _state: &mut S, _id: CorpusId) -> Result<(), Error>; // Add parent_id here if it has no inner @@ -184,7 +187,7 @@ where _observers: &OT, ) -> Result<(), Error> where - OT: ObserversTuple, + OT: MatchName, { Ok(()) } @@ -198,10 +201,10 @@ where &mut self, state: &mut S, next_id: Option, - ) -> Result<(), Error> { - *state.corpus_mut().current_mut() = next_id; - Ok(()) - } + ) -> Result<(), Error>; + + // *state.corpus_mut().current_mut() = next_id; + // Ok(()) } /// Feed the fuzzer simply with a random testcase on request @@ -212,7 +215,7 @@ pub struct RandScheduler { impl Scheduler for RandScheduler where - S: HasCorpus + HasRand + HasTestcase + State, + S: HasCorpus + HasRand + HasTestcase, { fn on_add(&mut self, state: &mut S, id: CorpusId) -> Result<(), Error> { // Set parent id @@ -239,6 +242,15 @@ where Ok(id) } } + + fn set_current_scheduled( + &mut self, + state: &mut S, + next_id: Option, + ) -> Result<(), Error> { + *state.corpus_mut().current_mut() = next_id; + Ok(()) + } } impl RandScheduler { diff --git a/libafl/src/schedulers/powersched.rs b/libafl/src/schedulers/powersched.rs index 5de71076c0..8da02f38c2 100644 --- a/libafl/src/schedulers/powersched.rs +++ b/libafl/src/schedulers/powersched.rs @@ -4,16 +4,18 @@ use alloc::vec::Vec; use core::{marker::PhantomData, time::Duration}; use libafl_bolts::{ - tuples::{Handle, Handled}, + tuples::{Handle, Handled, MatchName}, Named, }; use serde::{Deserialize, Serialize}; use crate::{ corpus::{Corpus, CorpusId, HasTestcase, Testcase}, - inputs::Input, - observers::{MapObserver, ObserversTuple}, - schedulers::{AflScheduler, HasQueueCycles, RemovableScheduler, Scheduler}, + observers::MapObserver, + schedulers::{ + on_add_metadata_default, on_evaluation_metadata_default, on_next_metadata_default, + AflScheduler, HasQueueCycles, RemovableScheduler, Scheduler, + }, state::{HasCorpus, State}, Error, HasMetadata, }; @@ -271,21 +273,15 @@ pub enum BaseSchedule { /// Note that this corpus is merely holding the metadata necessary for the power calculation /// and here we DON'T actually calculate the power (we do it in the stage) #[derive(Clone, Debug)] -pub struct PowerQueueScheduler { +pub struct PowerQueueScheduler { queue_cycles: u64, strat: PowerSchedule, map_observer_handle: Handle, last_hash: usize, - phantom: PhantomData<(I, O, S)>, + phantom: PhantomData, } -impl RemovableScheduler for PowerQueueScheduler -where - S: State + HasTestcase + HasMetadata + HasCorpus, - O: MapObserver, - C: AsRef, - I: Input, -{ +impl RemovableScheduler for PowerQueueScheduler { /// This will *NOT* neutralize the effect of this removed testcase from the global data such as `SchedulerMetadata` fn on_remove( &mut self, @@ -307,12 +303,7 @@ where } } -impl AflScheduler for PowerQueueScheduler -where - S: HasCorpus + HasMetadata + HasTestcase + State, - O: MapObserver, - C: AsRef, -{ +impl AflScheduler for PowerQueueScheduler { type MapObserverRef = C; fn last_hash(&self) -> usize { @@ -328,18 +319,13 @@ where } } -impl HasQueueCycles for PowerQueueScheduler -where - S: HasCorpus + HasMetadata + HasTestcase + State, - O: MapObserver, - C: AsRef, -{ +impl HasQueueCycles for PowerQueueScheduler { fn queue_cycles(&self) -> u64 { self.queue_cycles } } -impl Scheduler for PowerQueueScheduler +impl Scheduler for PowerQueueScheduler where S: HasCorpus + HasMetadata + HasTestcase + State, O: MapObserver, @@ -347,14 +333,14 @@ where { /// Called when a [`Testcase`] is added to the corpus fn on_add(&mut self, state: &mut S, id: CorpusId) -> Result<(), Error> { - >::on_add_metadata(self, state, id) + on_add_metadata_default(self, state, id) } - fn on_evaluation(&mut self, state: &mut S, input: &I, observers: &OT) -> Result<(), Error> + fn on_evaluation(&mut self, state: &mut S, _input: &I, observers: &OT) -> Result<(), Error> where - OT: ObserversTuple, + OT: MatchName, { - self.on_evaluation_metadata(state, input, observers) + on_evaluation_metadata_default(self, state, observers) } fn next(&mut self, state: &mut S) -> Result { @@ -376,7 +362,7 @@ where } None => state.corpus().first().unwrap(), }; - self.set_current_scheduled(state, Some(id))?; + >::set_current_scheduled(self, state, Some(id))?; Ok(id) } @@ -388,22 +374,24 @@ where state: &mut S, next_id: Option, ) -> Result<(), Error> { - >::on_next_metadata(self, state, next_id)?; + on_next_metadata_default(state)?; *state.corpus_mut().current_mut() = next_id; Ok(()) } } -impl PowerQueueScheduler +impl PowerQueueScheduler where - S: HasMetadata, O: MapObserver, C: AsRef + Named, { /// Create a new [`PowerQueueScheduler`] #[must_use] - pub fn new(state: &mut S, map_observer: &C, strat: PowerSchedule) -> Self { + pub fn new(state: &mut S, map_observer: &C, strat: PowerSchedule) -> Self + where + S: HasMetadata, + { if !state.has_metadata::() { state.add_metadata::(SchedulerMetadata::new(Some(strat))); } diff --git a/libafl/src/schedulers/probabilistic_sampling.rs b/libafl/src/schedulers/probabilistic_sampling.rs index 41d7207ddd..9bb8698de8 100644 --- a/libafl/src/schedulers/probabilistic_sampling.rs +++ b/libafl/src/schedulers/probabilistic_sampling.rs @@ -9,17 +9,17 @@ use libafl_bolts::rands::Rand; use serde::{Deserialize, Serialize}; use crate::{ - corpus::{Corpus, CorpusId, HasTestcase, Testcase}, + corpus::{Corpus, CorpusId, Testcase}, inputs::Input, schedulers::{RemovableScheduler, Scheduler, TestcaseScore}, - state::{HasCorpus, HasRand, State}, + state::{HasCorpus, HasRand}, Error, HasMetadata, }; /// Conduct reservoir sampling (probabilistic sampling) over all corpus elements. #[derive(Debug, Clone)] -pub struct ProbabilitySamplingScheduler { - phantom: PhantomData<(F, I, S)>, +pub struct ProbabilitySamplingScheduler { + phantom: PhantomData, } /// A state metadata holding a map of probability of corpus elements. @@ -54,12 +54,7 @@ impl Default for ProbabilityMetadata { } } -impl ProbabilitySamplingScheduler -where - F: TestcaseScore, - I: Input, - S: HasCorpus + HasMetadata + HasRand, -{ +impl ProbabilitySamplingScheduler { /// Creates a new [`struct@ProbabilitySamplingScheduler`] #[must_use] pub fn new() -> Self { @@ -71,7 +66,12 @@ where /// Calculate the score and store in `ProbabilityMetadata` #[allow(clippy::cast_precision_loss)] #[allow(clippy::unused_self)] - pub fn store_probability(&self, state: &mut S, id: CorpusId) -> Result<(), Error> { + pub fn store_probability(&self, state: &mut S, id: CorpusId) -> Result<(), Error> + where + F: TestcaseScore, + I: Input, + S: HasCorpus + HasMetadata + HasRand, + { let prob = F::compute(state, &mut *state.corpus().get(id)?.borrow_mut())?; debug_assert!( prob >= 0.0 && prob.is_finite(), @@ -87,11 +87,11 @@ where } } -impl RemovableScheduler for ProbabilitySamplingScheduler +impl RemovableScheduler for ProbabilitySamplingScheduler where F: TestcaseScore, I: Input, - S: HasCorpus + HasMetadata + HasRand + HasTestcase + State, + S: HasCorpus + HasMetadata + HasRand, { fn on_remove( &mut self, @@ -127,11 +127,11 @@ where } } -impl Scheduler for ProbabilitySamplingScheduler +impl Scheduler for ProbabilitySamplingScheduler where F: TestcaseScore, I: Input, - S: HasCorpus + HasMetadata + HasRand + HasTestcase + State, + S: HasCorpus + HasMetadata + HasRand, { fn on_add(&mut self, state: &mut S, id: CorpusId) -> Result<(), Error> { let current_id = *state.corpus().current(); @@ -171,14 +171,18 @@ where Ok(ret) } } + + fn set_current_scheduled( + &mut self, + state: &mut S, + next_id: Option, + ) -> Result<(), Error> { + *state.corpus_mut().current_mut() = next_id; + Ok(()) + } } -impl Default for ProbabilitySamplingScheduler -where - F: TestcaseScore, - I: Input, - S: HasCorpus + HasMetadata + HasRand, -{ +impl Default for ProbabilitySamplingScheduler { fn default() -> Self { Self::new() } @@ -187,41 +191,35 @@ where #[cfg(test)] #[cfg(feature = "std")] mod tests { - use core::{borrow::BorrowMut, marker::PhantomData}; + use core::borrow::BorrowMut; use libafl_bolts::rands::StdRand; use crate::{ corpus::{Corpus, InMemoryCorpus, Testcase}, feedbacks::ConstFeedback, - inputs::{bytes::BytesInput, Input}, + inputs::bytes::BytesInput, schedulers::{ProbabilitySamplingScheduler, Scheduler, TestcaseScore}, state::{HasCorpus, StdState}, - Error, HasMetadata, + Error, }; const FACTOR: f64 = 1337.0; #[derive(Debug, Clone)] - pub struct UniformDistribution - where - I: Input, - { - phantom: PhantomData, - } + pub struct UniformDistribution {} - impl TestcaseScore for UniformDistribution + impl TestcaseScore for UniformDistribution where - S: HasMetadata + HasCorpus, - I: Input, + S: HasCorpus, { fn compute(_state: &S, _: &mut Testcase) -> Result { Ok(FACTOR) } } - pub type UniformProbabilitySamplingScheduler = - ProbabilitySamplingScheduler, I, S>; + pub type UniformProbabilitySamplingScheduler = + ProbabilitySamplingScheduler; #[test] fn test_prob_sampling() { @@ -235,7 +233,7 @@ mod tests { // the first 3 probabilities will be .76, .86, .36 let rand = StdRand::with_seed(2); - let mut scheduler: ProbabilitySamplingScheduler<_, BytesInput, _> = + let mut scheduler: ProbabilitySamplingScheduler<_> = UniformProbabilitySamplingScheduler::new(); let mut feedback = ConstFeedback::new(false); diff --git a/libafl/src/schedulers/queue.rs b/libafl/src/schedulers/queue.rs index 605c1940e9..8787eb5379 100644 --- a/libafl/src/schedulers/queue.rs +++ b/libafl/src/schedulers/queue.rs @@ -1,29 +1,26 @@ //! The queue corpus scheduler implements an AFL-like queue mechanism use alloc::borrow::ToOwned; -use core::marker::PhantomData; use crate::{ - corpus::{Corpus, CorpusId, HasTestcase}, - inputs::Input, + corpus::{Corpus, CorpusId}, schedulers::{HasQueueCycles, RemovableScheduler, Scheduler}, - state::{HasCorpus, State}, + state::HasCorpus, Error, }; /// Walk the corpus in a queue-like fashion #[derive(Debug, Clone)] -pub struct QueueScheduler { +pub struct QueueScheduler { queue_cycles: u64, runs_in_current_cycle: u64, - phantom: PhantomData<(I, S)>, } -impl RemovableScheduler for QueueScheduler where I: Input {} +impl RemovableScheduler for QueueScheduler {} -impl Scheduler for QueueScheduler +impl Scheduler for QueueScheduler where - S: HasCorpus + HasTestcase + State, + S: HasCorpus, { fn on_add(&mut self, state: &mut S, id: CorpusId) -> Result<(), Error> { // Set parent id @@ -57,31 +54,39 @@ where if self.runs_in_current_cycle >= state.corpus().count() as u64 { self.queue_cycles += 1; } - self.set_current_scheduled(state, Some(id))?; + >::set_current_scheduled(self, state, Some(id))?; Ok(id) } } + + fn set_current_scheduled( + &mut self, + state: &mut S, + next_id: Option, + ) -> Result<(), Error> { + *state.corpus_mut().current_mut() = next_id; + Ok(()) + } } -impl QueueScheduler { +impl QueueScheduler { /// Creates a new `QueueScheduler` #[must_use] pub fn new() -> Self { Self { runs_in_current_cycle: 0, queue_cycles: 0, - phantom: PhantomData, } } } -impl Default for QueueScheduler { +impl Default for QueueScheduler { fn default() -> Self { Self::new() } } -impl HasQueueCycles for QueueScheduler { +impl HasQueueCycles for QueueScheduler { fn queue_cycles(&self) -> u64 { self.queue_cycles } @@ -106,7 +111,7 @@ mod tests { #[test] fn test_queuecorpus() { let rand = StdRand::with_seed(4); - let mut scheduler: QueueScheduler = QueueScheduler::new(); + let mut scheduler: QueueScheduler = QueueScheduler::new(); let mut q = OnDiskCorpus::::new(PathBuf::from("target/.test/fancy/path")).unwrap(); @@ -122,7 +127,8 @@ mod tests { let mut state = StdState::new(rand, q, objective_q, &mut feedback, &mut objective).unwrap(); - let next_id = scheduler.next(&mut state).unwrap(); + let next_id = + >::next(&mut scheduler, &mut state).unwrap(); let filename = state .corpus() .get(next_id) diff --git a/libafl/src/schedulers/testcase_score.rs b/libafl/src/schedulers/testcase_score.rs index d11404d3a2..4cb09f2138 100644 --- a/libafl/src/schedulers/testcase_score.rs +++ b/libafl/src/schedulers/testcase_score.rs @@ -1,13 +1,11 @@ //! The `TestcaseScore` is an evaluator providing scores of corpus items. use alloc::string::{String, ToString}; -use core::marker::PhantomData; use libafl_bolts::{HasLen, HasRefCnt}; use crate::{ corpus::{Corpus, SchedulerTestcaseMetadata, Testcase}, feedbacks::MapIndexesMetadata, - inputs::Input, schedulers::{ minimizer::{IsFavoredMetadata, TopRatedsMetadata}, powersched::{BaseSchedule, SchedulerMetadata}, @@ -17,11 +15,7 @@ use crate::{ }; /// Compute the favor factor of a [`Testcase`]. Higher is better. -pub trait TestcaseScore -where - S: HasMetadata + HasCorpus, - I: Input, -{ +pub trait TestcaseScore { /// Computes the favor factor of a [`Testcase`]. Higher is better. fn compute(state: &S, entry: &mut Testcase) -> Result; } @@ -29,14 +23,12 @@ where /// Multiply the testcase size with the execution time. /// This favors small and quick testcases. #[derive(Debug, Clone)] -pub struct LenTimeMulTestcaseScore { - phantom: PhantomData<(I, S)>, -} +pub struct LenTimeMulTestcaseScore {} -impl TestcaseScore for LenTimeMulTestcaseScore +impl TestcaseScore for LenTimeMulTestcaseScore where - S: HasCorpus + HasMetadata, - I: HasLen + Input, + S: HasCorpus, + I: HasLen, { #[allow(clippy::cast_precision_loss, clippy::cast_lossless)] fn compute(state: &S, entry: &mut Testcase) -> Result { @@ -54,14 +46,11 @@ const HAVOC_MAX_MULT: f64 = 64.0; /// The power assigned to each corpus entry /// This result is used for power scheduling #[derive(Debug, Clone)] -pub struct CorpusPowerTestcaseScore { - phantom: PhantomData, -} +pub struct CorpusPowerTestcaseScore {} -impl TestcaseScore for CorpusPowerTestcaseScore +impl TestcaseScore for CorpusPowerTestcaseScore where S: HasCorpus + HasMetadata, - I: Input, { /// Compute the `power` we assign to each corpus entry #[allow( @@ -276,14 +265,11 @@ where /// The weight for each corpus entry /// This result is used for corpus scheduling #[derive(Debug, Clone)] -pub struct CorpusWeightTestcaseScore { - phantom: PhantomData, -} +pub struct CorpusWeightTestcaseScore {} -impl TestcaseScore for CorpusWeightTestcaseScore +impl TestcaseScore for CorpusWeightTestcaseScore where S: HasCorpus + HasMetadata, - I: Input, { /// Compute the `weight` used in weighted corpus entry selection algo #[allow(clippy::cast_precision_loss, clippy::cast_lossless)] diff --git a/libafl/src/schedulers/tuneable.rs b/libafl/src/schedulers/tuneable.rs index d744be4266..b677e71896 100644 --- a/libafl/src/schedulers/tuneable.rs +++ b/libafl/src/schedulers/tuneable.rs @@ -3,17 +3,15 @@ //! chose the next corpus entry manually use alloc::borrow::ToOwned; -use core::marker::PhantomData; use libafl_bolts::impl_serdeany; use serde::{Deserialize, Serialize}; use super::RemovableScheduler; use crate::{ - corpus::{Corpus, CorpusId, HasTestcase}, - inputs::Input, + corpus::{Corpus, CorpusId}, schedulers::Scheduler, - state::{HasCorpus, State}, + state::HasCorpus, Error, HasMetadata, }; @@ -31,33 +29,35 @@ impl_serdeany!(TuneableSchedulerMetadata); /// Walk the corpus in a queue-like fashion /// With the specific `set_next` method, we can chose the next corpus entry manually #[derive(Debug, Clone)] -pub struct TuneableScheduler { - phantom: PhantomData<(I, S)>, -} +pub struct TuneableScheduler {} -impl TuneableScheduler -where - S: HasMetadata + HasCorpus, -{ +impl TuneableScheduler { /// Creates a new `TuneableScheduler` #[must_use] - pub fn new(state: &mut S) -> Self { + pub fn new(state: &mut S) -> Self + where + S: HasMetadata, + { if !state.has_metadata::() { state.add_metadata(TuneableSchedulerMetadata::default()); } - Self { - phantom: PhantomData, - } + Self {} } - fn metadata_mut(state: &mut S) -> &mut TuneableSchedulerMetadata { + fn metadata_mut(state: &mut S) -> &mut TuneableSchedulerMetadata + where + S: HasMetadata, + { state .metadata_map_mut() .get_mut::() .unwrap() } - fn metadata(state: &S) -> &TuneableSchedulerMetadata { + fn metadata(state: &S) -> &TuneableSchedulerMetadata + where + S: HasMetadata, + { state .metadata_map() .get::() @@ -65,23 +65,35 @@ where } /// Sets the next corpus id to be used - pub fn set_next(state: &mut S, next: CorpusId) { + pub fn set_next(state: &mut S, next: CorpusId) + where + S: HasMetadata, + { Self::metadata_mut(state).next = Some(next); } /// Gets the next set corpus id - pub fn get_next(state: &S) -> Option { + pub fn get_next(state: &S) -> Option + where + S: HasMetadata, + { Self::metadata(state).next } /// Resets this to a queue scheduler - pub fn reset(state: &mut S) { + pub fn reset(state: &mut S) + where + S: HasMetadata, + { let metadata = Self::metadata_mut(state); metadata.next = None; } /// Gets the current corpus entry id - pub fn get_current(state: &S) -> CorpusId { + pub fn get_current(state: &S) -> CorpusId + where + S: HasCorpus, + { state .corpus() .current() @@ -89,11 +101,11 @@ where } } -impl RemovableScheduler for TuneableScheduler where I: Input {} +impl RemovableScheduler for TuneableScheduler {} -impl Scheduler for TuneableScheduler +impl Scheduler for TuneableScheduler where - S: HasCorpus + HasMetadata + HasTestcase + State, + S: HasCorpus + HasMetadata, { fn on_add(&mut self, state: &mut S, id: CorpusId) -> Result<(), Error> { // Set parent id @@ -123,7 +135,15 @@ where } else { state.corpus().first().unwrap() }; - self.set_current_scheduled(state, Some(id))?; + >::set_current_scheduled(self, state, Some(id))?; Ok(id) } + fn set_current_scheduled( + &mut self, + state: &mut S, + next_id: Option, + ) -> Result<(), Error> { + *state.corpus_mut().current_mut() = next_id; + Ok(()) + } } diff --git a/libafl/src/schedulers/weighted.rs b/libafl/src/schedulers/weighted.rs index 4e73da31c4..24760f5e8e 100644 --- a/libafl/src/schedulers/weighted.rs +++ b/libafl/src/schedulers/weighted.rs @@ -8,7 +8,7 @@ use core::marker::PhantomData; use hashbrown::HashMap; use libafl_bolts::{ rands::Rand, - tuples::{Handle, Handled}, + tuples::{Handle, Handled, MatchName}, Named, }; use serde::{Deserialize, Serialize}; @@ -17,14 +17,15 @@ use super::powersched::PowerSchedule; use crate::{ corpus::{Corpus, CorpusId, HasTestcase, Testcase}, inputs::Input, - observers::{MapObserver, ObserversTuple}, + observers::MapObserver, random_corpus_id, schedulers::{ + on_add_metadata_default, on_evaluation_metadata_default, on_next_metadata_default, powersched::{BaseSchedule, SchedulerMetadata}, testcase_score::{CorpusWeightTestcaseScore, TestcaseScore}, AflScheduler, HasQueueCycles, RemovableScheduler, Scheduler, }, - state::{HasCorpus, HasRand, State}, + state::{HasCorpus, HasRand}, Error, HasMetadata, }; @@ -98,34 +99,36 @@ libafl_bolts::impl_serdeany!(WeightedScheduleMetadata); /// A corpus scheduler using power schedules with weighted queue item selection algo. #[derive(Clone, Debug)] -pub struct WeightedScheduler { +pub struct WeightedScheduler { table_invalidated: bool, strat: Option, map_observer_handle: Handle, last_hash: usize, queue_cycles: u64, - phantom: PhantomData<(F, I, O, S)>, + phantom: PhantomData<(F, O)>, /// Cycle `PowerSchedule` on completion of every queue cycle. cycle_schedules: bool, } -impl WeightedScheduler +impl WeightedScheduler where - F: TestcaseScore, - I: Input, - O: MapObserver, - S: HasCorpus + HasMetadata + HasRand, - C: AsRef + Named, + C: Named, { /// Create a new [`WeightedScheduler`] without any power schedule #[must_use] - pub fn new(state: &mut S, map_observer: &C) -> Self { + pub fn new(state: &mut S, map_observer: &C) -> Self + where + S: HasMetadata, + { Self::with_schedule(state, map_observer, None) } /// Create a new [`WeightedScheduler`] #[must_use] - pub fn with_schedule(state: &mut S, map_observer: &C, strat: Option) -> Self { + pub fn with_schedule(state: &mut S, map_observer: &C, strat: Option) -> Self + where + S: HasMetadata, + { let _ = state.metadata_or_insert_with(|| SchedulerMetadata::new(strat)); let _ = state.metadata_or_insert_with(WeightedScheduleMetadata::new); @@ -160,7 +163,12 @@ where clippy::cast_precision_loss, clippy::cast_lossless )] - pub fn create_alias_table(&self, state: &mut S) -> Result<(), Error> { + pub fn create_alias_table(&self, state: &mut S) -> Result<(), Error> + where + F: TestcaseScore, + I: Input, + S: HasCorpus + HasMetadata, + { let n = state.corpus().count(); let mut alias_table: HashMap = HashMap::default(); @@ -258,14 +266,7 @@ where } } -impl RemovableScheduler for WeightedScheduler -where - F: TestcaseScore, - O: MapObserver, - I: Input, - S: HasCorpus + HasMetadata + HasRand + HasTestcase + State, - C: AsRef + Named, -{ +impl RemovableScheduler for WeightedScheduler { /// This will *NOT* neutralize the effect of this removed testcase from the global data such as `SchedulerMetadata` fn on_remove( &mut self, @@ -289,14 +290,7 @@ where } } -impl AflScheduler for WeightedScheduler -where - F: TestcaseScore, - I: Input, - O: MapObserver, - S: HasCorpus + HasMetadata + HasTestcase + HasRand + State, - C: AsRef + Named, -{ +impl AflScheduler for WeightedScheduler { type MapObserverRef = C; fn last_hash(&self) -> usize { @@ -312,39 +306,32 @@ where } } -impl HasQueueCycles for WeightedScheduler -where - F: TestcaseScore, - I: Input, - O: MapObserver, - S: HasCorpus + HasMetadata + HasRand + HasTestcase + State, - C: AsRef + Named, -{ +impl HasQueueCycles for WeightedScheduler { fn queue_cycles(&self) -> u64 { self.queue_cycles } } -impl Scheduler for WeightedScheduler +impl Scheduler for WeightedScheduler where + C: AsRef + Named, F: TestcaseScore, I: Input, O: MapObserver, - S: HasCorpus + HasMetadata + HasRand + HasTestcase + State, - C: AsRef + Named, + S: HasCorpus + HasMetadata + HasRand + HasTestcase, { /// Called when a [`Testcase`] is added to the corpus fn on_add(&mut self, state: &mut S, id: CorpusId) -> Result<(), Error> { - self.on_add_metadata(state, id)?; + on_add_metadata_default(self, state, id)?; self.table_invalidated = true; Ok(()) } - fn on_evaluation(&mut self, state: &mut S, input: &I, observers: &OT) -> Result<(), Error> + fn on_evaluation(&mut self, state: &mut S, _input: &I, observers: &OT) -> Result<(), Error> where - OT: ObserversTuple, + OT: MatchName, { - self.on_evaluation_metadata(state, input, observers) + on_evaluation_metadata_default(self, state, observers) } #[allow(clippy::similar_names, clippy::cast_precision_loss)] @@ -402,7 +389,7 @@ where state: &mut S, next_id: Option, ) -> Result<(), Error> { - self.on_next_metadata(state, next_id)?; + on_next_metadata_default(state)?; *state.corpus_mut().current_mut() = next_id; Ok(()) @@ -410,5 +397,4 @@ where } /// The standard corpus weight, same as in `AFL++` -pub type StdWeightedScheduler = - WeightedScheduler, I, O, S>; +pub type StdWeightedScheduler = WeightedScheduler; diff --git a/libafl/src/stages/power.rs b/libafl/src/stages/power.rs index 7b3ce40678..ce88469535 100644 --- a/libafl/src/stages/power.rs +++ b/libafl/src/stages/power.rs @@ -143,4 +143,4 @@ where /// The standard powerscheduling stage pub type StdPowerMutationalStage = - PowerMutationalStage::State>, EM, I, M, Z>; + PowerMutationalStage;