From 41f16890b85a3ea97e8d97807501456356a63c14 Mon Sep 17 00:00:00 2001 From: Dhanvith Nayak <85876638+BAGUVIX456@users.noreply.github.com> Date: Fri, 7 Mar 2025 18:48:48 +0530 Subject: [PATCH] convert share_objectives into a runtime option (#3033) * add share_objectives field to StdFuzzer * uhhh maybe add field to StdState instead * trivial * implement to handle_in_client() * fmt * revert changes to state * no gating on receiving objectives * add query method to hasobjectives * make input field of Event::Objective optional * fmt and clippy * move setter to hasobjectives * better way to handle incoming objective * fmt --------- Co-authored-by: Dongjia "toka" Zhang --- libafl/Cargo.toml | 3 --- libafl/src/events/llmp/mod.rs | 9 ++++--- libafl/src/events/llmp/restarting.rs | 2 -- libafl/src/events/mod.rs | 3 +-- libafl/src/events/tcp.rs | 1 - libafl/src/executors/inprocess/mod.rs | 4 +-- libafl/src/fuzzer/mod.rs | 38 ++++++++++++++++++++------- libafl/src/stages/sync.rs | 4 +-- libafl_targets/src/drcov.rs | 8 +++++- 9 files changed, 44 insertions(+), 28 deletions(-) diff --git a/libafl/Cargo.toml b/libafl/Cargo.toml index d5b15f2dd8..cf38918683 100644 --- a/libafl/Cargo.toml +++ b/libafl/Cargo.toml @@ -142,9 +142,6 @@ unicode = ["libafl_bolts/alloc", "ahash/std", "serde/rc", "bitvec"] ## Enable multi-part input formats and mutators multipart_inputs = ["arrayvec", "rand_trait"] -## Share objectives across nodes -share_objectives = [] - #! ## LibAFL-Bolts Features ## Provide the `#[derive(SerdeAny)]` macro. diff --git a/libafl/src/events/llmp/mod.rs b/libafl/src/events/llmp/mod.rs index 7da1efb176..7c14f218c2 100644 --- a/libafl/src/events/llmp/mod.rs +++ b/libafl/src/events/llmp/mod.rs @@ -291,9 +291,10 @@ where } Ok(()) } - - #[cfg(feature = "share_objectives")] - Event::Objective { input, .. } => { + Event::Objective { + input: Some(unwrapped_input), + .. + } => { log::debug!("Received new Objective"); let Some(converter) = self.converter_back.as_mut() else { @@ -304,7 +305,7 @@ where state, executor, manager, - &converter.convert(input)?, + &converter.convert(unwrapped_input)?, false, )?; diff --git a/libafl/src/events/llmp/restarting.rs b/libafl/src/events/llmp/restarting.rs index f35bd2821a..8a8ff80edb 100644 --- a/libafl/src/events/llmp/restarting.rs +++ b/libafl/src/events/llmp/restarting.rs @@ -377,8 +377,6 @@ where return Ok(Some((event, false))); } - - #[cfg(feature = "share_objectives")] Event::Objective { .. } => { #[cfg(feature = "std")] log::debug!("[{}] Received new Objective", std::process::id()); diff --git a/libafl/src/events/mod.rs b/libafl/src/events/mod.rs index 396e78796d..c350cf3de7 100644 --- a/libafl/src/events/mod.rs +++ b/libafl/src/events/mod.rs @@ -300,8 +300,7 @@ pub enum Event { /// A new objective was found Objective { /// Input of newly found Objective - #[cfg(feature = "share_objectives")] - input: I, + input: Option, /// Objective corpus size objective_size: usize, /// The time when this event was created diff --git a/libafl/src/events/tcp.rs b/libafl/src/events/tcp.rs index 70bc9a1f3f..a4d280a0c6 100644 --- a/libafl/src/events/tcp.rs +++ b/libafl/src/events/tcp.rs @@ -700,7 +700,6 @@ where } return Ok(Some((event, false))); } - #[cfg(feature = "share_objectives")] Event::Objective { .. } => { log::info!("Received new Objective"); return Ok(Some((event, false))); diff --git a/libafl/src/executors/inprocess/mod.rs b/libafl/src/executors/inprocess/mod.rs index fd92a20e47..c2092492a3 100644 --- a/libafl/src/executors/inprocess/mod.rs +++ b/libafl/src/executors/inprocess/mod.rs @@ -430,9 +430,7 @@ pub fn run_observers_and_save_state( .fire( state, Event::Objective { - #[cfg(feature = "share_objectives")] - input: input.clone(), - + input: fuzzer.share_objectives().then_some(input.clone()), objective_size: state.solutions().count(), time: libafl_bolts::current_time(), }, diff --git a/libafl/src/fuzzer/mod.rs b/libafl/src/fuzzer/mod.rs index d7a0f73ccc..cfc41f05f2 100644 --- a/libafl/src/fuzzer/mod.rs +++ b/libafl/src/fuzzer/mod.rs @@ -70,6 +70,12 @@ pub trait HasObjective { /// The objective feedback (mutable) fn objective_mut(&mut self) -> &mut Self::Objective; + + /// Whether to share objective testcases among fuzzing nodes + fn share_objectives(&self) -> bool; + + /// Sets whether to share objectives among nodes + fn set_share_objectives(&mut self, share_objectives: bool); } /// Evaluates if an input is interesting using the feedback @@ -292,6 +298,8 @@ pub struct StdFuzzer { feedback: F, objective: OF, input_filter: IF, + // Handles whether to share objective testcases among nodes + share_objectives: bool, } impl HasScheduler for StdFuzzer @@ -331,6 +339,14 @@ impl HasObjective for StdFuzzer { fn objective_mut(&mut self) -> &mut OF { &mut self.objective } + + fn set_share_objectives(&mut self, share_objectives: bool) { + self.share_objectives = share_objectives; + } + + fn share_objectives(&self) -> bool { + self.share_objectives + } } impl ExecutionProcessor for StdFuzzer @@ -480,14 +496,11 @@ where }, )?; } - if exec_res.is_solution() { manager.fire( state, Event::Objective { - #[cfg(feature = "share_objectives")] - input: input.clone(), - + input: self.share_objectives.then_some(input.clone()), objective_size: state.solutions().count(), time: current_time(), }, @@ -677,9 +690,7 @@ where manager.fire( state, Event::Objective { - #[cfg(feature = "share_objectives")] - input: input.clone(), - + input: self.share_objectives.then_some(input.clone()), objective_size: state.solutions().count(), time: current_time(), }, @@ -802,10 +813,16 @@ where )?; res.1 } - #[cfg(feature = "share_objectives")] - Event::Objective { ref input, .. } => { + Event::Objective { + input: Some(ref unwrapped_input), + .. + } => { let res = self.evaluate_input_with_observers( - state, executor, manager, input, false, + state, + executor, + manager, + unwrapped_input, + false, )?; res.1 } @@ -966,6 +983,7 @@ impl StdFuzzer { feedback, objective, input_filter, + share_objectives: false, } } } diff --git a/libafl/src/stages/sync.rs b/libafl/src/stages/sync.rs index 8a7a1cfe29..8b2d3fbdb4 100644 --- a/libafl/src/stages/sync.rs +++ b/libafl/src/stages/sync.rs @@ -19,7 +19,7 @@ use crate::{ corpus::{Corpus, CorpusId, HasCurrentCorpusId}, events::{Event, EventConfig, EventFirer, llmp::LlmpEventConverter}, executors::{Executor, ExitKind, HasObservers}, - fuzzer::{Evaluator, EvaluatorObservers, ExecutionProcessor}, + fuzzer::{Evaluator, EvaluatorObservers, ExecutionProcessor, HasObjective}, inputs::{Input, InputConverter}, stages::{Restartable, RetryCountRestartHelper, Stage}, state::{ @@ -248,7 +248,7 @@ where + MaybeHasClientPerfMonitor, SHM: ShMem, SP: ShMemProvider, - Z: EvaluatorObservers + ExecutionProcessor, + Z: EvaluatorObservers + ExecutionProcessor + HasObjective, { #[inline] fn perform( diff --git a/libafl_targets/src/drcov.rs b/libafl_targets/src/drcov.rs index 83170ae32b..05f35804db 100644 --- a/libafl_targets/src/drcov.rs +++ b/libafl_targets/src/drcov.rs @@ -218,7 +218,13 @@ impl DrCovModuleEntry { pub fn to_module_line(&self) -> String { format!( "{:03}, 0x{:x}, 0x{:x}, 0x{:x}, 0x{:x}, 0x{:x}, {}", - self.id, self.base, self.end, self.entry, self.checksum, self.timestamp, self.path.display() + self.id, + self.base, + self.end, + self.entry, + self.checksum, + self.timestamp, + self.path.display() ) } }