From 902571c0c7b8a71e1825bf9ab500cf84f7207efe Mon Sep 17 00:00:00 2001 From: "Dongjia \"toka\" Zhang" Date: Wed, 18 Sep 2024 17:35:31 +0200 Subject: [PATCH] Delete pruning.rs (#2533) * set AFL_MAP_SIZE * delete it --- libafl/src/stages/mod.rs | 3 - libafl/src/stages/pruning.rs | 195 ----------------------------------- 2 files changed, 198 deletions(-) delete mode 100644 libafl/src/stages/pruning.rs diff --git a/libafl/src/stages/mod.rs b/libafl/src/stages/mod.rs index 6c7293d41a..b0f08bf55f 100644 --- a/libafl/src/stages/mod.rs +++ b/libafl/src/stages/mod.rs @@ -79,9 +79,6 @@ pub mod tuneable; #[cfg(feature = "unicode")] pub mod unicode; -pub mod pruning; -pub use pruning::*; - /// A stage is one step in the fuzzing process. /// Multiple stages will be scheduled one by one for each input. pub trait Stage: UsesState diff --git a/libafl/src/stages/pruning.rs b/libafl/src/stages/pruning.rs deleted file mode 100644 index 33f7d771b1..0000000000 --- a/libafl/src/stages/pruning.rs +++ /dev/null @@ -1,195 +0,0 @@ -//! Corpus pruning stage - -use alloc::string::ToString; -use core::marker::PhantomData; - -use libafl_bolts::{rands::Rand, Error}; - -use crate::{ - corpus::{Corpus, HasCurrentCorpusId}, - schedulers::{RemovableScheduler, Scheduler}, - stages::Stage, - state::{HasCorpus, HasRand, UsesState}, - HasScheduler, -}; -#[cfg(feature = "std")] -use crate::{events::EventRestarter, state::Stoppable}; - -#[derive(Debug)] -/// The stage to probabilistically disable a corpus entry. -/// -/// This stage should be wrapped in a if stage and run only when the fuzzer perform restarting -/// The idea comes from `https://mschloegel.me/paper/schiller2023fuzzerrestarts.pdf` -pub struct CorpusPruning { - /// The chance of retaining this corpus - prob: f64, - phantom: PhantomData, -} - -impl CorpusPruning { - fn new(prob: f64) -> Self { - Self { - prob, - phantom: PhantomData, - } - } -} - -impl Default for CorpusPruning { - fn default() -> Self { - Self::new(0.05) - } -} - -impl UsesState for CorpusPruning -where - EM: UsesState, -{ - type State = EM::State; -} - -impl Stage for CorpusPruning -where - EM: UsesState, - E: UsesState, - Z: UsesState + HasScheduler, - ::Scheduler: RemovableScheduler, - Self::State: HasCorpus + HasRand, -{ - #[allow(clippy::cast_precision_loss)] - fn perform( - &mut self, - fuzzer: &mut Z, - _executor: &mut E, - state: &mut Self::State, - _manager: &mut EM, - ) -> Result<(), Error> { - // Iterate over every corpus entr - let n_all = state.corpus().count_all(); - let n_enabled = state.corpus().count(); - - let Some(currently_fuzzed_idx) = state.current_corpus_id()? else { - return Err(Error::illegal_state("Not fuzzing any testcase".to_string())); - }; - - // eprintln!("Currently fuzzing {:#?}", currently_fuzzed_idx); - - let mut disabled_to_enabled = vec![]; - let mut enabled_to_disabled = vec![]; - // do it backwards so that the index won't change even after remove - for i in (0..n_all).rev() { - let r = state.rand_mut().below(100) as f64; - if self.prob * 100_f64 < r { - let idx = state.corpus().nth_from_all(i); - - // skip the currently fuzzed id; don't remove it - // because else after restart we can't call currrent.next() to find the next testcase - if idx == currently_fuzzed_idx { - // eprintln!("skipping {:#?}", idx); - continue; - } - - let removed = state.corpus_mut().remove(idx)?; - fuzzer - .scheduler_mut() - .on_remove(state, idx, &Some(removed.clone()))?; - // because [n_enabled, n_all) is disabled testcases - // and [0, n_enabled) is enabled testcases - if i >= n_enabled { - // we are moving disabled to enabled now - disabled_to_enabled.push((idx, removed)); - } else { - // we are moving enabled to disabled now - enabled_to_disabled.push((idx, removed)); - } - } - } - - // Actually move them - for (idx, testcase) in disabled_to_enabled { - state.corpus_mut().add(testcase)?; - fuzzer.scheduler_mut().on_add(state, idx)?; - } - - for (idx, testcase) in enabled_to_disabled { - state.corpus_mut().add_disabled(testcase)?; - fuzzer.scheduler_mut().on_add(state, idx)?; - } - /* - eprintln!( - "There was {}, and we retained {} corpura", - n_all, - state.corpus().count() - ); - */ - Ok(()) - } - - fn should_restart(&mut self, _state: &mut Self::State) -> Result { - // Not executing the target, so restart safety is not needed - Ok(true) - } - fn clear_progress(&mut self, _state: &mut Self::State) -> Result<(), Error> { - // Not executing the target, so restart safety is not needed - Ok(()) - } -} - -/// A stage for conditional restart -#[derive(Debug, Default)] -#[cfg(feature = "std")] -pub struct RestartStage { - phantom: PhantomData<(E, EM, Z)>, -} - -#[cfg(feature = "std")] -impl UsesState for RestartStage -where - E: UsesState, -{ - type State = E::State; -} - -#[cfg(feature = "std")] -impl Stage for RestartStage -where - E: UsesState, - EM: UsesState + EventRestarter, - Z: UsesState, -{ - #[allow(unreachable_code)] - fn perform( - &mut self, - _fuzzer: &mut Z, - _executor: &mut E, - state: &mut Self::State, - manager: &mut EM, - ) -> Result<(), Error> { - manager.on_restart(state).unwrap(); - state.request_stop(); - Ok(()) - } - - fn should_restart(&mut self, _state: &mut Self::State) -> Result { - Ok(true) - } - - fn clear_progress(&mut self, _state: &mut Self::State) -> Result<(), Error> { - Ok(()) - } -} - -#[cfg(feature = "std")] -impl RestartStage -where - E: UsesState, -{ - /// Constructor for this conditionally enabled stage. - /// If the closure returns true, the wrapped stage will be executed, else it will be skipped. - #[must_use] - pub fn new() -> Self { - Self { - phantom: PhantomData, - } - } -}