diff --git a/libafl/src/corpus/testcase.rs b/libafl/src/corpus/testcase.rs index cb5422ea9f..ded6265777 100644 --- a/libafl/src/corpus/testcase.rs +++ b/libafl/src/corpus/testcase.rs @@ -65,6 +65,8 @@ where parent_id: Option, /// If the testcase is "disabled" disabled: bool, + /// has found crash (or timeout) or not + objectives_found: usize, } impl HasMetadata for Testcase @@ -227,6 +229,7 @@ where scheduled_count: 0, parent_id: None, disabled: false, + objectives_found: 0, } } @@ -248,6 +251,7 @@ where scheduled_count: 0, parent_id: Some(parent_id), disabled: false, + objectives_found: 0, } } @@ -269,6 +273,7 @@ where scheduled_count: 0, parent_id: None, disabled: false, + objectives_found: 0, } } @@ -290,6 +295,7 @@ where scheduled_count: 0, parent_id: None, disabled: false, + objectives_found: 0, } } @@ -308,6 +314,16 @@ where pub fn set_parent_id_optional(&mut self, parent_id: Option) { self.parent_id = parent_id; } + + /// Gets how many objectives were found by mutating this testcase + pub fn objectives_found(&self) -> usize { + self.objectives_found + } + + /// Adds one objectives to the `objectives_found` counter. Mostly called from crash handler or executor. + pub fn found_objective(&mut self) { + let _ = self.objectives_found.saturating_add(1); + } } impl Default for Testcase @@ -331,6 +347,7 @@ where #[cfg(feature = "std")] metadata_path: None, disabled: false, + objectives_found: 0, } } } diff --git a/libafl/src/executors/inprocess/mod.rs b/libafl/src/executors/inprocess/mod.rs index bd8edb51fe..97df8116b0 100644 --- a/libafl/src/executors/inprocess/mod.rs +++ b/libafl/src/executors/inprocess/mod.rs @@ -32,7 +32,7 @@ use crate::{ fuzzer::HasObjective, inputs::UsesInput, observers::{ObserversTuple, UsesObservers}, - state::{HasCorpus, HasExecutions, HasSolutions, State, UsesState}, + state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions, State, UsesState}, Error, HasMetadata, }; @@ -454,6 +454,11 @@ pub fn run_observers_and_save_state( let mut new_testcase = Testcase::with_executions(input.clone(), executions); new_testcase.add_metadata(exitkind); new_testcase.set_parent_id_optional(*state.corpus().current()); + + if let Ok(mut tc) = state.current_testcase_mut() { + tc.found_objective(); + } + fuzzer .objective_mut() .append_metadata(state, event_mgr, &*observers, &mut new_testcase) diff --git a/libafl/src/fuzzer/mod.rs b/libafl/src/fuzzer/mod.rs index eb5d99aa3b..f55016573e 100644 --- a/libafl/src/fuzzer/mod.rs +++ b/libafl/src/fuzzer/mod.rs @@ -17,7 +17,10 @@ use crate::{ schedulers::Scheduler, stages::{HasCurrentStage, StagesTuple}, start_timer, - state::{HasCorpus, HasExecutions, HasImported, HasLastReportTime, HasSolutions, UsesState}, + state::{ + HasCorpus, HasCurrentTestcase, HasExecutions, HasImported, HasLastReportTime, HasSolutions, + UsesState, + }, Error, HasMetadata, }; #[cfg(feature = "introspection")] @@ -360,7 +363,13 @@ where F: Feedback, OF: Feedback, OT: ObserversTuple + Serialize + DeserializeOwned, - CS::State: HasCorpus + HasSolutions + HasExecutions + HasCorpus + HasImported, + CS::State: HasCorpus + + HasSolutions + + HasExecutions + + HasCorpus + + HasImported + + HasCurrentTestcase<::Input> + + HasCurrentCorpusIdx, { fn execute_no_process( &mut self, @@ -495,6 +504,9 @@ where // The input is a solution, add it to the respective corpus let mut testcase = Testcase::with_executions(input, executions); testcase.set_parent_id_optional(*state.corpus().current()); + if let Ok(mut tc) = state.current_testcase_mut() { + tc.found_objective(); + } self.objective_mut() .append_metadata(state, manager, observers, &mut testcase)?; state.solutions_mut().add(testcase)?; diff --git a/libafl/src/schedulers/testcase_score.rs b/libafl/src/schedulers/testcase_score.rs index 0acfc4508e..4e57549712 100644 --- a/libafl/src/schedulers/testcase_score.rs +++ b/libafl/src/schedulers/testcase_score.rs @@ -303,19 +303,13 @@ where let q_bitmap_size = tcmeta.bitmap_size() as f64; - if let Some(strat) = psmeta.strat() { - match strat { - PowerSchedule::FAST - | PowerSchedule::COE - | PowerSchedule::LIN - | PowerSchedule::QUAD => { - let hits = psmeta.n_fuzz()[tcmeta.n_fuzz_entry()]; - if hits > 0 { - weight /= libm::log10(f64::from(hits)) + 1.0; - } - } - // EXPLORE and EXPLOIT fall into this - _ => {} + 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; } }