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 <tokazerkje@outlook.com>
This commit is contained in:
parent
76539fa247
commit
41f16890b8
@ -142,9 +142,6 @@ unicode = ["libafl_bolts/alloc", "ahash/std", "serde/rc", "bitvec"]
|
|||||||
## Enable multi-part input formats and mutators
|
## Enable multi-part input formats and mutators
|
||||||
multipart_inputs = ["arrayvec", "rand_trait"]
|
multipart_inputs = ["arrayvec", "rand_trait"]
|
||||||
|
|
||||||
## Share objectives across nodes
|
|
||||||
share_objectives = []
|
|
||||||
|
|
||||||
#! ## LibAFL-Bolts Features
|
#! ## LibAFL-Bolts Features
|
||||||
|
|
||||||
## Provide the `#[derive(SerdeAny)]` macro.
|
## Provide the `#[derive(SerdeAny)]` macro.
|
||||||
|
@ -291,9 +291,10 @@ where
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Event::Objective {
|
||||||
#[cfg(feature = "share_objectives")]
|
input: Some(unwrapped_input),
|
||||||
Event::Objective { input, .. } => {
|
..
|
||||||
|
} => {
|
||||||
log::debug!("Received new Objective");
|
log::debug!("Received new Objective");
|
||||||
|
|
||||||
let Some(converter) = self.converter_back.as_mut() else {
|
let Some(converter) = self.converter_back.as_mut() else {
|
||||||
@ -304,7 +305,7 @@ where
|
|||||||
state,
|
state,
|
||||||
executor,
|
executor,
|
||||||
manager,
|
manager,
|
||||||
&converter.convert(input)?,
|
&converter.convert(unwrapped_input)?,
|
||||||
false,
|
false,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -377,8 +377,6 @@ where
|
|||||||
|
|
||||||
return Ok(Some((event, false)));
|
return Ok(Some((event, false)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "share_objectives")]
|
|
||||||
Event::Objective { .. } => {
|
Event::Objective { .. } => {
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
log::debug!("[{}] Received new Objective", std::process::id());
|
log::debug!("[{}] Received new Objective", std::process::id());
|
||||||
|
@ -300,8 +300,7 @@ pub enum Event<I> {
|
|||||||
/// A new objective was found
|
/// A new objective was found
|
||||||
Objective {
|
Objective {
|
||||||
/// Input of newly found Objective
|
/// Input of newly found Objective
|
||||||
#[cfg(feature = "share_objectives")]
|
input: Option<I>,
|
||||||
input: I,
|
|
||||||
/// Objective corpus size
|
/// Objective corpus size
|
||||||
objective_size: usize,
|
objective_size: usize,
|
||||||
/// The time when this event was created
|
/// The time when this event was created
|
||||||
|
@ -700,7 +700,6 @@ where
|
|||||||
}
|
}
|
||||||
return Ok(Some((event, false)));
|
return Ok(Some((event, false)));
|
||||||
}
|
}
|
||||||
#[cfg(feature = "share_objectives")]
|
|
||||||
Event::Objective { .. } => {
|
Event::Objective { .. } => {
|
||||||
log::info!("Received new Objective");
|
log::info!("Received new Objective");
|
||||||
return Ok(Some((event, false)));
|
return Ok(Some((event, false)));
|
||||||
|
@ -430,9 +430,7 @@ pub fn run_observers_and_save_state<E, EM, F, I, OF, S, Z>(
|
|||||||
.fire(
|
.fire(
|
||||||
state,
|
state,
|
||||||
Event::Objective {
|
Event::Objective {
|
||||||
#[cfg(feature = "share_objectives")]
|
input: fuzzer.share_objectives().then_some(input.clone()),
|
||||||
input: input.clone(),
|
|
||||||
|
|
||||||
objective_size: state.solutions().count(),
|
objective_size: state.solutions().count(),
|
||||||
time: libafl_bolts::current_time(),
|
time: libafl_bolts::current_time(),
|
||||||
},
|
},
|
||||||
|
@ -70,6 +70,12 @@ pub trait HasObjective {
|
|||||||
|
|
||||||
/// The objective feedback (mutable)
|
/// The objective feedback (mutable)
|
||||||
fn objective_mut(&mut self) -> &mut Self::Objective;
|
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
|
/// Evaluates if an input is interesting using the feedback
|
||||||
@ -292,6 +298,8 @@ pub struct StdFuzzer<CS, F, IF, OF> {
|
|||||||
feedback: F,
|
feedback: F,
|
||||||
objective: OF,
|
objective: OF,
|
||||||
input_filter: IF,
|
input_filter: IF,
|
||||||
|
// Handles whether to share objective testcases among nodes
|
||||||
|
share_objectives: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<CS, F, I, IF, OF, S> HasScheduler<I, S> for StdFuzzer<CS, F, IF, OF>
|
impl<CS, F, I, IF, OF, S> HasScheduler<I, S> for StdFuzzer<CS, F, IF, OF>
|
||||||
@ -331,6 +339,14 @@ impl<CS, F, IF, OF> HasObjective for StdFuzzer<CS, F, IF, OF> {
|
|||||||
fn objective_mut(&mut self) -> &mut OF {
|
fn objective_mut(&mut self) -> &mut OF {
|
||||||
&mut self.objective
|
&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<CS, EM, F, I, IF, OF, OT, S> ExecutionProcessor<EM, I, OT, S> for StdFuzzer<CS, F, IF, OF>
|
impl<CS, EM, F, I, IF, OF, OT, S> ExecutionProcessor<EM, I, OT, S> for StdFuzzer<CS, F, IF, OF>
|
||||||
@ -480,14 +496,11 @@ where
|
|||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if exec_res.is_solution() {
|
if exec_res.is_solution() {
|
||||||
manager.fire(
|
manager.fire(
|
||||||
state,
|
state,
|
||||||
Event::Objective {
|
Event::Objective {
|
||||||
#[cfg(feature = "share_objectives")]
|
input: self.share_objectives.then_some(input.clone()),
|
||||||
input: input.clone(),
|
|
||||||
|
|
||||||
objective_size: state.solutions().count(),
|
objective_size: state.solutions().count(),
|
||||||
time: current_time(),
|
time: current_time(),
|
||||||
},
|
},
|
||||||
@ -677,9 +690,7 @@ where
|
|||||||
manager.fire(
|
manager.fire(
|
||||||
state,
|
state,
|
||||||
Event::Objective {
|
Event::Objective {
|
||||||
#[cfg(feature = "share_objectives")]
|
input: self.share_objectives.then_some(input.clone()),
|
||||||
input: input.clone(),
|
|
||||||
|
|
||||||
objective_size: state.solutions().count(),
|
objective_size: state.solutions().count(),
|
||||||
time: current_time(),
|
time: current_time(),
|
||||||
},
|
},
|
||||||
@ -802,10 +813,16 @@ where
|
|||||||
)?;
|
)?;
|
||||||
res.1
|
res.1
|
||||||
}
|
}
|
||||||
#[cfg(feature = "share_objectives")]
|
Event::Objective {
|
||||||
Event::Objective { ref input, .. } => {
|
input: Some(ref unwrapped_input),
|
||||||
|
..
|
||||||
|
} => {
|
||||||
let res = self.evaluate_input_with_observers(
|
let res = self.evaluate_input_with_observers(
|
||||||
state, executor, manager, input, false,
|
state,
|
||||||
|
executor,
|
||||||
|
manager,
|
||||||
|
unwrapped_input,
|
||||||
|
false,
|
||||||
)?;
|
)?;
|
||||||
res.1
|
res.1
|
||||||
}
|
}
|
||||||
@ -966,6 +983,7 @@ impl<CS, F, IF, OF> StdFuzzer<CS, F, IF, OF> {
|
|||||||
feedback,
|
feedback,
|
||||||
objective,
|
objective,
|
||||||
input_filter,
|
input_filter,
|
||||||
|
share_objectives: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ use crate::{
|
|||||||
corpus::{Corpus, CorpusId, HasCurrentCorpusId},
|
corpus::{Corpus, CorpusId, HasCurrentCorpusId},
|
||||||
events::{Event, EventConfig, EventFirer, llmp::LlmpEventConverter},
|
events::{Event, EventConfig, EventFirer, llmp::LlmpEventConverter},
|
||||||
executors::{Executor, ExitKind, HasObservers},
|
executors::{Executor, ExitKind, HasObservers},
|
||||||
fuzzer::{Evaluator, EvaluatorObservers, ExecutionProcessor},
|
fuzzer::{Evaluator, EvaluatorObservers, ExecutionProcessor, HasObjective},
|
||||||
inputs::{Input, InputConverter},
|
inputs::{Input, InputConverter},
|
||||||
stages::{Restartable, RetryCountRestartHelper, Stage},
|
stages::{Restartable, RetryCountRestartHelper, Stage},
|
||||||
state::{
|
state::{
|
||||||
@ -248,7 +248,7 @@ where
|
|||||||
+ MaybeHasClientPerfMonitor,
|
+ MaybeHasClientPerfMonitor,
|
||||||
SHM: ShMem,
|
SHM: ShMem,
|
||||||
SP: ShMemProvider<ShMem = SHM>,
|
SP: ShMemProvider<ShMem = SHM>,
|
||||||
Z: EvaluatorObservers<E, EM, I, S> + ExecutionProcessor<EM, I, E::Observers, S>,
|
Z: EvaluatorObservers<E, EM, I, S> + ExecutionProcessor<EM, I, E::Observers, S> + HasObjective,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn perform(
|
fn perform(
|
||||||
|
@ -218,7 +218,13 @@ impl DrCovModuleEntry {
|
|||||||
pub fn to_module_line(&self) -> String {
|
pub fn to_module_line(&self) -> String {
|
||||||
format!(
|
format!(
|
||||||
"{:03}, 0x{:x}, 0x{:x}, 0x{:x}, 0x{:x}, 0x{:x}, {}",
|
"{: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()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user