No Uses* for Feedbacks (#2578)

* add from addison's change

* fixing

* one left

* adding

* 444444

* okoko

* no prelude

* i hate rust

* stuff

* no std/win

* getting closer

* a

* a

* aa

* a

* a

* libafl_fuzz

* toml

* tutorial

* libafl_libfuzzer
This commit is contained in:
Dongjia "toka" Zhang 2024-10-02 14:07:08 +02:00 committed by GitHub
parent a212d66afe
commit cbce7ffdfd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
42 changed files with 1029 additions and 1638 deletions

View File

@ -2,12 +2,10 @@ use std::borrow::Cow;
use libafl::{ use libafl::{
corpus::{Corpus, Testcase}, corpus::{Corpus, Testcase},
events::EventFirer,
executors::ExitKind, executors::ExitKind,
feedbacks::{Feedback, MapIndexesMetadata}, feedbacks::{Feedback, MapIndexesMetadata, StateInitializer},
observers::ObserversTuple,
schedulers::{MinimizerScheduler, TestcaseScore}, schedulers::{MinimizerScheduler, TestcaseScore},
state::{HasCorpus, State}, state::HasCorpus,
Error, HasMetadata, Error, HasMetadata,
}; };
use libafl_bolts::{Named, SerdeAny}; use libafl_bolts::{Named, SerdeAny};
@ -45,29 +43,24 @@ pub struct PacketLenFeedback {
len: u64, len: u64,
} }
impl<S> Feedback<S> for PacketLenFeedback impl<S> StateInitializer<S> for PacketLenFeedback {}
where
S: State<Input = PacketData>, impl<EM, OT, S> Feedback<EM, PacketData, OT, S> for PacketLenFeedback {
{
#[inline] #[inline]
fn is_interesting<EM, OT>( fn is_interesting(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
_manager: &mut EM, _manager: &mut EM,
input: &PacketData, input: &PacketData,
_observers: &OT, _observers: &OT,
_exit_kind: &ExitKind, _exit_kind: &ExitKind,
) -> Result<bool, Error> ) -> Result<bool, Error> {
where
EM: EventFirer<State = S>,
OT: ObserversTuple<PacketData, S>,
{
self.len = input.length; self.len = input.length;
Ok(false) Ok(false)
} }
#[inline] #[inline]
fn append_metadata<EM, OT>( fn append_metadata(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
_manager: &mut EM, _manager: &mut EM,

View File

@ -1,18 +1,13 @@
use std::{ use std::{
borrow::Cow, borrow::Cow,
fmt::{Debug, Formatter},
marker::PhantomData,
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
use libafl::{ use libafl::{
corpus::Testcase, corpus::{Corpus, Testcase},
events::EventFirer,
executors::ExitKind, executors::ExitKind,
feedbacks::{Feedback, FeedbackFactory}, feedbacks::{Feedback, FeedbackFactory, StateInitializer},
inputs::Input, state::HasCorpus,
observers::ObserversTuple,
state::State,
}; };
use libafl_bolts::{Error, Named}; use libafl_bolts::{Error, Named};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -22,108 +17,68 @@ use serde::{Deserialize, Serialize};
/// Note: If used as part of the `Objective` chain, then it will only apply to testcases which are /// Note: If used as part of the `Objective` chain, then it will only apply to testcases which are
/// `Objectives`, vice versa for `Feedback`. /// `Objectives`, vice versa for `Feedback`.
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct CustomFilepathToTestcaseFeedback<F, I, S> pub struct CustomFilepathToTestcaseFeedback<F> {
where
I: Input,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>, &Path) -> Result<(), Error>,
{
/// Closure that returns the filename. /// Closure that returns the filename.
func: F, func: F,
/// The root output directory /// The root output directory
out_dir: PathBuf, out_dir: PathBuf,
phantomm: PhantomData<(I, S)>,
} }
impl<F, I, S> CustomFilepathToTestcaseFeedback<F, I, S> impl<F> CustomFilepathToTestcaseFeedback<F> {
where
I: Input,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>, &Path) -> Result<(), Error>,
{
/// Create a new [`CustomFilepathToTestcaseFeedback`]. /// Create a new [`CustomFilepathToTestcaseFeedback`].
pub fn new(func: F, out_dir: PathBuf) -> Self { pub fn new(func: F, out_dir: PathBuf) -> Self {
Self { Self { func, out_dir }
func,
out_dir,
phantomm: PhantomData,
}
} }
} }
impl<F, I, S, T> FeedbackFactory<CustomFilepathToTestcaseFeedback<F, I, S>, T> impl<F, T> FeedbackFactory<CustomFilepathToTestcaseFeedback<F>, T>
for CustomFilepathToTestcaseFeedback<F, I, S> for CustomFilepathToTestcaseFeedback<F>
where where
I: Input, F: Clone,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>, &Path) -> Result<(), Error> + Clone,
{ {
fn create_feedback(&self, _ctx: &T) -> CustomFilepathToTestcaseFeedback<F, I, S> { fn create_feedback(&self, _ctx: &T) -> CustomFilepathToTestcaseFeedback<F> {
Self { Self {
func: self.func.clone(), func: self.func.clone(),
phantomm: self.phantomm,
out_dir: self.out_dir.clone(), out_dir: self.out_dir.clone(),
} }
} }
} }
impl<F, I, S> Named for CustomFilepathToTestcaseFeedback<F, I, S> impl<F> Named for CustomFilepathToTestcaseFeedback<F> {
where
I: Input,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>, &Path) -> Result<(), Error>,
{
fn name(&self) -> &Cow<'static, str> { fn name(&self) -> &Cow<'static, str> {
static NAME: Cow<'static, str> = Cow::Borrowed("CustomFilepathToTestcaseFeedback"); static NAME: Cow<'static, str> = Cow::Borrowed("CustomFilepathToTestcaseFeedback");
&NAME &NAME
} }
} }
impl<F, I, S> Debug for CustomFilepathToTestcaseFeedback<F, I, S> impl<F, S> StateInitializer<S> for CustomFilepathToTestcaseFeedback<F> {}
where
I: Input,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>, &Path) -> Result<(), Error>,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("CustomFilepathToTestcaseFeedback")
.finish_non_exhaustive()
}
}
impl<F, I, S> Feedback<S> for CustomFilepathToTestcaseFeedback<F, I, S> impl<F, EM, OT, S> Feedback<EM, <S::Corpus as Corpus>::Input, OT, S>
for CustomFilepathToTestcaseFeedback<F>
where where
S: State<Input = I>, S: HasCorpus,
F: FnMut(&mut S, &mut Testcase<S::Input>, &Path) -> Result<(), Error>, F: FnMut(&mut S, &mut Testcase<<S::Corpus as Corpus>::Input>, &Path) -> Result<(), Error>,
I: Input,
{ {
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
#[inline] #[inline]
fn is_interesting<EM, OT>( fn is_interesting(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_input: &I, _input: &<S::Corpus as Corpus>::Input,
_observers: &OT, _observers: &OT,
_exit_kind: &ExitKind, _exit_kind: &ExitKind,
) -> Result<bool, Error> ) -> Result<bool, Error> {
where
EM: EventFirer<State = S>,
{
Ok(false) Ok(false)
} }
fn append_metadata<EM, OT>( fn append_metadata(
&mut self, &mut self,
state: &mut S, state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_observers: &OT, _observers: &OT,
testcase: &mut Testcase<S::Input>, testcase: &mut Testcase<<S::Corpus as Corpus>::Input>,
) -> Result<(), Error> ) -> Result<(), Error> {
where
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
(self.func)(state, testcase, &self.out_dir)?; (self.func)(state, testcase, &self.out_dir)?;
Ok(()) Ok(())
} }

View File

@ -1,18 +1,12 @@
use std::{ use std::{borrow::Cow, collections::VecDeque};
borrow::Cow,
collections::VecDeque,
fmt::{Debug, Formatter},
marker::PhantomData,
};
use libafl::{ use libafl::{
corpus::{Corpus, Testcase}, corpus::{Corpus, Testcase},
events::EventFirer,
executors::ExitKind, executors::ExitKind,
feedbacks::{Feedback, FeedbackFactory}, feedbacks::{Feedback, FeedbackFactory},
inputs::Input, inputs::Input,
observers::ObserversTuple, prelude::StateInitializer,
state::{HasCorpus, State}, state::HasCorpus,
}; };
use libafl_bolts::{Error, Named}; use libafl_bolts::{Error, Named};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -20,85 +14,59 @@ use serde::{Deserialize, Serialize};
/// A [`PersitentRecordFeedback`] tracks the last N inputs that the fuzzer has run. /// A [`PersitentRecordFeedback`] tracks the last N inputs that the fuzzer has run.
/// TODO: Kept in memory for now but should write to disk. /// TODO: Kept in memory for now but should write to disk.
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct PersitentRecordFeedback<I, S> pub struct PersitentRecordFeedback<I> {
where
S: State<Input = I>,
{
/// Vec that tracks the last `record_size` [`Input`] /// Vec that tracks the last `record_size` [`Input`]
record: VecDeque<I>, record: VecDeque<I>,
record_size: usize, record_size: usize,
phantomm: PhantomData<(I, S)>,
} }
impl<I, S> PersitentRecordFeedback<I, S> impl<I> PersitentRecordFeedback<I> {
where
I: Input,
S: State<Input = I>,
{
/// Create a new [`PersitentRecordFeedback`]. /// Create a new [`PersitentRecordFeedback`].
pub fn new(record_size: usize) -> Self { pub fn new(record_size: usize) -> Self {
Self { Self {
record_size, record_size,
record: VecDeque::default(), record: VecDeque::default(),
phantomm: PhantomData,
} }
} }
} }
impl<I, S, T> FeedbackFactory<PersitentRecordFeedback<I, S>, T> for PersitentRecordFeedback<I, S> impl<I, T> FeedbackFactory<PersitentRecordFeedback<I>, T> for PersitentRecordFeedback<I>
where where
I: Input, I: Clone,
S: State<Input = I>,
{ {
fn create_feedback(&self, _ctx: &T) -> PersitentRecordFeedback<I, S> { fn create_feedback(&self, _ctx: &T) -> PersitentRecordFeedback<I> {
Self { Self {
record_size: self.record_size, record_size: self.record_size,
record: self.record.clone(), record: self.record.clone(),
phantomm: self.phantomm,
} }
} }
} }
impl<I, S> Named for PersitentRecordFeedback<I, S> impl<I> Named for PersitentRecordFeedback<I> {
where
I: Input,
S: State<Input = I>,
{
fn name(&self) -> &Cow<'static, str> { fn name(&self) -> &Cow<'static, str> {
static NAME: Cow<'static, str> = Cow::Borrowed("PersitentRecordFeedback"); static NAME: Cow<'static, str> = Cow::Borrowed("PersitentRecordFeedback");
&NAME &NAME
} }
} }
impl<I, S> Debug for PersitentRecordFeedback<I, S> impl<I, S> StateInitializer<S> for PersitentRecordFeedback<I> {}
where
I: Input,
S: State<Input = I>,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("PersitentRecordFeedback")
.finish_non_exhaustive()
}
}
impl<I, S> Feedback<S> for PersitentRecordFeedback<I, S> impl<EM, I, OT, S> Feedback<EM, I, OT, S> for PersitentRecordFeedback<I>
where where
S: State<Input = I> + HasCorpus, S: HasCorpus,
S::Corpus: Corpus<Input = I>,
I: Input, I: Input,
{ {
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
#[inline] #[inline]
fn is_interesting<EM, OT>( fn is_interesting(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
_manager: &mut EM, _manager: &mut EM,
input: &I, input: &I,
_observers: &OT, _observers: &OT,
_exit_kind: &ExitKind, _exit_kind: &ExitKind,
) -> Result<bool, Error> ) -> Result<bool, Error> {
where
EM: EventFirer<State = S>,
{
if self.should_run() { if self.should_run() {
self.record.push_back(input.clone()); self.record.push_back(input.clone());
if self.record.len() == self.record_size { if self.record.len() == self.record_size {
@ -108,17 +76,13 @@ where
Ok(false) Ok(false)
} }
fn append_metadata<EM, OT>( fn append_metadata(
&mut self, &mut self,
state: &mut S, state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_observers: &OT, _observers: &OT,
testcase: &mut Testcase<S::Input>, testcase: &mut Testcase<I>,
) -> Result<(), Error> ) -> Result<(), Error> {
where
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
if self.should_run() { if self.should_run() {
let file_path = testcase let file_path = testcase
.file_path() .file_path()
@ -150,11 +114,7 @@ where
} }
} }
impl<I, S> PersitentRecordFeedback<I, S> impl<I> PersitentRecordFeedback<I> {
where
I: Input,
S: State<Input = I>,
{
fn should_run(&self) -> bool { fn should_run(&self) -> bool {
self.record_size > 0 self.record_size > 0
} }

View File

@ -1,8 +1,7 @@
use std::{borrow::Cow, marker::PhantomData}; use std::{borrow::Cow, marker::PhantomData};
use libafl::{ use libafl::{
corpus::Testcase, events::EventFirer, executors::ExitKind, feedbacks::Feedback, corpus::Testcase, executors::ExitKind, feedbacks::Feedback, prelude::StateInitializer, Error,
observers::ObserversTuple, state::State, Error,
}; };
use libafl_bolts::Named; use libafl_bolts::Named;
@ -13,57 +12,50 @@ use crate::Opt;
/// then, essentially becomes benign /// then, essentially becomes benign
#[allow(clippy::module_name_repetitions, clippy::struct_excessive_bools)] #[allow(clippy::module_name_repetitions, clippy::struct_excessive_bools)]
#[derive(Debug)] #[derive(Debug)]
pub struct SeedFeedback<A, S> pub struct SeedFeedback<A, S> {
where
A: Feedback<S>,
S: State,
{
/// Inner [`Feedback`] /// Inner [`Feedback`]
pub inner: A, pub inner: A,
ignore_timeouts: bool, ignore_timeouts: bool,
ignore_seed_issues: bool, ignore_seed_issues: bool,
exit_on_seed_issues: bool, exit_on_seed_issues: bool,
phantom: PhantomData<S>,
done_loading_seeds: bool, done_loading_seeds: bool,
phantom: PhantomData<S>,
} }
impl<A, S> SeedFeedback<A, S> impl<A, S> SeedFeedback<A, S> {
where
A: Feedback<S>,
S: State,
{
pub fn new(inner: A, opt: &Opt) -> Self { pub fn new(inner: A, opt: &Opt) -> Self {
Self { Self {
inner, inner,
ignore_timeouts: opt.ignore_timeouts, ignore_timeouts: opt.ignore_timeouts,
ignore_seed_issues: opt.ignore_seed_issues, ignore_seed_issues: opt.ignore_seed_issues,
exit_on_seed_issues: opt.exit_on_seed_issues, exit_on_seed_issues: opt.exit_on_seed_issues,
phantom: PhantomData,
done_loading_seeds: false, done_loading_seeds: false,
phantom: PhantomData,
} }
} }
} }
impl<A, S> Feedback<S> for SeedFeedback<A, S> impl<A, S> StateInitializer<S> for SeedFeedback<A, S>
where where
A: Feedback<S>, A: StateInitializer<S>,
S: State,
{ {
fn init_state(&mut self, state: &mut S) -> Result<(), Error> { fn init_state(&mut self, state: &mut S) -> Result<(), Error> {
self.inner.init_state(state)?; self.inner.init_state(state)?;
Ok(()) Ok(())
} }
fn is_interesting<EM, OT>( }
impl<A, EM, I, OT, S> Feedback<EM, I, OT, S> for SeedFeedback<A, S>
where
A: Feedback<EM, I, OT, S>,
{
fn is_interesting(
&mut self, &mut self,
state: &mut S, state: &mut S,
manager: &mut EM, manager: &mut EM,
input: &S::Input, input: &I,
observers: &OT, observers: &OT,
exit_kind: &ExitKind, exit_kind: &ExitKind,
) -> Result<bool, Error> ) -> Result<bool, Error> {
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S::Input, S>,
{
if !self.done_loading_seeds { if !self.done_loading_seeds {
match exit_kind { match exit_kind {
ExitKind::Timeout => { ExitKind::Timeout => {
@ -93,17 +85,13 @@ where
} }
/// Append to the testcase the generated metadata in case of a new corpus item /// Append to the testcase the generated metadata in case of a new corpus item
#[inline] #[inline]
fn append_metadata<EM, OT>( fn append_metadata(
&mut self, &mut self,
state: &mut S, state: &mut S,
manager: &mut EM, manager: &mut EM,
observers: &OT, observers: &OT,
testcase: &mut Testcase<S::Input>, testcase: &mut Testcase<I>,
) -> Result<(), Error> ) -> Result<(), Error> {
where
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
self.inner self.inner
.append_metadata(state, manager, observers, testcase)?; .append_metadata(state, manager, observers, testcase)?;
Ok(()) Ok(())
@ -111,7 +99,7 @@ where
/// Discard the stored metadata in case that the testcase is not added to the corpus /// Discard the stored metadata in case that the testcase is not added to the corpus
#[inline] #[inline]
fn discard_metadata(&mut self, state: &mut S, input: &S::Input) -> Result<(), Error> { fn discard_metadata(&mut self, state: &mut S, input: &I) -> Result<(), Error> {
self.inner.discard_metadata(state, input)?; self.inner.discard_metadata(state, input)?;
Ok(()) Ok(())
} }
@ -128,11 +116,7 @@ where
} }
} }
impl<S, A> Named for SeedFeedback<A, S> impl<A, S> Named for SeedFeedback<A, S> {
where
A: Feedback<S>,
S: State,
{
#[inline] #[inline]
fn name(&self) -> &Cow<'static, str> { fn name(&self) -> &Cow<'static, str> {
static NAME: Cow<'static, str> = Cow::Borrowed("SeedFeedback"); static NAME: Cow<'static, str> = Cow::Borrowed("SeedFeedback");
@ -140,11 +124,7 @@ where
} }
} }
impl<S, A> SeedFeedback<A, S> impl<A, S> SeedFeedback<A, S> {
where
A: Feedback<S>,
S: State,
{
pub fn done_loading_seeds(&mut self) { pub fn done_loading_seeds(&mut self) {
self.done_loading_seeds = true; self.done_loading_seeds = true;
} }

View File

@ -8,8 +8,8 @@ use std::{
use libafl::{ use libafl::{
corpus::{CachedOnDiskCorpus, Corpus, OnDiskCorpus}, corpus::{CachedOnDiskCorpus, Corpus, OnDiskCorpus},
events::{ events::{
CentralizedEventManager, EventManagerHooksTuple, EventProcessor, CentralizedEventManager, EventManagerHooksTuple, LlmpRestartingEventManager,
LlmpRestartingEventManager, ProgressReporter, ProgressReporter,
}, },
executors::forkserver::{ForkserverExecutor, ForkserverExecutorBuilder}, executors::forkserver::{ForkserverExecutor, ForkserverExecutorBuilder},
feedback_and, feedback_or, feedback_or_fast, feedback_and, feedback_or, feedback_or_fast,
@ -530,7 +530,7 @@ pub fn run_fuzzer_with_stages<Z, ST, E, EM>(
where where
Z: Fuzzer<E, EM, ST>, Z: Fuzzer<E, EM, ST>,
E: UsesState<State = Z::State>, E: UsesState<State = Z::State>,
EM: ProgressReporter<State = Z::State> + EventProcessor<E, Z>, EM: ProgressReporter<State = Z::State>,
ST: StagesTuple<E, EM, Z::State, Z>, ST: StagesTuple<E, EM, Z::State, Z>,
<Z as UsesState>::State: HasLastReportTime + HasExecutions + HasMetadata, <Z as UsesState>::State: HasLastReportTime + HasExecutions + HasMetadata,
{ {

View File

@ -377,8 +377,8 @@ where
S: State, S: State,
Self::State: HasExecutions + HasMetadata, Self::State: HasExecutions + HasMetadata,
SP: ShMemProvider, SP: ShMemProvider,
Z: EvaluatorObservers<E::Observers, State = Self::State> Z: EvaluatorObservers<Self, E::Observers, State = Self::State>
+ ExecutionProcessor<State = Self::State>, + ExecutionProcessor<Self, E::Observers, State = Self::State>,
{ {
fn process( fn process(
&mut self, &mut self,
@ -413,8 +413,8 @@ where
EMH: EventManagerHooksTuple<EM::State>, EMH: EventManagerHooksTuple<EM::State>,
S: State, S: State,
SP: ShMemProvider, SP: ShMemProvider,
Z: EvaluatorObservers<E::Observers, State = Self::State> Z: EvaluatorObservers<Self, E::Observers, State = Self::State>
+ ExecutionProcessor<State = Self::State>, + ExecutionProcessor<Self, E::Observers, State = Self::State>,
{ {
} }
@ -535,8 +535,8 @@ where
ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State> + Serialize, ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State> + Serialize,
<Self as UsesState>::State: UsesInput + HasExecutions + HasMetadata, <Self as UsesState>::State: UsesInput + HasExecutions + HasMetadata,
for<'a> E::Observers: Deserialize<'a>, for<'a> E::Observers: Deserialize<'a>,
Z: ExecutionProcessor<State = <Self as UsesState>::State> Z: ExecutionProcessor<Self, E::Observers, State = <Self as UsesState>::State>
+ EvaluatorObservers<E::Observers>, + EvaluatorObservers<Self, E::Observers>,
{ {
// TODO: Get around local event copy by moving handle_in_client // TODO: Get around local event copy by moving handle_in_client
let self_id = self.client.sender().id(); let self_id = self.client.sender().id();
@ -585,8 +585,8 @@ where
ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State> + Serialize, ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State> + Serialize,
<Self as UsesState>::State: UsesInput + HasExecutions + HasMetadata, <Self as UsesState>::State: UsesInput + HasExecutions + HasMetadata,
for<'a> E::Observers: Deserialize<'a> + Serialize, for<'a> E::Observers: Deserialize<'a> + Serialize,
Z: ExecutionProcessor<State = <Self as UsesState>::State> Z: ExecutionProcessor<Self, E::Observers, State = <Self as UsesState>::State>
+ EvaluatorObservers<E::Observers>, + EvaluatorObservers<Self, E::Observers>,
{ {
log::debug!("handle_in_main!"); log::debug!("handle_in_main!");
@ -641,7 +641,7 @@ where
process::id(), process::id(),
event_name event_name
); );
fuzzer.evaluate_input_with_observers::<E, Self>( fuzzer.evaluate_input_with_observers::<E>(
state, state,
executor, executor,
self, self,

View File

@ -406,7 +406,9 @@ where
E: Executor<Self, Z, State = S> + HasObservers, E: Executor<Self, Z, State = S> + HasObservers,
E::Observers: ObserversTuple<S::Input, S> + Serialize, E::Observers: ObserversTuple<S::Input, S> + Serialize,
for<'a> E::Observers: Deserialize<'a>, for<'a> E::Observers: Deserialize<'a>,
Z: ExecutionProcessor<State = S> + EvaluatorObservers<E::Observers> + Evaluator<E, Self>, Z: ExecutionProcessor<Self, E::Observers, State = S>
+ EvaluatorObservers<Self, E::Observers>
+ Evaluator<E, Self>,
{ {
if !self.hooks.pre_exec_all(state, client_id, &event)? { if !self.hooks.pre_exec_all(state, client_id, &event)? {
return Ok(()); return Ok(());
@ -449,7 +451,7 @@ where
{ {
state.scalability_monitor_mut().testcase_without_observers += 1; state.scalability_monitor_mut().testcase_without_observers += 1;
} }
fuzzer.evaluate_input_with_observers::<E, Self>( fuzzer.evaluate_input_with_observers::<E>(
state, executor, self, input, false, state, executor, self, input, false,
)? )?
}; };
@ -590,7 +592,9 @@ where
E: HasObservers + Executor<Self, Z, State = S>, E: HasObservers + Executor<Self, Z, State = S>,
E::Observers: ObserversTuple<S::Input, S> + Serialize, E::Observers: ObserversTuple<S::Input, S> + Serialize,
for<'a> E::Observers: Deserialize<'a>, for<'a> E::Observers: Deserialize<'a>,
Z: ExecutionProcessor<State = S> + EvaluatorObservers<E::Observers> + Evaluator<E, Self>, Z: ExecutionProcessor<Self, E::Observers, State = S>
+ EvaluatorObservers<Self, E::Observers>
+ Evaluator<E, Self>,
{ {
fn process( fn process(
&mut self, &mut self,
@ -642,7 +646,9 @@ where
EMH: EventManagerHooksTuple<S>, EMH: EventManagerHooksTuple<S>,
S: State + HasExecutions + HasMetadata + HasLastReportTime + HasImported, S: State + HasExecutions + HasMetadata + HasLastReportTime + HasImported,
SP: ShMemProvider, SP: ShMemProvider,
Z: ExecutionProcessor<State = S> + EvaluatorObservers<E::Observers> + Evaluator<E, Self>, Z: ExecutionProcessor<Self, E::Observers, State = S>
+ EvaluatorObservers<Self, E::Observers>
+ Evaluator<E, Self>,
{ {
} }

View File

@ -296,7 +296,7 @@ where
E: Executor<EM, Z, State = S> + HasObservers, E: Executor<EM, Z, State = S> + HasObservers,
EM: UsesState<State = S> + EventFirer, EM: UsesState<State = S> + EventFirer,
for<'a> E::Observers: Deserialize<'a>, for<'a> E::Observers: Deserialize<'a>,
Z: ExecutionProcessor<State = S> + EvaluatorObservers<E::Observers>, Z: ExecutionProcessor<EM, E::Observers, State = S> + EvaluatorObservers<EM, E::Observers>,
{ {
match event { match event {
Event::NewTestcase { Event::NewTestcase {
@ -308,7 +308,7 @@ where
return Ok(()); return Ok(());
}; };
let res = fuzzer.evaluate_input_with_observers::<E, EM>( let res = fuzzer.evaluate_input_with_observers::<E>(
state, state,
executor, executor,
manager, manager,
@ -350,7 +350,7 @@ where
E: Executor<EM, Z, State = S> + HasObservers, E: Executor<EM, Z, State = S> + HasObservers,
EM: UsesState<State = S> + EventFirer, EM: UsesState<State = S> + EventFirer,
for<'a> E::Observers: Deserialize<'a>, for<'a> E::Observers: Deserialize<'a>,
Z: ExecutionProcessor<State = S> + EvaluatorObservers<E::Observers>, Z: ExecutionProcessor<EM, E::Observers, State = S> + EvaluatorObservers<EM, E::Observers>,
{ {
// TODO: Get around local event copy by moving handle_in_client // TODO: Get around local event copy by moving handle_in_client
let self_id = self.llmp.sender().id(); let self_id = self.llmp.sender().id();

View File

@ -210,8 +210,8 @@ where
EMH: EventManagerHooksTuple<S>, EMH: EventManagerHooksTuple<S>,
S: State + HasExecutions + HasMetadata + HasImported, S: State + HasExecutions + HasMetadata + HasImported,
SP: ShMemProvider, SP: ShMemProvider,
Z: ExecutionProcessor<State = S> Z: ExecutionProcessor<LlmpEventManager<EMH, S, SP>, E::Observers, State = S>
+ EvaluatorObservers<E::Observers> + EvaluatorObservers<LlmpEventManager<EMH, S, SP>, E::Observers>
+ Evaluator<E, LlmpEventManager<EMH, S, SP>>, + Evaluator<E, LlmpEventManager<EMH, S, SP>>,
{ {
fn process(&mut self, fuzzer: &mut Z, state: &mut S, executor: &mut E) -> Result<usize, Error> { fn process(&mut self, fuzzer: &mut Z, state: &mut S, executor: &mut E) -> Result<usize, Error> {
@ -234,8 +234,8 @@ where
EMH: EventManagerHooksTuple<S>, EMH: EventManagerHooksTuple<S>,
S: State + HasExecutions + HasMetadata + HasLastReportTime + HasImported, S: State + HasExecutions + HasMetadata + HasLastReportTime + HasImported,
SP: ShMemProvider, SP: ShMemProvider,
Z: ExecutionProcessor<State = S> Z: ExecutionProcessor<LlmpEventManager<EMH, S, SP>, E::Observers, State = S>
+ EvaluatorObservers<E::Observers> + EvaluatorObservers<LlmpEventManager<EMH, S, SP>, E::Observers>
+ Evaluator<E, LlmpEventManager<EMH, S, SP>>, + Evaluator<E, LlmpEventManager<EMH, S, SP>>,
{ {
} }

View File

@ -614,7 +614,8 @@ where
E: Executor<Self, Z, State = S> + HasObservers, E: Executor<Self, Z, State = S> + HasObservers,
E::Observers: Serialize + ObserversTuple<S::Input, S>, E::Observers: Serialize + ObserversTuple<S::Input, S>,
for<'a> E::Observers: Deserialize<'a>, for<'a> E::Observers: Deserialize<'a>,
Z: ExecutionProcessor<State = S> + EvaluatorObservers<E::Observers>, Z: ExecutionProcessor<Self, E::Observers, State = S>
+ EvaluatorObservers<Self, E::Observers>,
{ {
if !self.hooks.pre_exec_all(state, client_id, &event)? { if !self.hooks.pre_exec_all(state, client_id, &event)? {
return Ok(()); return Ok(());
@ -645,9 +646,8 @@ where
{ {
state.scalability_monitor_mut().testcase_without_observers += 1; state.scalability_monitor_mut().testcase_without_observers += 1;
} }
fuzzer.evaluate_input_with_observers::<E, Self>( fuzzer
state, executor, self, input, false, .evaluate_input_with_observers::<E>(state, executor, self, input, false)?
)?
}; };
if let Some(item) = _res.1 { if let Some(item) = _res.1 {
*state.imported_mut() += 1; *state.imported_mut() += 1;
@ -756,7 +756,8 @@ where
for<'a> E::Observers: Deserialize<'a>, for<'a> E::Observers: Deserialize<'a>,
EMH: EventManagerHooksTuple<S>, EMH: EventManagerHooksTuple<S>,
S: State + HasExecutions + HasMetadata + HasImported, S: State + HasExecutions + HasMetadata + HasImported,
Z: EvaluatorObservers<E::Observers, State = S> + ExecutionProcessor<State = S>, Z: EvaluatorObservers<Self, E::Observers, State = S>
+ ExecutionProcessor<Self, E::Observers, State = S>,
{ {
fn process( fn process(
&mut self, &mut self,
@ -830,7 +831,8 @@ where
for<'a> E::Observers: Deserialize<'a>, for<'a> E::Observers: Deserialize<'a>,
EMH: EventManagerHooksTuple<S>, EMH: EventManagerHooksTuple<S>,
S: State + HasExecutions + HasMetadata + HasLastReportTime + HasImported, S: State + HasExecutions + HasMetadata + HasLastReportTime + HasImported,
Z: EvaluatorObservers<E::Observers, State = S> + ExecutionProcessor<State = S>, Z: EvaluatorObservers<Self, E::Observers, State = S>
+ ExecutionProcessor<Self, E::Observers, State = S>,
{ {
} }
@ -976,7 +978,8 @@ where
EMH: EventManagerHooksTuple<S>, EMH: EventManagerHooksTuple<S>,
S: State + HasExecutions + HasMetadata + HasImported, S: State + HasExecutions + HasMetadata + HasImported,
SP: ShMemProvider + 'static, SP: ShMemProvider + 'static,
Z: EvaluatorObservers<E::Observers, State = S> + ExecutionProcessor, //CE: CustomEvent<I>, Z: EvaluatorObservers<TcpEventManager<EMH, S>, E::Observers, State = S>
+ ExecutionProcessor<TcpEventManager<EMH, S>, E::Observers>, //CE: CustomEvent<I>,
{ {
fn process(&mut self, fuzzer: &mut Z, state: &mut S, executor: &mut E) -> Result<usize, Error> { fn process(&mut self, fuzzer: &mut Z, state: &mut S, executor: &mut E) -> Result<usize, Error> {
self.tcp_mgr.process(fuzzer, state, executor) self.tcp_mgr.process(fuzzer, state, executor)
@ -996,7 +999,8 @@ where
EMH: EventManagerHooksTuple<S>, EMH: EventManagerHooksTuple<S>,
S: State + HasExecutions + HasMetadata + HasLastReportTime + HasImported, S: State + HasExecutions + HasMetadata + HasLastReportTime + HasImported,
SP: ShMemProvider + 'static, SP: ShMemProvider + 'static,
Z: EvaluatorObservers<E::Observers, State = S> + ExecutionProcessor, //CE: CustomEvent<I>, Z: EvaluatorObservers<TcpEventManager<EMH, S>, E::Observers, State = S>
+ ExecutionProcessor<TcpEventManager<EMH, S>, E::Observers>, //CE: CustomEvent<I>,
{ {
} }

View File

@ -239,7 +239,7 @@ where
E: Executor<EM, Z> + HasObservers + HasInProcessHooks<E::State>, E: Executor<EM, Z> + HasObservers + HasInProcessHooks<E::State>,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>, E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>, EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>, OF: Feedback<EM, E::Input, E::Observers, E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus, E::State: HasExecutions + HasSolutions + HasCorpus,
Z: HasObjective<Objective = OF, State = E::State>, Z: HasObjective<Objective = OF, State = E::State>,
<<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me <<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me
@ -282,7 +282,7 @@ where
E: Executor<EM, Z> + HasObservers + HasInProcessHooks<E::State>, E: Executor<EM, Z> + HasObservers + HasInProcessHooks<E::State>,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>, E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>, EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>, OF: Feedback<EM, E::Input, E::Observers, E::State>,
E::State: State + HasExecutions + HasSolutions + HasCorpus, E::State: State + HasExecutions + HasSolutions + HasCorpus,
Z: HasObjective<Objective = OF, State = E::State>, Z: HasObjective<Objective = OF, State = E::State>,
<<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me <<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me
@ -339,7 +339,7 @@ where
where where
E: Executor<EM, Z> + HasObservers + HasInProcessHooks<E::State>, E: Executor<EM, Z> + HasObservers + HasInProcessHooks<E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>, EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>, OF: Feedback<EM, E::Input, E::Observers, E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus, E::State: HasExecutions + HasSolutions + HasCorpus,
Z: HasObjective<Objective = OF, State = E::State>, Z: HasObjective<Objective = OF, State = E::State>,
{ {

View File

@ -80,7 +80,7 @@ pub mod unix_signal_handler {
E: Executor<EM, Z> + HasObservers, E: Executor<EM, Z> + HasObservers,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>, E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>, EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>, OF: Feedback<EM, E::Input, E::Observers, E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus, E::State: HasExecutions + HasSolutions + HasCorpus,
Z: HasObjective<Objective = OF, State = E::State>, Z: HasObjective<Objective = OF, State = E::State>,
<<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me <<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me
@ -130,7 +130,7 @@ pub mod unix_signal_handler {
E: Executor<EM, Z> + HasInProcessHooks<E::State> + HasObservers, E: Executor<EM, Z> + HasInProcessHooks<E::State> + HasObservers,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>, E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>, EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>, OF: Feedback<EM, E::Input, E::Observers, E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus, E::State: HasExecutions + HasSolutions + HasCorpus,
Z: HasObjective<Objective = OF, State = E::State>, Z: HasObjective<Objective = OF, State = E::State>,
<<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me <<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me
@ -188,7 +188,7 @@ pub mod unix_signal_handler {
E: Executor<EM, Z> + HasObservers, E: Executor<EM, Z> + HasObservers,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>, E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>, EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>, OF: Feedback<EM, E::Input, E::Observers, E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus, E::State: HasExecutions + HasSolutions + HasCorpus,
Z: HasObjective<Objective = OF, State = E::State>, Z: HasObjective<Objective = OF, State = E::State>,
<<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me <<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me

View File

@ -31,7 +31,7 @@ pub mod windows_asan_handler {
where where
E: Executor<EM, Z> + HasObservers, E: Executor<EM, Z> + HasObservers,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>, EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>, OF: Feedback<EM, E::Input, E::Observers, E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus, E::State: HasExecutions + HasSolutions + HasCorpus,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>, E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
Z: HasObjective<Objective = OF, State = E::State>, Z: HasObjective<Objective = OF, State = E::State>,
@ -184,7 +184,7 @@ pub mod windows_exception_handler {
where where
E: HasObservers + Executor<EM, Z>, E: HasObservers + Executor<EM, Z>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>, EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>, OF: Feedback<EM, E::Input, E::Observers, E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus, E::State: HasExecutions + HasSolutions + HasCorpus,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>, E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
Z: HasObjective<Objective = OF, State = E::State>, Z: HasObjective<Objective = OF, State = E::State>,
@ -248,7 +248,7 @@ pub mod windows_exception_handler {
E: HasObservers + HasInProcessHooks<E::State> + Executor<EM, Z>, E: HasObservers + HasInProcessHooks<E::State> + Executor<EM, Z>,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>, E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>, EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>, OF: Feedback<EM, E::Input, E::Observers, E::State>,
E::State: State + HasExecutions + HasSolutions + HasCorpus, E::State: State + HasExecutions + HasSolutions + HasCorpus,
Z: HasObjective<Objective = OF, State = E::State>, Z: HasObjective<Objective = OF, State = E::State>,
<<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me <<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me
@ -321,7 +321,7 @@ pub mod windows_exception_handler {
E: Executor<EM, Z> + HasObservers, E: Executor<EM, Z> + HasObservers,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>, E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>, EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>, OF: Feedback<EM, E::Input, E::Observers, E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus, E::State: HasExecutions + HasSolutions + HasCorpus,
Z: HasObjective<Objective = OF, State = E::State>, Z: HasObjective<Objective = OF, State = E::State>,
<<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me <<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me

View File

@ -170,7 +170,7 @@ where
E: Executor<EM, Z, State = S> + HasObservers + HasInProcessHooks<S>, E: Executor<EM, Z, State = S> + HasObservers + HasInProcessHooks<S>,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>, E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = S> + EventRestarter, EM: EventFirer<State = S> + EventRestarter,
OF: Feedback<S>, OF: Feedback<EM, E::Input, E::Observers, S>,
S: State, S: State,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
<<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me <<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me
@ -200,7 +200,7 @@ where
E: Executor<EM, Z, State = S> + HasObservers + HasInProcessHooks<S>, E: Executor<EM, Z, State = S> + HasObservers + HasInProcessHooks<S>,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>, E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = S> + EventRestarter, EM: EventFirer<State = S> + EventRestarter,
OF: Feedback<S>, OF: Feedback<EM, E::Input, E::Observers, S>,
S: State, S: State,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
<<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me <<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me
@ -233,7 +233,7 @@ where
E: Executor<EM, Z, State = S> + HasObservers + HasInProcessHooks<S>, E: Executor<EM, Z, State = S> + HasObservers + HasInProcessHooks<S>,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>, E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = S> + EventRestarter, EM: EventFirer<State = S> + EventRestarter,
OF: Feedback<S>, OF: Feedback<EM, E::Input, E::Observers, S>,
S: State, S: State,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
<<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me <<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me

View File

@ -173,7 +173,7 @@ where
where where
Self: Executor<EM, Z, State = S> + HasObservers, Self: Executor<EM, Z, State = S> + HasObservers,
EM: EventFirer<State = S> + EventRestarter, EM: EventFirer<State = S> + EventRestarter,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: State, S: State,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
{ {
@ -201,7 +201,7 @@ where
where where
Self: Executor<EM, Z, State = S>, Self: Executor<EM, Z, State = S>,
EM: EventFirer<State = S> + EventRestarter, EM: EventFirer<State = S> + EventRestarter,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: State, S: State,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
<S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me <S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me
@ -242,7 +242,7 @@ where
where where
Self: Executor<EM, Z, State = S>, Self: Executor<EM, Z, State = S>,
EM: EventFirer<State = S> + EventRestarter, EM: EventFirer<State = S> + EventRestarter,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: State, S: State,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
<S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me <S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me
@ -287,7 +287,7 @@ where
where where
Self: Executor<EM, Z, State = S>, Self: Executor<EM, Z, State = S>,
EM: EventFirer<State = S> + EventRestarter, EM: EventFirer<State = S> + EventRestarter,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: State, S: State,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
{ {
@ -316,7 +316,7 @@ where
where where
Self: Executor<EM, Z, State = S>, Self: Executor<EM, Z, State = S>,
EM: EventFirer<State = S> + EventRestarter, EM: EventFirer<State = S> + EventRestarter,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: State, S: State,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
<S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me <S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me
@ -353,7 +353,7 @@ where
where where
Self: Executor<EM, Z, State = S>, Self: Executor<EM, Z, State = S>,
EM: EventFirer<State = S> + EventRestarter, EM: EventFirer<State = S> + EventRestarter,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: State, S: State,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
<S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me <S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me
@ -442,7 +442,7 @@ pub fn run_observers_and_save_state<E, EM, OF, Z>(
E: Executor<EM, Z> + HasObservers, E: Executor<EM, Z> + HasObservers,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>, E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>, EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>, OF: Feedback<EM, E::Input, E::Observers, E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase, E::State: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase,
Z: HasObjective<Objective = OF, State = E::State>, Z: HasObjective<Objective = OF, State = E::State>,
<<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me <<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me
@ -505,11 +505,11 @@ where
E: Executor<EM, Z> + HasObservers, E: Executor<EM, Z> + HasObservers,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>, E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>, EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>, OF: Feedback<EM, E::Input, E::Observers, E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase, E::State: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase,
Z: HasObjective<Objective = OF, State = E::State> Z: HasObjective<Objective = OF, State = E::State>
+ HasScheduler<State = E::State> + HasScheduler<State = E::State>
+ ExecutionProcessor, + ExecutionProcessor<EM, E::Observers>,
<<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me <<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me
{ {
let data = addr_of_mut!(GLOBAL_STATE); let data = addr_of_mut!(GLOBAL_STATE);

View File

@ -163,7 +163,7 @@ where
where where
Self: Executor<EM, Z, State = S>, Self: Executor<EM, Z, State = S>,
EM: EventFirer<State = S> + EventRestarter, EM: EventFirer<State = S> + EventRestarter,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: State, S: State,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
{ {
@ -193,7 +193,7 @@ where
where where
Self: Executor<EM, Z, State = S>, Self: Executor<EM, Z, State = S>,
EM: EventFirer<State = S> + EventRestarter, EM: EventFirer<State = S> + EventRestarter,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: State, S: State,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
<S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me <S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me
@ -236,7 +236,7 @@ where
where where
Self: Executor<EM, Z, State = S>, Self: Executor<EM, Z, State = S>,
EM: EventFirer<State = S> + EventRestarter, EM: EventFirer<State = S> + EventRestarter,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: State, S: State,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
<S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me <S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me
@ -301,7 +301,7 @@ where
) -> Result<Self, Error> ) -> Result<Self, Error>
where where
EM: EventFirer<State = S> + EventRestarter, EM: EventFirer<State = S> + EventRestarter,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: State, S: State,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
{ {
@ -332,7 +332,7 @@ where
) -> Result<Self, Error> ) -> Result<Self, Error>
where where
EM: EventFirer<State = S> + EventRestarter, EM: EventFirer<State = S> + EventRestarter,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: State, S: State,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
<S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me <S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me
@ -371,7 +371,7 @@ where
) -> Result<Self, Error> ) -> Result<Self, Error>
where where
EM: EventFirer<State = S> + EventRestarter, EM: EventFirer<State = S> + EventRestarter,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: State, S: State,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
<S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me <S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me

View File

@ -53,7 +53,7 @@ where
OT: ObserversTuple<S::Input, S>, OT: ObserversTuple<S::Input, S>,
SP: ShMemProvider, SP: ShMemProvider,
EM: EventFirer<State = S> + EventRestarter<State = S>, EM: EventFirer<State = S> + EventRestarter<State = S>,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: HasSolutions, S: HasSolutions,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
{ {
@ -190,7 +190,7 @@ where
OT: ObserversTuple<S::Input, S>, OT: ObserversTuple<S::Input, S>,
SP: ShMemProvider, SP: ShMemProvider,
EM: EventFirer<State = S> + EventRestarter<State = S>, EM: EventFirer<State = S> + EventRestarter<State = S>,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: State + HasSolutions, S: State + HasSolutions,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
{ {

View File

@ -38,7 +38,7 @@ where
OT: ObserversTuple<S::Input, S>, OT: ObserversTuple<S::Input, S>,
SP: ShMemProvider, SP: ShMemProvider,
EM: EventFirer<State = S> + EventRestarter<State = S>, EM: EventFirer<State = S> + EventRestarter<State = S>,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: State + HasSolutions, S: State + HasSolutions,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
{ {
@ -137,7 +137,7 @@ where
HT: ExecutorHooksTuple<S>, HT: ExecutorHooksTuple<S>,
EM: EventFirer<State = S> + EventRestarter<State = S>, EM: EventFirer<State = S> + EventRestarter<State = S>,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
{ {
#[allow(unreachable_code)] #[allow(unreachable_code)]
#[inline] #[inline]
@ -179,7 +179,7 @@ where
SP: ShMemProvider, SP: ShMemProvider,
Z: UsesState<State = S>, Z: UsesState<State = S>,
EM: EventFirer<State = S> + EventRestarter<State = S>, EM: EventFirer<State = S> + EventRestarter<State = S>,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: State + HasSolutions, S: State + HasSolutions,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
{ {

View File

@ -5,21 +5,17 @@
//! to be not interesting. //! to be not interesting.
//! Requires a [`ConcolicObserver`] to observe the concolic trace. //! Requires a [`ConcolicObserver`] to observe the concolic trace.
use alloc::borrow::Cow; use alloc::borrow::Cow;
use core::{fmt::Debug, marker::PhantomData}; use core::fmt::Debug;
use libafl_bolts::{ use libafl_bolts::{
tuples::{Handle, Handled, MatchNameRef}, tuples::{Handle, Handled, MatchName, MatchNameRef},
Named, Named,
}; };
use crate::{ use crate::{
corpus::Testcase, corpus::Testcase,
events::EventFirer, feedbacks::{Feedback, StateInitializer},
executors::ExitKind, observers::concolic::ConcolicObserver,
feedbacks::Feedback,
inputs::UsesInput,
observers::{concolic::ConcolicObserver, ObserversTuple},
state::State,
Error, HasMetadata, Error, HasMetadata,
}; };
@ -29,60 +25,45 @@ use crate::{
/// to be not interesting. /// to be not interesting.
/// Requires a [`ConcolicObserver`] to observe the concolic trace. /// Requires a [`ConcolicObserver`] to observe the concolic trace.
#[derive(Debug)] #[derive(Debug)]
pub struct ConcolicFeedback<'map, S> { pub struct ConcolicFeedback<'map> {
observer_handle: Handle<ConcolicObserver<'map>>, observer_handle: Handle<ConcolicObserver<'map>>,
phantom: PhantomData<S>,
} }
impl<'map, S> ConcolicFeedback<'map, S> { impl<'map> ConcolicFeedback<'map> {
/// Creates a concolic feedback from an observer /// Creates a concolic feedback from an observer
#[allow(unused)] #[allow(unused)]
#[must_use] #[must_use]
pub fn from_observer(observer: &ConcolicObserver<'map>) -> Self { pub fn from_observer(observer: &ConcolicObserver<'map>) -> Self {
Self { Self {
observer_handle: observer.handle(), observer_handle: observer.handle(),
phantom: PhantomData,
} }
} }
} }
impl<S> Named for ConcolicFeedback<'_, S> { impl Named for ConcolicFeedback<'_> {
fn name(&self) -> &Cow<'static, str> { fn name(&self) -> &Cow<'static, str> {
self.observer_handle.name() self.observer_handle.name()
} }
} }
impl<S> Feedback<S> for ConcolicFeedback<'_, S> impl<S> StateInitializer<S> for ConcolicFeedback<'_> {}
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for ConcolicFeedback<'_>
where where
S: State, OT: MatchName,
{ {
#[allow(clippy::wrong_self_convention)] #[cfg(feature = "track_hit_feedbacks")]
fn is_interesting<EM, OT>( fn last_result(&self) -> Result<bool, Error> {
&mut self,
_state: &mut S,
_manager: &mut EM,
_input: &<S as UsesInput>::Input,
_observers: &OT,
_exit_kind: &ExitKind,
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S::Input, S>,
{
Ok(false) Ok(false)
} }
fn append_metadata<EM, OT>( fn append_metadata(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
_manager: &mut EM, _manager: &mut EM,
observers: &OT, observers: &OT,
testcase: &mut Testcase<S::Input>, testcase: &mut Testcase<I>,
) -> Result<(), Error> ) -> Result<(), Error> {
where
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
if let Some(metadata) = observers if let Some(metadata) = observers
.get(&self.observer_handle) .get(&self.observer_handle)
.map(ConcolicObserver::create_metadata_from_current_map) .map(ConcolicObserver::create_metadata_from_current_map)
@ -91,17 +72,4 @@ where
} }
Ok(()) Ok(())
} }
fn discard_metadata(
&mut self,
_state: &mut S,
_input: &<S as UsesInput>::Input,
) -> Result<(), Error> {
Ok(())
}
#[cfg(feature = "track_hit_feedbacks")]
fn last_result(&self) -> Result<bool, Error> {
Ok(false)
}
} }

View File

@ -1,135 +1,97 @@
use alloc::{borrow::Cow, string::String}; use alloc::{borrow::Cow, string::String};
use core::{ use core::fmt::{self, Debug, Formatter};
fmt::{self, Debug, Formatter},
marker::PhantomData,
};
use libafl_bolts::Named; use libafl_bolts::Named;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
corpus::Testcase, corpus::Testcase,
events::EventFirer, feedbacks::{Feedback, FeedbackFactory, StateInitializer},
executors::ExitKind,
feedbacks::{Feedback, FeedbackFactory},
inputs::Input,
observers::ObserversTuple,
state::State,
Error, Error,
}; };
/// A [`CustomFilenameToTestcaseFeedback`] takes a closure which returns a filename for the testcase. /// Type which can generate a custom filename for a given input/state pair
/// pub trait CustomFilenameGenerator<I, S> {
/// Sets the name of the provided [`Testcase`] based on the state and input
fn set_name(&mut self, state: &mut S, testcase: &mut Testcase<I>) -> Result<String, Error>;
}
// maintain compatibility with old impls
impl<I, F, S> CustomFilenameGenerator<I, S> for F
where
F: FnMut(&mut S, &mut Testcase<I>) -> Result<String, Error>,
{
fn set_name(&mut self, state: &mut S, testcase: &mut Testcase<I>) -> Result<String, Error> {
self(state, testcase)
}
}
/// A [`CustomFilenameToTestcaseFeedback`] takes a [`CustomFilenameGenerator`] which returns a
/// filename for the testcase.
/// Is never interesting (use with an Eager OR). /// Is never interesting (use with an Eager OR).
///
/// Note: Use only in conjunction with a `Corpus` type that writes to disk. /// Note: Use only in conjunction with a `Corpus` type that writes to disk.
/// Note: If used as part of the `Objective` chain, then it will only apply to testcases which are /// Note: If used as part of the `Objective` chain, then it will only apply to testcases which are
/// `Objectives`, vice versa for `Feedback`. /// `Objectives`, vice versa for `Feedback`.
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct CustomFilenameToTestcaseFeedback<F, I, S> pub struct CustomFilenameToTestcaseFeedback<N> {
where /// Generator that returns the filename.
I: Input, generator: N,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>) -> Result<String, Error>,
{
/// Closure that returns the filename.
func: F,
phantomm: PhantomData<(I, S)>,
} }
impl<F, I, S> CustomFilenameToTestcaseFeedback<F, I, S> impl<N> CustomFilenameToTestcaseFeedback<N> {
where
I: Input,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>) -> Result<String, Error>,
{
/// Create a new [`CustomFilenameToTestcaseFeedback`]. /// Create a new [`CustomFilenameToTestcaseFeedback`].
pub fn new(func: F) -> Self { pub fn new(generator: N) -> Self {
Self { generator }
}
}
impl<N, T> FeedbackFactory<CustomFilenameToTestcaseFeedback<N>, T>
for CustomFilenameToTestcaseFeedback<N>
where
N: Clone,
{
fn create_feedback(&self, _ctx: &T) -> CustomFilenameToTestcaseFeedback<N> {
Self { Self {
func, generator: self.generator.clone(),
phantomm: PhantomData,
} }
} }
} }
impl<F, I, S, T> FeedbackFactory<CustomFilenameToTestcaseFeedback<F, I, S>, T> impl<N> Named for CustomFilenameToTestcaseFeedback<N> {
for CustomFilenameToTestcaseFeedback<F, I, S>
where
I: Input,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>) -> Result<String, Error> + Clone,
{
fn create_feedback(&self, _ctx: &T) -> CustomFilenameToTestcaseFeedback<F, I, S> {
Self {
func: self.func.clone(),
phantomm: self.phantomm,
}
}
}
impl<F, I, S> Named for CustomFilenameToTestcaseFeedback<F, I, S>
where
I: Input,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>) -> Result<String, Error>,
{
fn name(&self) -> &Cow<'static, str> { fn name(&self) -> &Cow<'static, str> {
static NAME: Cow<'static, str> = Cow::Borrowed("CustomFilenameToTestcaseFeedback"); static NAME: Cow<'static, str> = Cow::Borrowed("CustomFilenameToTestcaseFeedback");
&NAME &NAME
} }
} }
impl<F, I, S> Debug for CustomFilenameToTestcaseFeedback<F, I, S> impl<N> Debug for CustomFilenameToTestcaseFeedback<N> {
where
I: Input,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>) -> Result<String, Error>,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("CustomFilenameToTestcaseFeedback") f.debug_struct("CustomFilenameToTestcaseFeedback")
.finish_non_exhaustive() .finish_non_exhaustive()
} }
} }
impl<F, I, S> Feedback<S> for CustomFilenameToTestcaseFeedback<F, I, S> impl<N, S> StateInitializer<S> for CustomFilenameToTestcaseFeedback<N> {}
impl<EM, I, OT, N, S> Feedback<EM, I, OT, S> for CustomFilenameToTestcaseFeedback<N>
where where
S: State<Input = I>, N: CustomFilenameGenerator<I, S>,
F: FnMut(&mut S, &mut Testcase<S::Input>) -> Result<String, Error>,
I: Input,
{ {
#[allow(clippy::wrong_self_convention)]
#[inline]
fn is_interesting<EM, OT>(
&mut self,
_state: &mut S,
_manager: &mut EM,
_input: &I,
_observers: &OT,
_exit_kind: &ExitKind,
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
{
Ok(false)
}
fn append_metadata<EM, OT>(
&mut self,
state: &mut S,
_manager: &mut EM,
_observers: &OT,
testcase: &mut Testcase<<S>::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
*testcase.filename_mut() = Some((self.func)(state, testcase)?);
Ok(())
}
#[cfg(feature = "track_hit_feedbacks")] #[cfg(feature = "track_hit_feedbacks")]
#[inline] #[inline]
fn last_result(&self) -> Result<bool, Error> { fn last_result(&self) -> Result<bool, Error> {
Ok(false) Ok(false)
} }
fn append_metadata(
&mut self,
state: &mut S,
_manager: &mut EM,
_observers: &OT,
testcase: &mut Testcase<I>,
) -> Result<(), Error> {
*testcase.filename_mut() = Some(self.generator.set_name(state, testcase)?);
Ok(())
}
} }

View File

@ -2,10 +2,7 @@
//! //!
use alloc::borrow::Cow; use alloc::borrow::Cow;
use core::{ use core::fmt::{self, Debug, Formatter};
fmt::{self, Debug, Formatter},
marker::PhantomData,
};
use libafl_bolts::{ use libafl_bolts::{
tuples::{Handle, Handled, MatchName, MatchNameRef}, tuples::{Handle, Handled, MatchName, MatchNameRef},
@ -16,13 +13,9 @@ use serde::{Deserialize, Serialize};
#[cfg(feature = "track_hit_feedbacks")] #[cfg(feature = "track_hit_feedbacks")]
use crate::feedbacks::premature_last_result_err; use crate::feedbacks::premature_last_result_err;
use crate::{ use crate::{
events::EventFirer,
executors::ExitKind, executors::ExitKind,
feedbacks::{Feedback, FeedbackFactory}, feedbacks::{Feedback, FeedbackFactory, StateInitializer},
inputs::Input, Error,
observers::{Observer, ObserversTuple},
state::State,
Error, HasMetadata,
}; };
/// The result of a differential test between two observers. /// The result of a differential test between two observers.
@ -51,12 +44,24 @@ impl DiffResult {
} }
} }
/// A [`DiffFeedback`] compares the content of two [`Observer`]s using the given compare function. /// Compares two [`crate::observers::Observer`]s to see if the result should be denoted as equal
#[derive(Serialize, Deserialize)] pub trait DiffComparator<O1, O2> {
pub struct DiffFeedback<F, I, O1, O2, S> /// Performs the comparison between two [`crate::observers::Observer`]s
fn compare(&mut self, first: &O1, second: &O2) -> DiffResult;
}
impl<F, O1, O2> DiffComparator<O1, O2> for F
where where
F: FnMut(&O1, &O2) -> DiffResult, F: Fn(&O1, &O2) -> DiffResult,
{ {
fn compare(&mut self, first: &O1, second: &O2) -> DiffResult {
self(first, second)
}
}
/// A [`DiffFeedback`] compares the content of two observers using the given compare function.
#[derive(Serialize, Deserialize)]
pub struct DiffFeedback<C, O1, O2> {
/// This feedback's name /// This feedback's name
name: Cow<'static, str>, name: Cow<'static, str>,
/// The first observer to compare against /// The first observer to compare against
@ -66,19 +71,17 @@ where
// The previous run's result of `Self::is_interesting` // The previous run's result of `Self::is_interesting`
#[cfg(feature = "track_hit_feedbacks")] #[cfg(feature = "track_hit_feedbacks")]
last_result: Option<bool>, last_result: Option<bool>,
/// The function used to compare the two observers /// The comparator used to compare the two observers
compare_fn: F, comparator: C,
phantomm: PhantomData<(I, S)>,
} }
impl<F, I, O1, O2, S> DiffFeedback<F, I, O1, O2, S> impl<C, O1, O2> DiffFeedback<C, O1, O2>
where where
F: FnMut(&O1, &O2) -> DiffResult,
O1: Named, O1: Named,
O2: Named, O2: Named,
{ {
/// Create a new [`DiffFeedback`] using two observers and a test function. /// Create a new [`DiffFeedback`] using two observers and a test function.
pub fn new(name: &'static str, o1: &O1, o2: &O2, compare_fn: F) -> Result<Self, Error> { pub fn new(name: &'static str, o1: &O1, o2: &O2, comparator: C) -> Result<Self, Error> {
let o1_ref = o1.handle(); let o1_ref = o1.handle();
let o2_ref = o2.handle(); let o2_ref = o2.handle();
if o1_ref.name() == o2_ref.name() { if o1_ref.name() == o2_ref.name() {
@ -93,51 +96,38 @@ where
name: Cow::from(name), name: Cow::from(name),
#[cfg(feature = "track_hit_feedbacks")] #[cfg(feature = "track_hit_feedbacks")]
last_result: None, last_result: None,
compare_fn, comparator,
phantomm: PhantomData,
}) })
} }
} }
} }
impl<F, I, O1, O2, S, T> FeedbackFactory<DiffFeedback<F, I, O1, O2, S>, T> impl<C, O1, O2, T> FeedbackFactory<DiffFeedback<C, O1, O2>, T> for DiffFeedback<C, O1, O2>
for DiffFeedback<F, I, O1, O2, S>
where where
F: FnMut(&O1, &O2) -> DiffResult + Clone, C: Clone,
I: Input,
O1: Observer<S::Input, S> + Named,
O2: Observer<S::Input, S> + Named,
S: HasMetadata + State<Input = I>,
{ {
fn create_feedback(&self, _ctx: &T) -> DiffFeedback<F, I, O1, O2, S> { fn create_feedback(&self, _ctx: &T) -> DiffFeedback<C, O1, O2> {
Self { Self {
name: self.name.clone(), name: self.name.clone(),
o1_ref: self.o1_ref.clone(), o1_ref: self.o1_ref.clone(),
o2_ref: self.o2_ref.clone(), o2_ref: self.o2_ref.clone(),
compare_fn: self.compare_fn.clone(), comparator: self.comparator.clone(),
#[cfg(feature = "track_hit_feedbacks")] #[cfg(feature = "track_hit_feedbacks")]
last_result: None, last_result: None,
phantomm: self.phantomm,
} }
} }
} }
impl<F, I, O1, O2, S> Named for DiffFeedback<F, I, O1, O2, S> impl<C, O1, O2> Named for DiffFeedback<C, O1, O2> {
where
F: FnMut(&O1, &O2) -> DiffResult,
O1: Named,
O2: Named,
{
fn name(&self) -> &Cow<'static, str> { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
impl<F, I, O1, O2, S> Debug for DiffFeedback<F, I, O1, O2, S> impl<C, O1, O2> Debug for DiffFeedback<C, O1, O2>
where where
F: FnMut(&O1, &O2) -> DiffResult, O1: Debug,
O1: Named, O2: Debug,
O2: Named,
{ {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("DiffFeedback") f.debug_struct("DiffFeedback")
@ -148,27 +138,22 @@ where
} }
} }
impl<F, I, O1, O2, S> Feedback<S> for DiffFeedback<F, I, O1, O2, S> impl<C, O1, O2, S> StateInitializer<S> for DiffFeedback<C, O1, O2> {}
impl<C, EM, I, O1, O2, OT, S> Feedback<EM, I, OT, S> for DiffFeedback<C, O1, O2>
where where
F: FnMut(&O1, &O2) -> DiffResult, OT: MatchName,
I: Input, C: DiffComparator<O1, O2>,
S: HasMetadata + State<Input = I>,
O1: Observer<S::Input, S>,
O2: Observer<S::Input, S>,
{ {
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
fn is_interesting<EM, OT>( fn is_interesting(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_input: &I, _input: &I,
observers: &OT, observers: &OT,
_exit_kind: &ExitKind, _exit_kind: &ExitKind,
) -> Result<bool, Error> ) -> Result<bool, Error> {
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S::Input, S> + MatchName,
{
fn err(name: &str) -> Error { fn err(name: &str) -> Error {
Error::illegal_argument(format!("DiffFeedback: observer {name} not found")) Error::illegal_argument(format!("DiffFeedback: observer {name} not found"))
} }
@ -178,7 +163,7 @@ where
let o2: &O2 = observers let o2: &O2 = observers
.get(&self.o2_ref) .get(&self.o2_ref)
.ok_or_else(|| err(self.o2_ref.name()))?; .ok_or_else(|| err(self.o2_ref.name()))?;
let res = (self.compare_fn)(o1, o2) == DiffResult::Diff; let res = self.comparator.compare(o1, o2) == DiffResult::Diff;
#[cfg(feature = "track_hit_feedbacks")] #[cfg(feature = "track_hit_feedbacks")]
{ {
self.last_result = Some(res); self.last_result = Some(res);
@ -195,25 +180,24 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use alloc::borrow::Cow; use alloc::borrow::Cow;
use core::marker::PhantomData;
use libafl_bolts::{tuples::tuple_list, Named}; use libafl_bolts::{tuples::tuple_list, Named};
use crate::{ use crate::{
events::EventFirer, events::NopEventManager,
executors::ExitKind, executors::ExitKind,
feedbacks::{differential::DiffResult, DiffFeedback, Feedback}, feedbacks::{differential::DiffResult, DiffFeedback, Feedback},
inputs::BytesInput, inputs::BytesInput,
observers::Observer, observers::Observer,
state::{NopState, State, UsesState}, state::NopState,
}; };
#[derive(Debug)] #[derive(Debug)]
struct NopObserver { struct DummyObserver {
name: Cow<'static, str>, name: Cow<'static, str>,
value: bool, value: bool,
} }
impl NopObserver { impl DummyObserver {
fn new(name: &'static str, value: bool) -> Self { fn new(name: &'static str, value: bool) -> Self {
Self { Self {
name: Cow::from(name), name: Cow::from(name),
@ -221,67 +205,40 @@ mod tests {
} }
} }
} }
impl<I, S> Observer<I, S> for NopObserver {} impl<I, S> Observer<I, S> for DummyObserver {}
impl PartialEq for NopObserver { impl PartialEq for DummyObserver {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.value == other.value self.value == other.value
} }
} }
impl Named for NopObserver { impl Named for DummyObserver {
fn name(&self) -> &Cow<'static, str> { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
struct NopEventFirer<S> { fn comparator(o1: &DummyObserver, o2: &DummyObserver) -> DiffResult {
phantom: PhantomData<S>,
}
impl<S> UsesState for NopEventFirer<S>
where
S: State,
{
type State = S;
}
impl<S> EventFirer for NopEventFirer<S>
where
S: State,
{
fn should_send(&self) -> bool {
true
}
fn fire(
&mut self,
_state: &mut S,
_event: crate::events::Event<S::Input>,
) -> Result<(), crate::Error> {
Ok(())
}
}
fn test_diff(should_equal: bool) {
let mut nop_state = NopState::new();
let o1 = NopObserver::new("o1", true);
let o2 = NopObserver::new("o2", should_equal);
let mut diff_feedback = DiffFeedback::new("diff_feedback", &o1, &o2, |o1, o2| {
if o1 == o2 { if o1 == o2 {
DiffResult::Equal DiffResult::Equal
} else { } else {
DiffResult::Diff DiffResult::Diff
} }
}) }
.unwrap();
fn test_diff(should_equal: bool) {
let mut nop_state: NopState<BytesInput> = NopState::new();
let o1 = DummyObserver::new("o1", true);
let o2 = DummyObserver::new("o2", should_equal);
let mut diff_feedback = DiffFeedback::new("diff_feedback", &o1, &o2, comparator).unwrap();
let observers = tuple_list![o1, o2]; let observers = tuple_list![o1, o2];
assert_eq!( assert_eq!(
!should_equal, !should_equal,
diff_feedback DiffFeedback::<_, _, _>::is_interesting(
.is_interesting( &mut diff_feedback,
&mut nop_state, &mut nop_state,
&mut NopEventFirer { &mut NopEventManager::<NopState<BytesInput>>::default(),
phantom: PhantomData
},
&BytesInput::new(vec![0]), &BytesInput::new(vec![0]),
&observers, &observers,
&ExitKind::Ok &ExitKind::Ok

View File

@ -3,46 +3,34 @@ use core::{fmt::Debug, hash::Hash};
use hashbrown::HashSet; use hashbrown::HashSet;
use libafl_bolts::{ use libafl_bolts::{
tuples::{Handle, Handled, MatchNameRef}, tuples::{Handle, Handled, MatchName, MatchNameRef},
Error, HasRefCnt, Named, Error, HasRefCnt, Named,
}; };
use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serde::{de::DeserializeOwned, Deserialize, Serialize};
use crate::{ use crate::{
events::EventFirer,
executors::ExitKind, executors::ExitKind,
feedbacks::Feedback, feedbacks::{Feedback, StateInitializer},
observers::{ListObserver, ObserversTuple}, observers::ListObserver,
state::State,
HasNamedMetadata, HasNamedMetadata,
}; };
/// The metadata to remember past observed value /// The metadata to remember past observed value
#[derive(Default, Serialize, Deserialize, Clone, Debug)] #[derive(Default, Serialize, Deserialize, Clone, Debug)]
#[serde(bound = "T: DeserializeOwned")] #[serde(bound = "T: Eq + Hash + for<'a> Deserialize<'a> + Serialize")]
#[cfg_attr( pub struct ListFeedbackMetadata<T> {
any(not(feature = "serdeany_autoreg"), miri),
allow(clippy::unsafe_derive_deserialize)
)]
pub struct ListFeedbackMetadata<T>
where
T: Default + Copy + 'static + Serialize + Eq + Hash,
{
/// Contains the information of past observed set of values. /// Contains the information of past observed set of values.
pub set: HashSet<T>, pub set: HashSet<T>,
/// A refcount used to know when we can remove this metadata /// A refcount used to know when we can remove this metadata
pub tcref: isize, pub tcref: isize,
} }
impl<T> ListFeedbackMetadata<T> impl<T> ListFeedbackMetadata<T> {
where
T: Default + Copy + 'static + Serialize + Eq + Hash,
{
/// The constructor /// The constructor
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
set: HashSet::<T>::new(), set: HashSet::new(),
tcref: 0, tcref: 0,
} }
} }
@ -54,10 +42,7 @@ where
} }
} }
impl<T> HasRefCnt for ListFeedbackMetadata<T> impl<T> HasRefCnt for ListFeedbackMetadata<T> {
where
T: Default + Copy + 'static + Serialize + Eq + Hash,
{
fn refcnt(&self) -> isize { fn refcnt(&self) -> isize {
self.tcref self.tcref
} }
@ -69,10 +54,7 @@ where
/// Consider interesting a testcase if the list in `ListObserver` is not empty. /// Consider interesting a testcase if the list in `ListObserver` is not empty.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct ListFeedback<T> pub struct ListFeedback<T> {
where
T: Hash + Eq,
{
observer_handle: Handle<ListObserver<T>>, observer_handle: Handle<ListObserver<T>>,
novelty: HashSet<T>, novelty: HashSet<T>,
} }
@ -82,30 +64,32 @@ libafl_bolts::impl_serdeany!(
<u8>,<u16>,<u32>,<u64>,<i8>,<i16>,<i32>,<i64>,<bool>,<char>,<usize> <u8>,<u16>,<u32>,<u64>,<i8>,<i16>,<i32>,<i64>,<bool>,<char>,<usize>
); );
impl<S, T> Feedback<S> for ListFeedback<T> impl<S, T> StateInitializer<S> for ListFeedback<T>
where where
S: State + HasNamedMetadata, S: HasNamedMetadata,
T: Debug + Serialize + Hash + Eq + DeserializeOwned + Default + Copy + 'static, T: Debug + Serialize + Hash + Eq + DeserializeOwned + Default + Copy + 'static,
{ {
fn init_state(&mut self, state: &mut S) -> Result<(), Error> { fn init_state(&mut self, state: &mut S) -> Result<(), Error> {
// eprintln!("self.name {:#?}", &self.name);
state.add_named_metadata(self.name(), ListFeedbackMetadata::<T>::default()); state.add_named_metadata(self.name(), ListFeedbackMetadata::<T>::default());
Ok(()) Ok(())
} }
}
impl<EM, I, OT, S, T> Feedback<EM, I, OT, S> for ListFeedback<T>
where
OT: MatchName,
S: HasNamedMetadata,
T: Debug + Serialize + Hash + Eq + DeserializeOwned + Default + Copy + 'static,
{
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
fn is_interesting<EM, OT>( fn is_interesting(
&mut self, &mut self,
state: &mut S, state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_input: &S::Input, _input: &I,
observers: &OT, observers: &OT,
_exit_kind: &ExitKind, _exit_kind: &ExitKind,
) -> Result<bool, Error> ) -> Result<bool, Error> {
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S::Input, S>,
{
// TODO Replace with match_name_type when stable
let observer = observers.get(&self.observer_handle).unwrap(); let observer = observers.get(&self.observer_handle).unwrap();
// TODO register the list content in a testcase metadata // TODO register the list content in a testcase metadata
self.novelty.clear(); self.novelty.clear();
@ -122,17 +106,18 @@ where
Ok(!self.novelty.is_empty()) Ok(!self.novelty.is_empty())
} }
fn append_metadata<EM, OT>( #[cfg(feature = "track_hit_feedbacks")]
fn last_result(&self) -> Result<bool, Error> {
Ok(!self.novelty.is_empty())
}
fn append_metadata(
&mut self, &mut self,
state: &mut S, state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_observers: &OT, _observers: &OT,
_testcase: &mut crate::corpus::Testcase<<S>::Input>, _testcase: &mut crate::corpus::Testcase<I>,
) -> Result<(), Error> ) -> Result<(), Error> {
where
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
let history_set = state let history_set = state
.named_metadata_map_mut() .named_metadata_map_mut()
.get_mut::<ListFeedbackMetadata<T>>(self.name()) .get_mut::<ListFeedbackMetadata<T>>(self.name())
@ -143,32 +128,22 @@ where
} }
Ok(()) Ok(())
} }
#[cfg(feature = "track_hit_feedbacks")]
fn last_result(&self) -> Result<bool, Error> {
Ok(!self.novelty.is_empty())
}
} }
impl<T> Named for ListFeedback<T> impl<T> Named for ListFeedback<T> {
where
T: Debug + Serialize + Hash + Eq + DeserializeOwned,
{
#[inline] #[inline]
fn name(&self) -> &Cow<'static, str> { fn name(&self) -> &Cow<'static, str> {
self.observer_handle.name() self.observer_handle.name()
} }
} }
impl<T> ListFeedback<T> impl<T> ListFeedback<T> {
where
T: Debug + Serialize + Hash + Eq + DeserializeOwned,
{
/// Creates a new [`ListFeedback`], deciding if the given [`ListObserver`] value of a run is interesting. /// Creates a new [`ListFeedback`], deciding if the given [`ListObserver`] value of a run is interesting.
#[must_use] #[must_use]
pub fn new(observer: &ListObserver<T>) -> Self { pub fn new(observer: &ListObserver<T>) -> Self {
Self { Self {
observer_handle: observer.handle(), observer_handle: observer.handle(),
novelty: HashSet::<T>::new(), novelty: HashSet::new(),
} }
} }
} }

View File

@ -12,7 +12,7 @@ use core::{
#[rustversion::nightly] #[rustversion::nightly]
use libafl_bolts::AsSlice; use libafl_bolts::AsSlice;
use libafl_bolts::{ use libafl_bolts::{
tuples::{Handle, Handled, MatchNameRef}, tuples::{Handle, Handled, MatchName, MatchNameRef},
AsIter, HasRefCnt, Named, AsIter, HasRefCnt, Named,
}; };
use num_traits::PrimInt; use num_traits::PrimInt;
@ -24,37 +24,33 @@ use crate::{
corpus::Testcase, corpus::Testcase,
events::{Event, EventFirer}, events::{Event, EventFirer},
executors::ExitKind, executors::ExitKind,
feedbacks::{Feedback, HasObserverHandle}, feedbacks::{Feedback, HasObserverHandle, StateInitializer},
inputs::UsesInput, inputs::UsesInput,
monitors::{AggregatorOps, UserStats, UserStatsValue}, monitors::{AggregatorOps, UserStats, UserStatsValue},
observers::{CanTrack, MapObserver, Observer, ObserversTuple}, observers::{CanTrack, MapObserver},
state::State,
Error, HasMetadata, HasNamedMetadata, Error, HasMetadata, HasNamedMetadata,
}; };
/// A [`MapFeedback`] that implements the AFL algorithm using an [`OrReducer`] combining the bits for the history map and the bit from (`HitcountsMapObserver`)[`crate::observers::HitcountsMapObserver`]. /// A [`MapFeedback`] that implements the AFL algorithm using an [`OrReducer`] combining the bits for the history map and the bit from (`HitcountsMapObserver`)[`crate::observers::HitcountsMapObserver`].
pub type AflMapFeedback<C, O, T> = MapFeedback<C, DifferentIsNovel, O, OrReducer, T>; pub type AflMapFeedback<C, O> = MapFeedback<C, DifferentIsNovel, O, OrReducer>;
/// A [`MapFeedback`] that strives to maximize the map contents. /// A [`MapFeedback`] that strives to maximize the map contents.
pub type MaxMapFeedback<C, O, T> = MapFeedback<C, DifferentIsNovel, O, MaxReducer, T>; pub type MaxMapFeedback<C, O> = MapFeedback<C, DifferentIsNovel, O, MaxReducer>;
/// A [`MapFeedback`] that strives to minimize the map contents. /// A [`MapFeedback`] that strives to minimize the map contents.
pub type MinMapFeedback<C, O, T> = MapFeedback<C, DifferentIsNovel, O, MinReducer, T>; pub type MinMapFeedback<C, O> = MapFeedback<C, DifferentIsNovel, O, MinReducer>;
/// A [`MapFeedback`] that always returns `true` for `is_interesting`. Useful for tracing all executions. /// A [`MapFeedback`] that always returns `true` for `is_interesting`. Useful for tracing all executions.
pub type AlwaysInterestingMapFeedback<C, O, T> = MapFeedback<C, AllIsNovel, O, NopReducer, T>; pub type AlwaysInterestingMapFeedback<C, O> = MapFeedback<C, AllIsNovel, O, NopReducer>;
/// A [`MapFeedback`] that strives to maximize the map contents, /// A [`MapFeedback`] that strives to maximize the map contents,
/// but only, if a value is larger than `pow2` of the previous. /// but only, if a value is larger than `pow2` of the previous.
pub type MaxMapPow2Feedback<C, O, T> = MapFeedback<C, NextPow2IsNovel, O, MaxReducer, T>; pub type MaxMapPow2Feedback<C, O> = MapFeedback<C, NextPow2IsNovel, O, MaxReducer>;
/// A [`MapFeedback`] that strives to maximize the map contents, /// A [`MapFeedback`] that strives to maximize the map contents,
/// but only, if a value is either `T::one()` or `T::max_value()`. /// but only, if a value is either `T::one()` or `T::max_value()`.
pub type MaxMapOneOrFilledFeedback<C, O, T> = MapFeedback<C, OneOrFilledIsNovel, O, MaxReducer, T>; pub type MaxMapOneOrFilledFeedback<C, O> = MapFeedback<C, OneOrFilledIsNovel, O, MaxReducer>;
/// A `Reducer` function is used to aggregate values for the novelty search /// A `Reducer` function is used to aggregate values for the novelty search
pub trait Reducer<T>: 'static pub trait Reducer<T> {
where
T: Default + Copy + 'static,
{
/// Reduce two values to one value, with the current [`Reducer`]. /// Reduce two values to one value, with the current [`Reducer`].
fn reduce(first: T, second: T) -> T; fn reduce(first: T, second: T) -> T;
} }
@ -65,7 +61,7 @@ pub struct OrReducer {}
impl<T> Reducer<T> for OrReducer impl<T> Reducer<T> for OrReducer
where where
T: BitOr<Output = T> + Default + Copy + 'static + PartialOrd, T: BitOr<Output = T>,
{ {
#[inline] #[inline]
fn reduce(history: T, new: T) -> T { fn reduce(history: T, new: T) -> T {
@ -79,7 +75,7 @@ pub struct AndReducer {}
impl<T> Reducer<T> for AndReducer impl<T> Reducer<T> for AndReducer
where where
T: BitAnd<Output = T> + Default + Copy + 'static + PartialOrd, T: BitAnd<Output = T>,
{ {
#[inline] #[inline]
fn reduce(history: T, new: T) -> T { fn reduce(history: T, new: T) -> T {
@ -91,10 +87,7 @@ where
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct NopReducer {} pub struct NopReducer {}
impl<T> Reducer<T> for NopReducer impl<T> Reducer<T> for NopReducer {
where
T: Default + Copy + 'static,
{
#[inline] #[inline]
fn reduce(_history: T, new: T) -> T { fn reduce(_history: T, new: T) -> T {
new new
@ -107,7 +100,7 @@ pub struct MaxReducer {}
impl<T> Reducer<T> for MaxReducer impl<T> Reducer<T> for MaxReducer
where where
T: Default + Copy + 'static + PartialOrd, T: PartialOrd,
{ {
#[inline] #[inline]
fn reduce(first: T, second: T) -> T { fn reduce(first: T, second: T) -> T {
@ -125,7 +118,7 @@ pub struct MinReducer {}
impl<T> Reducer<T> for MinReducer impl<T> Reducer<T> for MinReducer
where where
T: Default + Copy + 'static + PartialOrd, T: PartialOrd,
{ {
#[inline] #[inline]
fn reduce(first: T, second: T) -> T { fn reduce(first: T, second: T) -> T {
@ -138,10 +131,7 @@ where
} }
/// A `IsNovel` function is used to discriminate if a reduced value is considered novel. /// A `IsNovel` function is used to discriminate if a reduced value is considered novel.
pub trait IsNovel<T>: 'static pub trait IsNovel<T> {
where
T: Default + Copy + 'static,
{
/// If a new value in the [`MapFeedback`] was found, /// If a new value in the [`MapFeedback`] was found,
/// this filter can decide if the result is considered novel or not. /// this filter can decide if the result is considered novel or not.
fn is_novel(old: T, new: T) -> bool; fn is_novel(old: T, new: T) -> bool;
@ -225,11 +215,8 @@ where
} }
/// A testcase metadata holding a list of indexes of a map /// A testcase metadata holding a list of indexes of a map
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
#[cfg_attr( #[allow(clippy::unsafe_derive_deserialize)] // for SerdeAny
any(not(feature = "serdeany_autoreg"), miri),
allow(clippy::unsafe_derive_deserialize)
)] // for SerdeAny
pub struct MapIndexesMetadata { pub struct MapIndexesMetadata {
/// The list of indexes. /// The list of indexes.
pub list: Vec<usize>, pub list: Vec<usize>,
@ -274,10 +261,7 @@ impl MapIndexesMetadata {
/// A testcase metadata holding a list of indexes of a map /// A testcase metadata holding a list of indexes of a map
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
#[cfg_attr( #[allow(clippy::unsafe_derive_deserialize)] // for SerdeAny
any(not(feature = "serdeany_autoreg"), miri),
allow(clippy::unsafe_derive_deserialize)
)] // for SerdeAny
pub struct MapNoveltiesMetadata { pub struct MapNoveltiesMetadata {
/// A `list` of novelties. /// A `list` of novelties.
pub list: Vec<usize>, pub list: Vec<usize>,
@ -312,15 +296,8 @@ impl MapNoveltiesMetadata {
/// The state of [`MapFeedback`] /// The state of [`MapFeedback`]
#[derive(Default, Serialize, Deserialize, Clone, Debug)] #[derive(Default, Serialize, Deserialize, Clone, Debug)]
#[serde(bound = "T: DeserializeOwned")] #[allow(clippy::unsafe_derive_deserialize)] // for SerdeAny
#[cfg_attr( pub struct MapFeedbackMetadata<T> {
any(not(feature = "serdeany_autoreg"), miri),
allow(clippy::unsafe_derive_deserialize)
)] // for SerdeAny
pub struct MapFeedbackMetadata<T>
where
T: Default + Copy + 'static + Serialize,
{
/// Contains information about untouched entries /// Contains information about untouched entries
pub history_map: Vec<T>, pub history_map: Vec<T>,
/// Tells us how many non-initial entries there are in `history_map` /// Tells us how many non-initial entries there are in `history_map`
@ -328,7 +305,7 @@ where
} }
libafl_bolts::impl_serdeany!( libafl_bolts::impl_serdeany!(
MapFeedbackMetadata<T: Debug + Default + Copy + 'static + Serialize + DeserializeOwned>, MapFeedbackMetadata<T: 'static + Debug + Serialize + DeserializeOwned>,
<u8>,<u16>,<u32>,<u64>,<i8>,<i16>,<i32>,<i64>,<f32>,<f64>,<bool>,<char>,<usize> <u8>,<u16>,<u32>,<u64>,<i8>,<i16>,<i32>,<i64>,<f32>,<f64>,<bool>,<char>,<usize>
); );
@ -384,7 +361,7 @@ where
/// The most common AFL-like feedback type /// The most common AFL-like feedback type
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct MapFeedback<C, N, O, R, T> { pub struct MapFeedback<C, N, O, R> {
/// New indexes observed in the last observation /// New indexes observed in the last observation
novelties: Option<Vec<usize>>, novelties: Option<Vec<usize>>,
/// Name identifier of this instance /// Name identifier of this instance
@ -397,38 +374,44 @@ pub struct MapFeedback<C, N, O, R, T> {
#[cfg(feature = "track_hit_feedbacks")] #[cfg(feature = "track_hit_feedbacks")]
last_result: Option<bool>, last_result: Option<bool>,
/// Phantom Data of Reducer /// Phantom Data of Reducer
phantom: PhantomData<(C, N, O, R, T)>, #[allow(clippy::type_complexity)]
phantom: PhantomData<fn() -> (N, O, R)>,
} }
impl<C, N, O, R, S, T> Feedback<S> for MapFeedback<C, N, O, R, T> impl<C, N, O, R, S> StateInitializer<S> for MapFeedback<C, N, O, R>
where where
N: IsNovel<T>, O: MapObserver,
O: MapObserver<Entry = T> + for<'it> AsIter<'it, Item = T>, O::Entry: 'static + Default + Debug + DeserializeOwned + Serialize,
R: Reducer<T>, S: HasNamedMetadata,
S: State + HasNamedMetadata,
T: Default + Copy + Serialize + for<'de> Deserialize<'de> + PartialEq + Debug + 'static,
C: CanTrack + AsRef<O> + Named,
{ {
fn init_state(&mut self, state: &mut S) -> Result<(), Error> { fn init_state(&mut self, state: &mut S) -> Result<(), Error> {
// Initialize `MapFeedbackMetadata` with an empty vector and add it to the state. // Initialize `MapFeedbackMetadata` with an empty vector and add it to the state.
// The `MapFeedbackMetadata` would be resized on-demand in `is_interesting` // The `MapFeedbackMetadata` would be resized on-demand in `is_interesting`
state.add_named_metadata(&self.name, MapFeedbackMetadata::<T>::default()); state.add_named_metadata(&self.name, MapFeedbackMetadata::<O::Entry>::default());
Ok(()) Ok(())
} }
}
impl<C, EM, I, N, O, OT, R, S> Feedback<EM, I, OT, S> for MapFeedback<C, N, O, R>
where
C: CanTrack + AsRef<O>,
EM: EventFirer<State = S>,
N: IsNovel<O::Entry>,
O: MapObserver + for<'it> AsIter<'it, Item = O::Entry>,
O::Entry: 'static + Default + Debug + DeserializeOwned + Serialize,
OT: MatchName,
R: Reducer<O::Entry>,
S: HasNamedMetadata + UsesInput, // delete me
{
#[rustversion::nightly] #[rustversion::nightly]
default fn is_interesting<EM, OT>( default fn is_interesting(
&mut self, &mut self,
state: &mut S, state: &mut S,
manager: &mut EM, manager: &mut EM,
input: &S::Input, input: &I,
observers: &OT, observers: &OT,
exit_kind: &ExitKind, exit_kind: &ExitKind,
) -> Result<bool, Error> ) -> Result<bool, Error> {
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S::Input, S>,
{
let res = self.is_interesting_default(state, manager, input, observers, exit_kind); let res = self.is_interesting_default(state, manager, input, observers, exit_kind);
#[cfg(feature = "track_hit_feedbacks")] #[cfg(feature = "track_hit_feedbacks")]
{ {
@ -438,18 +421,14 @@ where
} }
#[rustversion::not(nightly)] #[rustversion::not(nightly)]
fn is_interesting<EM, OT>( fn is_interesting(
&mut self, &mut self,
state: &mut S, state: &mut S,
manager: &mut EM, manager: &mut EM,
input: &<S as UsesInput>::Input, input: &I,
observers: &OT, observers: &OT,
exit_kind: &ExitKind, exit_kind: &ExitKind,
) -> Result<bool, Error> ) -> Result<bool, Error> {
where
EM: EventFirer<State = S>,
OT: ObserversTuple<<S as UsesInput>::Input, S>,
{
let res = self.is_interesting_default(state, manager, input, observers, exit_kind); let res = self.is_interesting_default(state, manager, input, observers, exit_kind);
#[cfg(feature = "track_hit_feedbacks")] #[cfg(feature = "track_hit_feedbacks")]
@ -459,17 +438,18 @@ where
Ok(res) Ok(res)
} }
fn append_metadata<EM, OT>( #[cfg(feature = "track_hit_feedbacks")]
fn last_result(&self) -> Result<bool, Error> {
self.last_result.ok_or(premature_last_result_err())
}
fn append_metadata(
&mut self, &mut self,
state: &mut S, state: &mut S,
manager: &mut EM, manager: &mut EM,
observers: &OT, observers: &OT,
testcase: &mut Testcase<S::Input>, testcase: &mut Testcase<I>,
) -> Result<(), Error> ) -> Result<(), Error> {
where
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
if let Some(novelties) = self.novelties.as_mut().map(core::mem::take) { if let Some(novelties) = self.novelties.as_mut().map(core::mem::take) {
let meta = MapNoveltiesMetadata::new(novelties); let meta = MapNoveltiesMetadata::new(novelties);
testcase.add_metadata(meta); testcase.add_metadata(meta);
@ -478,7 +458,7 @@ where
let initial = observer.initial(); let initial = observer.initial();
let map_state = state let map_state = state
.named_metadata_map_mut() .named_metadata_map_mut()
.get_mut::<MapFeedbackMetadata<T>>(&self.name) .get_mut::<MapFeedbackMetadata<O::Entry>>(&self.name)
.unwrap(); .unwrap();
let len = observer.len(); let len = observer.len();
if map_state.history_map.len() < len { if map_state.history_map.len() < len {
@ -551,35 +531,28 @@ where
Ok(()) Ok(())
} }
#[cfg(feature = "track_hit_feedbacks")]
fn last_result(&self) -> Result<bool, Error> {
self.last_result.ok_or(premature_last_result_err())
}
} }
/// Specialize for the common coverage map size, maximization of u8s /// Specialize for the common coverage map size, maximization of u8s
#[rustversion::nightly] #[rustversion::nightly]
impl<C, O, S> Feedback<S> for MapFeedback<C, DifferentIsNovel, O, MaxReducer, u8> impl<C, O, EM, I, OT, S> Feedback<EM, I, OT, S> for MapFeedback<C, DifferentIsNovel, O, MaxReducer>
where where
C: CanTrack + AsRef<O>,
EM: EventFirer<State = S>,
O: MapObserver<Entry = u8> + for<'a> AsSlice<'a, Entry = u8> + for<'a> AsIter<'a, Item = u8>, O: MapObserver<Entry = u8> + for<'a> AsSlice<'a, Entry = u8> + for<'a> AsIter<'a, Item = u8>,
S: State + HasNamedMetadata, OT: MatchName,
C: CanTrack + AsRef<O> + Observer<S::Input, S>, S: HasNamedMetadata + UsesInput,
{ {
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
#[allow(clippy::needless_range_loop)] #[allow(clippy::needless_range_loop)]
fn is_interesting<EM, OT>( fn is_interesting(
&mut self, &mut self,
state: &mut S, state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_input: &S::Input, _input: &I,
observers: &OT, observers: &OT,
_exit_kind: &ExitKind, _exit_kind: &ExitKind,
) -> Result<bool, Error> ) -> Result<bool, Error> {
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S::Input, S>,
{
// 128 bits vectors // 128 bits vectors
type VectorType = core::simd::u8x16; type VectorType = core::simd::u8x16;
@ -679,18 +652,14 @@ where
} }
} }
impl<C, N, O, R, T> Named for MapFeedback<C, N, O, R, T> { impl<C, N, O, R> Named for MapFeedback<C, N, O, R> {
#[inline] #[inline]
fn name(&self) -> &Cow<'static, str> { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
impl<C, N, O, R, T> HasObserverHandle for MapFeedback<C, N, O, R, T> impl<C, N, O, R> HasObserverHandle for MapFeedback<C, N, O, R> {
where
O: Named,
C: AsRef<O>,
{
type Observer = C; type Observer = C;
#[inline] #[inline]
@ -708,14 +677,9 @@ fn create_stats_name(name: &Cow<'static, str>) -> Cow<'static, str> {
} }
} }
impl<C, N, O, R, T> MapFeedback<C, N, O, R, T> impl<C, N, O, R> MapFeedback<C, N, O, R>
where where
T: PartialEq + Default + Copy + 'static + Serialize + DeserializeOwned + Debug, C: CanTrack + Named + AsRef<O>,
R: Reducer<T>,
O: MapObserver<Entry = T>,
for<'it> O: AsIter<'it, Item = T>,
N: IsNovel<T>,
C: CanTrack + AsRef<O> + Named,
{ {
/// Create new `MapFeedback` /// Create new `MapFeedback`
#[must_use] #[must_use]
@ -747,22 +711,30 @@ where
phantom: PhantomData, phantom: PhantomData,
} }
} }
}
impl<C, N, O, R> MapFeedback<C, N, O, R>
where
R: Reducer<O::Entry>,
O: MapObserver + for<'it> AsIter<'it, Item = O::Entry>,
O::Entry: 'static + Debug + Serialize + DeserializeOwned,
N: IsNovel<O::Entry>,
C: AsRef<O>,
{
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
#[allow(clippy::needless_range_loop)] #[allow(clippy::needless_range_loop)]
#[allow(clippy::trivially_copy_pass_by_ref)] #[allow(clippy::trivially_copy_pass_by_ref)]
fn is_interesting_default<EM, S, OT>( fn is_interesting_default<EM, I, OT, S>(
&mut self, &mut self,
state: &mut S, state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_input: &S::Input, _input: &I,
observers: &OT, observers: &OT,
_exit_kind: &ExitKind, _exit_kind: &ExitKind,
) -> bool ) -> bool
where where
EM: EventFirer<State = S>, S: HasNamedMetadata,
OT: ObserversTuple<S::Input, S>, OT: MatchName,
S: UsesInput + HasNamedMetadata,
{ {
let mut interesting = false; let mut interesting = false;
// TODO Replace with match_name_type when stable // TODO Replace with match_name_type when stable
@ -770,7 +742,7 @@ where
let map_state = state let map_state = state
.named_metadata_map_mut() .named_metadata_map_mut()
.get_mut::<MapFeedbackMetadata<T>>(&self.name) .get_mut::<MapFeedbackMetadata<O::Entry>>(&self.name)
.unwrap(); .unwrap();
let len = observer.len(); let len = observer.len();
if map_state.history_map.len() < len { if map_state.history_map.len() < len {

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
//! Nautilus grammar mutator, see <https://github.com/nautilus-fuzz/nautilus> //! Nautilus grammar mutator, see <https://github.com/nautilus-fuzz/nautilus>
use alloc::{borrow::Cow, string::String}; use alloc::{borrow::Cow, string::String};
use core::{fmt::Debug, marker::PhantomData}; use core::fmt::Debug;
use std::fs::create_dir_all; use std::fs::create_dir_all;
use libafl_bolts::Named; use libafl_bolts::Named;
@ -9,13 +9,11 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
common::nautilus::grammartec::{chunkstore::ChunkStore, context::Context}, common::nautilus::grammartec::{chunkstore::ChunkStore, context::Context},
corpus::{Corpus, Testcase}, corpus::{Corpus, Testcase},
events::EventFirer,
executors::ExitKind, executors::ExitKind,
feedbacks::Feedback, feedbacks::{Feedback, StateInitializer},
generators::NautilusContext, generators::NautilusContext,
inputs::NautilusInput, inputs::NautilusInput,
observers::ObserversTuple, state::HasCorpus,
state::{HasCorpus, State},
Error, HasMetadata, Error, HasMetadata,
}; };
@ -51,66 +49,52 @@ impl NautilusChunksMetadata {
} }
/// A nautilus feedback for grammar fuzzing /// A nautilus feedback for grammar fuzzing
pub struct NautilusFeedback<'a, S> { #[derive(Debug)]
pub struct NautilusFeedback<'a> {
ctx: &'a Context, ctx: &'a Context,
phantom: PhantomData<S>,
} }
impl<S> Debug for NautilusFeedback<'_, S> { impl<'a> NautilusFeedback<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "NautilusFeedback {{}}")
}
}
impl<'a, S> NautilusFeedback<'a, S> {
/// Create a new [`NautilusFeedback`] /// Create a new [`NautilusFeedback`]
#[must_use] #[must_use]
pub fn new(context: &'a NautilusContext) -> Self { pub fn new(context: &'a NautilusContext) -> Self {
Self { Self { ctx: &context.ctx }
ctx: &context.ctx,
phantom: PhantomData,
}
} }
} }
impl<'a, S> Named for NautilusFeedback<'a, S> { impl<'a> Named for NautilusFeedback<'a> {
fn name(&self) -> &Cow<'static, str> { fn name(&self) -> &Cow<'static, str> {
static NAME: Cow<'static, str> = Cow::Borrowed("NautilusFeedback"); static NAME: Cow<'static, str> = Cow::Borrowed("NautilusFeedback");
&NAME &NAME
} }
} }
impl<'a, S> Feedback<S> for NautilusFeedback<'a, S> impl<'a, S> StateInitializer<S> for NautilusFeedback<'a> {}
impl<'a, EM, OT, S> Feedback<EM, NautilusInput, OT, S> for NautilusFeedback<'a>
where where
S: HasMetadata + HasCorpus + State<Input = NautilusInput>, S: HasMetadata + HasCorpus,
S::Corpus: Corpus<Input = NautilusInput>, S::Corpus: Corpus<Input = NautilusInput>,
{ {
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
fn is_interesting<EM, OT>( fn is_interesting(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_input: &NautilusInput, _input: &NautilusInput,
_observers: &OT, _observers: &OT,
_exit_kind: &ExitKind, _exit_kind: &ExitKind,
) -> Result<bool, Error> ) -> Result<bool, Error> {
where
EM: EventFirer<State = S>,
OT: ObserversTuple<NautilusInput, S>,
{
Ok(false) Ok(false)
} }
fn append_metadata<EM, OT>( fn append_metadata(
&mut self, &mut self,
state: &mut S, state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_observers: &OT, _observers: &OT,
testcase: &mut Testcase<S::Input>, testcase: &mut Testcase<NautilusInput>,
) -> Result<(), Error> ) -> Result<(), Error> {
where
OT: ObserversTuple<NautilusInput, S>,
{
state.corpus().load_input_into(testcase)?; state.corpus().load_input_into(testcase)?;
let input = testcase.input().as_ref().unwrap().clone(); let input = testcase.input().as_ref().unwrap().clone();
let meta = state let meta = state

View File

@ -1,11 +1,11 @@
//! The ``NewHashFeedback`` uses the backtrace hash and a hashset to only keep novel cases //! The ``NewHashFeedback`` uses the backtrace hash and a hashset to only keep novel cases
use alloc::{borrow::Cow, string::ToString}; use alloc::{borrow::Cow, string::ToString};
use std::{fmt::Debug, marker::PhantomData}; use std::fmt::Debug;
use hashbrown::HashSet; use hashbrown::HashSet;
use libafl_bolts::{ use libafl_bolts::{
tuples::{Handle, Handled, MatchNameRef}, tuples::{Handle, Handled, MatchName, MatchNameRef},
Named, Named,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -13,12 +13,9 @@ use serde::{Deserialize, Serialize};
#[cfg(feature = "track_hit_feedbacks")] #[cfg(feature = "track_hit_feedbacks")]
use crate::feedbacks::premature_last_result_err; use crate::feedbacks::premature_last_result_err;
use crate::{ use crate::{
events::EventFirer,
executors::ExitKind, executors::ExitKind,
feedbacks::{Feedback, HasObserverHandle}, feedbacks::{Feedback, HasObserverHandle, StateInitializer},
inputs::UsesInput, observers::ObserverWithHashField,
observers::{ObserverWithHashField, ObserversTuple},
state::State,
Error, HasNamedMetadata, Error, HasNamedMetadata,
}; };
@ -38,7 +35,7 @@ pub trait HashSetState<T> {
#[allow(clippy::unsafe_derive_deserialize)] #[allow(clippy::unsafe_derive_deserialize)]
pub struct NewHashFeedbackMetadata { pub struct NewHashFeedbackMetadata {
/// Contains information about untouched entries /// Contains information about untouched entries
pub hash_set: HashSet<u64>, hash_set: HashSet<u64>,
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -64,6 +61,17 @@ impl NewHashFeedbackMetadata {
self.hash_set.clear(); self.hash_set.clear();
Ok(()) Ok(())
} }
/// Gets the associated [`HashSet`] being used to track hashes
#[must_use]
pub fn hash_set(&self) -> &HashSet<u64> {
&self.hash_set
}
/// Gets the associated [`HashSet`] being used to track hashes, mutably
pub fn hash_set_mut(&mut self) -> &mut HashSet<u64> {
&mut self.hash_set
}
} }
impl HashSetState<u64> for NewHashFeedbackMetadata { impl HashSetState<u64> for NewHashFeedbackMetadata {
@ -82,7 +90,7 @@ impl HashSetState<u64> for NewHashFeedbackMetadata {
/// A [`NewHashFeedback`] maintains a hashset of already seen stacktraces and considers interesting unseen ones /// A [`NewHashFeedback`] maintains a hashset of already seen stacktraces and considers interesting unseen ones
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NewHashFeedback<O, S> { pub struct NewHashFeedback<O> {
name: Cow<'static, str>, name: Cow<'static, str>,
o_ref: Handle<O>, o_ref: Handle<O>,
/// Initial capacity of hash set /// Initial capacity of hash set
@ -90,13 +98,11 @@ pub struct NewHashFeedback<O, S> {
#[cfg(feature = "track_hit_feedbacks")] #[cfg(feature = "track_hit_feedbacks")]
// The previous run's result of `Self::is_interesting` // The previous run's result of `Self::is_interesting`
last_result: Option<bool>, last_result: Option<bool>,
phantom: PhantomData<S>,
} }
impl<O, S> Feedback<S> for NewHashFeedback<O, S> impl<O, S> StateInitializer<S> for NewHashFeedback<O>
where where
O: ObserverWithHashField + Named, S: HasNamedMetadata,
S: State + HasNamedMetadata,
{ {
fn init_state(&mut self, state: &mut S) -> Result<(), Error> { fn init_state(&mut self, state: &mut S) -> Result<(), Error> {
state.add_named_metadata( state.add_named_metadata(
@ -105,20 +111,23 @@ where
); );
Ok(()) Ok(())
} }
}
impl<O, EM, I, OT, S> Feedback<EM, I, OT, S> for NewHashFeedback<O>
where
O: ObserverWithHashField,
OT: MatchName,
S: HasNamedMetadata,
{
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
fn is_interesting<EM, OT>( fn is_interesting(
&mut self, &mut self,
state: &mut S, state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_input: &<S as UsesInput>::Input, _input: &I,
observers: &OT, observers: &OT,
_exit_kind: &ExitKind, _exit_kind: &ExitKind,
) -> Result<bool, Error> ) -> Result<bool, Error> {
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S::Input, S>,
{
let observer = observers let observer = observers
.get(&self.o_ref) .get(&self.o_ref)
.expect("A NewHashFeedback needs a BacktraceObserver"); .expect("A NewHashFeedback needs a BacktraceObserver");
@ -147,14 +156,14 @@ where
} }
} }
impl<O, S> Named for NewHashFeedback<O, S> { impl<O> Named for NewHashFeedback<O> {
#[inline] #[inline]
fn name(&self) -> &Cow<'static, str> { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
impl<O, S> HasObserverHandle for NewHashFeedback<O, S> { impl<O> HasObserverHandle for NewHashFeedback<O> {
type Observer = O; type Observer = O;
#[inline] #[inline]
@ -169,9 +178,9 @@ impl<O, S> HasObserverHandle for NewHashFeedback<O, S> {
/// runs of the target, producing many different feedbacks. /// runs of the target, producing many different feedbacks.
const DEFAULT_CAPACITY: usize = 4096; const DEFAULT_CAPACITY: usize = 4096;
impl<O, S> NewHashFeedback<O, S> impl<O> NewHashFeedback<O>
where where
O: ObserverWithHashField + Named, O: Named,
{ {
/// Returns a new [`NewHashFeedback`]. /// Returns a new [`NewHashFeedback`].
#[must_use] #[must_use]
@ -189,7 +198,6 @@ where
capacity, capacity,
#[cfg(feature = "track_hit_feedbacks")] #[cfg(feature = "track_hit_feedbacks")]
last_result: None, last_result: None,
phantom: PhantomData,
} }
} }
} }

View File

@ -4,18 +4,15 @@ use alloc::{borrow::Cow, string::String};
use libafl_bolts::{ use libafl_bolts::{
impl_serdeany, impl_serdeany,
tuples::{Handle, Handled, MatchNameRef}, tuples::{Handle, Handled, MatchName, MatchNameRef},
Named, Named,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
corpus::Testcase, corpus::Testcase,
events::EventFirer, feedbacks::{Feedback, StateInitializer},
executors::ExitKind, observers::{StdErrObserver, StdOutObserver},
feedbacks::Feedback,
observers::{ObserversTuple, StdErrObserver, StdOutObserver},
state::State,
Error, HasMetadata, Error, HasMetadata,
}; };
@ -35,40 +32,26 @@ pub struct StdOutToMetadataFeedback {
o_ref: Handle<StdOutObserver>, o_ref: Handle<StdOutObserver>,
} }
impl<S> Feedback<S> for StdOutToMetadataFeedback impl<S> StateInitializer<S> for StdOutToMetadataFeedback {}
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for StdOutToMetadataFeedback
where where
S: State, OT: MatchName,
{ {
#[allow(clippy::wrong_self_convention)] #[cfg(feature = "track_hit_feedbacks")]
#[inline] fn last_result(&self) -> Result<bool, Error> {
fn is_interesting<EM, OT>(
&mut self,
_state: &mut S,
_manager: &mut EM,
_input: &S::Input,
_observers: &OT,
_exit_kind: &ExitKind,
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S::Input, S>,
{
Ok(false) Ok(false)
} }
/// Append to the testcase the generated metadata in case of a new corpus item. /// Append to the testcase the generated metadata in case of a new corpus item.
#[inline] #[inline]
fn append_metadata<EM, OT>( fn append_metadata(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
_manager: &mut EM, _manager: &mut EM,
observers: &OT, observers: &OT,
testcase: &mut Testcase<S::Input>, testcase: &mut Testcase<I>,
) -> Result<(), Error> ) -> Result<(), Error> {
where
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
let observer = observers let observer = observers
.get(&self.o_ref) .get(&self.o_ref)
.ok_or(Error::illegal_state("StdOutObserver is missing"))?; .ok_or(Error::illegal_state("StdOutObserver is missing"))?;
@ -84,17 +67,6 @@ where
Ok(()) Ok(())
} }
/// Discard the stored metadata in case that the testcase is not added to the corpus.
#[inline]
fn discard_metadata(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
Ok(())
}
#[cfg(feature = "track_hit_feedbacks")]
fn last_result(&self) -> Result<bool, Error> {
Ok(false)
}
} }
impl Named for StdOutToMetadataFeedback { impl Named for StdOutToMetadataFeedback {
@ -130,40 +102,26 @@ pub struct StdErrToMetadataFeedback {
o_ref: Handle<StdErrObserver>, o_ref: Handle<StdErrObserver>,
} }
impl<S> Feedback<S> for StdErrToMetadataFeedback impl<S> StateInitializer<S> for StdErrToMetadataFeedback {}
impl<EM, I, OT, S> Feedback<EM, I, OT, S> for StdErrToMetadataFeedback
where where
S: State, OT: MatchName,
{ {
#[allow(clippy::wrong_self_convention)] #[cfg(feature = "track_hit_feedbacks")]
#[inline] fn last_result(&self) -> Result<bool, Error> {
fn is_interesting<EM, OT>(
&mut self,
_state: &mut S,
_manager: &mut EM,
_input: &S::Input,
_observers: &OT,
_exit_kind: &ExitKind,
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S::Input, S>,
{
Ok(false) Ok(false)
} }
/// Append to the testcase the generated metadata in case of a new corpus item. /// Append to the testcase the generated metadata in case of a new corpus item.
#[inline] #[inline]
fn append_metadata<EM, OT>( fn append_metadata(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
_manager: &mut EM, _manager: &mut EM,
observers: &OT, observers: &OT,
testcase: &mut Testcase<S::Input>, testcase: &mut Testcase<I>,
) -> Result<(), Error> ) -> Result<(), Error> {
where
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
let observer = observers let observer = observers
.get(&self.o_ref) .get(&self.o_ref)
.ok_or(Error::illegal_state("StdErrObserver is missing"))?; .ok_or(Error::illegal_state("StdErrObserver is missing"))?;
@ -179,16 +137,6 @@ where
Ok(()) Ok(())
} }
/// Discard the stored metadata in case that the testcase is not added to the corpus.
#[inline]
fn discard_metadata(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
Ok(())
}
#[cfg(feature = "track_hit_feedbacks")]
fn last_result(&self) -> Result<bool, Error> {
Ok(false)
}
} }
impl Named for StdErrToMetadataFeedback { impl Named for StdErrToMetadataFeedback {

View File

@ -9,17 +9,18 @@ use serde::{Deserialize, Serialize};
#[cfg(feature = "track_hit_feedbacks")] #[cfg(feature = "track_hit_feedbacks")]
use crate::feedbacks::premature_last_result_err; use crate::feedbacks::premature_last_result_err;
use crate::{ use crate::{
events::EventFirer, executors::ExitKind, feedbacks::Feedback, observers::ObserversTuple, executors::ExitKind,
state::State, HasMetadata, feedbacks::{Feedback, StateInitializer},
HasMetadata,
}; };
/// Constant name of the [`TransferringMetadata`]. /// Constant name of the [`TransferringMetadata`].
pub const TRANSFERRED_FEEDBACK_NAME: Cow<'static, str> = pub const TRANSFERRED_FEEDBACK_NAME: Cow<'static, str> =
Cow::Borrowed("transferred_feedback_internal"); Cow::Borrowed("transferred_feedback_internal");
/// Metadata which denotes whether we are currently transferring an input. /// Metadata which denotes whether we are currently transferring an input.
/// ///
/// Implementors of /// Implementors of multi-node communication systems (like [`crate::events::LlmpEventManager`]) should wrap any
/// multi-node communication systems (like [`crate::events::LlmpEventManager`]) should wrap any
/// [`crate::EvaluatorObservers::evaluate_input_with_observers`] or /// [`crate::EvaluatorObservers::evaluate_input_with_observers`] or
/// [`crate::ExecutionProcessor::process_execution`] calls with setting this metadata to true/false /// [`crate::ExecutionProcessor::process_execution`] calls with setting this metadata to true/false
/// before and after. /// before and after.
@ -52,27 +53,28 @@ impl Named for TransferredFeedback {
} }
} }
impl<S> Feedback<S> for TransferredFeedback impl<S> StateInitializer<S> for TransferredFeedback
where where
S: HasMetadata + State, S: HasMetadata,
{ {
fn init_state(&mut self, state: &mut S) -> Result<(), Error> { fn init_state(&mut self, state: &mut S) -> Result<(), Error> {
state.add_metadata(TransferringMetadata { transferring: true }); state.add_metadata(TransferringMetadata { transferring: true });
Ok(()) Ok(())
} }
}
fn is_interesting<EM, OT>( impl<EM, I, OT, S> Feedback<EM, I, OT, S> for TransferredFeedback
where
S: HasMetadata,
{
fn is_interesting(
&mut self, &mut self,
state: &mut S, state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_input: &S::Input, _input: &I,
_observers: &OT, _observers: &OT,
_exit_kind: &ExitKind, _exit_kind: &ExitKind,
) -> Result<bool, Error> ) -> Result<bool, Error> {
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S::Input, S>,
{
let res = state.metadata::<TransferringMetadata>()?.transferring; let res = state.metadata::<TransferringMetadata>()?.transferring;
#[cfg(feature = "track_hit_feedbacks")] #[cfg(feature = "track_hit_feedbacks")]
{ {
@ -80,6 +82,7 @@ where
} }
Ok(res) Ok(res)
} }
#[cfg(feature = "track_hit_feedbacks")] #[cfg(feature = "track_hit_feedbacks")]
fn last_result(&self) -> Result<bool, Error> { fn last_result(&self) -> Result<bool, Error> {
self.last_result.ok_or(premature_last_result_err()) self.last_result.ok_or(premature_last_result_err())

View File

@ -47,7 +47,7 @@ where
/// Holds an feedback /// Holds an feedback
pub trait HasFeedback: UsesState { pub trait HasFeedback: UsesState {
/// The feedback type /// The feedback type
type Feedback: Feedback<Self::State>; type Feedback;
/// The feedback /// The feedback
fn feedback(&self) -> &Self::Feedback; fn feedback(&self) -> &Self::Feedback;
@ -59,7 +59,7 @@ pub trait HasFeedback: UsesState {
/// Holds an objective feedback /// Holds an objective feedback
pub trait HasObjective: UsesState { pub trait HasObjective: UsesState {
/// The type of the [`Feedback`] used to find objectives for this fuzzer /// The type of the [`Feedback`] used to find objectives for this fuzzer
type Objective: Feedback<Self::State>; type Objective;
/// The objective feedback /// The objective feedback
fn objective(&self) -> &Self::Objective; fn objective(&self) -> &Self::Objective;
@ -69,9 +69,9 @@ pub trait HasObjective: UsesState {
} }
/// Evaluates if an input is interesting using the feedback /// Evaluates if an input is interesting using the feedback
pub trait ExecutionProcessor: UsesState { pub trait ExecutionProcessor<EM, OT>: UsesState {
/// Check the outcome of the execution, find if it is worth for corpus or objectives /// Check the outcome of the execution, find if it is worth for corpus or objectives
fn check_results<EM, OT>( fn check_results(
&mut self, &mut self,
state: &mut Self::State, state: &mut Self::State,
manager: &mut EM, manager: &mut EM,
@ -85,7 +85,7 @@ pub trait ExecutionProcessor: UsesState {
/// Process `ExecuteInputResult`. Add to corpus, solution or ignore /// Process `ExecuteInputResult`. Add to corpus, solution or ignore
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn process_execution<EM, OT>( fn process_execution(
&mut self, &mut self,
state: &mut Self::State, state: &mut Self::State,
manager: &mut EM, manager: &mut EM,
@ -98,7 +98,7 @@ pub trait ExecutionProcessor: UsesState {
OT: ObserversTuple<<Self as UsesInput>::Input, Self::State>; OT: ObserversTuple<<Self as UsesInput>::Input, Self::State>;
/// serialize and send event via manager /// serialize and send event via manager
fn serialize_and_dispatch<EM, OT>( fn serialize_and_dispatch(
&mut self, &mut self,
state: &mut Self::State, state: &mut Self::State,
manager: &mut EM, manager: &mut EM,
@ -112,7 +112,7 @@ pub trait ExecutionProcessor: UsesState {
OT: ObserversTuple<<Self as UsesInput>::Input, Self::State> + Serialize; OT: ObserversTuple<<Self as UsesInput>::Input, Self::State> + Serialize;
/// send event via manager /// send event via manager
fn dispatch_event<EM>( fn dispatch_event(
&mut self, &mut self,
state: &mut Self::State, state: &mut Self::State,
manager: &mut EM, manager: &mut EM,
@ -125,7 +125,7 @@ pub trait ExecutionProcessor: UsesState {
EM: EventFirer<State = Self::State>; EM: EventFirer<State = Self::State>;
/// Evaluate if a set of observation channels has an interesting state /// Evaluate if a set of observation channels has an interesting state
fn evaluate_execution<EM, OT>( fn evaluate_execution(
&mut self, &mut self,
state: &mut Self::State, state: &mut Self::State,
manager: &mut EM, manager: &mut EM,
@ -140,11 +140,11 @@ pub trait ExecutionProcessor: UsesState {
} }
/// Evaluates an input modifying the state of the fuzzer /// Evaluates an input modifying the state of the fuzzer
pub trait EvaluatorObservers<OT>: UsesState + Sized { pub trait EvaluatorObservers<EM, OT>: UsesState + Sized {
/// Runs the input and triggers observers and feedback, /// Runs the input and triggers observers and feedback,
/// returns if is interesting an (option) the index of the new /// returns if is interesting an (option) the index of the new
/// [`crate::corpus::Testcase`] in the [`crate::corpus::Corpus`] /// [`crate::corpus::Testcase`] in the [`crate::corpus::Corpus`]
fn evaluate_input_with_observers<E, EM>( fn evaluate_input_with_observers<E>(
&mut self, &mut self,
state: &mut Self::State, state: &mut Self::State,
executor: &mut E, executor: &mut E,
@ -336,8 +336,6 @@ where
impl<CS, F, OF, S> HasFeedback for StdFuzzer<CS, F, OF, S> impl<CS, F, OF, S> HasFeedback for StdFuzzer<CS, F, OF, S>
where where
S: State, S: State,
F: Feedback<S>,
OF: Feedback<S>,
{ {
type Feedback = F; type Feedback = F;
@ -353,8 +351,6 @@ where
impl<CS, F, OF, S> HasObjective for StdFuzzer<CS, F, OF, S> impl<CS, F, OF, S> HasObjective for StdFuzzer<CS, F, OF, S>
where where
S: State, S: State,
F: Feedback<S>,
OF: Feedback<S>,
{ {
type Objective = OF; type Objective = OF;
@ -367,16 +363,16 @@ where
} }
} }
impl<CS, F, OF, S> ExecutionProcessor for StdFuzzer<CS, F, OF, S> impl<CS, EM, F, OF, OT, S> ExecutionProcessor<EM, OT> for StdFuzzer<CS, F, OF, S>
where where
CS: Scheduler<S::Input, S>, CS: Scheduler<S::Input, S>,
F: Feedback<S>, F: Feedback<EM, S::Input, OT, S>,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: HasCorpus + HasSolutions + HasExecutions + HasCorpus + HasCurrentCorpusId + State, S: HasCorpus + HasSolutions + HasExecutions + HasCorpus + HasCurrentCorpusId + State,
S::Corpus: Corpus<Input = S::Input>, //delete me S::Corpus: Corpus<Input = S::Input>, //delete me
S::Solutions: Corpus<Input = S::Input>, //delete me S::Solutions: Corpus<Input = S::Input>, //delete me
{ {
fn check_results<EM, OT>( fn check_results(
&mut self, &mut self,
state: &mut S, state: &mut S,
manager: &mut EM, manager: &mut EM,
@ -420,7 +416,7 @@ where
Ok(res) Ok(res)
} }
fn evaluate_execution<EM, OT>( fn evaluate_execution(
&mut self, &mut self,
state: &mut Self::State, state: &mut Self::State,
manager: &mut EM, manager: &mut EM,
@ -441,7 +437,7 @@ where
Ok((exec_res, corpus_id)) Ok((exec_res, corpus_id))
} }
fn serialize_and_dispatch<EM, OT>( fn serialize_and_dispatch(
&mut self, &mut self,
state: &mut Self::State, state: &mut Self::State,
manager: &mut EM, manager: &mut EM,
@ -475,7 +471,7 @@ where
Ok(()) Ok(())
} }
fn dispatch_event<EM>( fn dispatch_event(
&mut self, &mut self,
state: &mut Self::State, state: &mut Self::State,
manager: &mut EM, manager: &mut EM,
@ -527,7 +523,7 @@ where
} }
/// Evaluate if a set of observation channels has an interesting state /// Evaluate if a set of observation channels has an interesting state
fn process_execution<EM, OT>( fn process_execution(
&mut self, &mut self,
state: &mut Self::State, state: &mut Self::State,
manager: &mut EM, manager: &mut EM,
@ -585,19 +581,19 @@ where
} }
} }
impl<CS, F, OF, OT, S> EvaluatorObservers<OT> for StdFuzzer<CS, F, OF, S> impl<CS, EM, F, OF, OT, S> EvaluatorObservers<EM, OT> for StdFuzzer<CS, F, OF, S>
where where
CS: Scheduler<S::Input, S>, CS: Scheduler<S::Input, S>,
OT: ObserversTuple<S::Input, S> + Serialize + DeserializeOwned, OT: ObserversTuple<S::Input, S> + Serialize + DeserializeOwned,
F: Feedback<S>, F: Feedback<EM, S::Input, OT, S>,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: HasCorpus + HasSolutions + HasExecutions + State, S: HasCorpus + HasSolutions + HasExecutions + State,
S::Corpus: Corpus<Input = S::Input>, //delete me S::Corpus: Corpus<Input = S::Input>, //delete me
S::Solutions: Corpus<Input = S::Input>, //delete me S::Solutions: Corpus<Input = S::Input>, //delete me
{ {
/// Process one input, adding to the respective corpora if needed and firing the right events /// Process one input, adding to the respective corpora if needed and firing the right events
#[inline] #[inline]
fn evaluate_input_with_observers<E, EM>( fn evaluate_input_with_observers<E>(
&mut self, &mut self,
state: &mut S, state: &mut S,
executor: &mut E, executor: &mut E,
@ -624,8 +620,8 @@ where
E: HasObservers + Executor<EM, Self, State = S>, E: HasObservers + Executor<EM, Self, State = S>,
E::Observers: ObserversTuple<S::Input, S> + Serialize + DeserializeOwned, E::Observers: ObserversTuple<S::Input, S> + Serialize + DeserializeOwned,
EM: EventFirer<State = S>, EM: EventFirer<State = S>,
F: Feedback<S>, F: Feedback<EM, S::Input, E::Observers, S>,
OF: Feedback<S>, OF: Feedback<EM, S::Input, E::Observers, S>,
S: HasCorpus + HasSolutions + HasExecutions + HasLastFoundTime + State, S: HasCorpus + HasSolutions + HasExecutions + HasLastFoundTime + State,
S::Corpus: Corpus<Input = S::Input>, //delete me S::Corpus: Corpus<Input = S::Input>, //delete me
S::Solutions: Corpus<Input = S::Input>, //delete me S::Solutions: Corpus<Input = S::Input>, //delete me
@ -760,8 +756,6 @@ where
CS: Scheduler<S::Input, S>, CS: Scheduler<S::Input, S>,
E: UsesState<State = S>, E: UsesState<State = S>,
EM: ProgressReporter + EventProcessor<E, Self, State = S>, EM: ProgressReporter + EventProcessor<E, Self, State = S>,
F: Feedback<S>,
OF: Feedback<S>,
S: HasExecutions S: HasExecutions
+ HasMetadata + HasMetadata
+ HasCorpus + HasCorpus
@ -837,8 +831,6 @@ where
impl<CS, F, OF, S> StdFuzzer<CS, F, OF, S> impl<CS, F, OF, S> StdFuzzer<CS, F, OF, S>
where where
CS: Scheduler<S::Input, S>, CS: Scheduler<S::Input, S>,
F: Feedback<<Self as UsesState>::State>,
OF: Feedback<<Self as UsesState>::State>,
S: UsesInput + HasExecutions + HasCorpus + State, S: UsesInput + HasExecutions + HasCorpus + State,
{ {
/// Create a new `StdFuzzer` with standard behavior. /// Create a new `StdFuzzer` with standard behavior.
@ -901,8 +893,6 @@ where
impl<CS, E, EM, F, OF, S> ExecutesInput<E, EM> for StdFuzzer<CS, F, OF, S> impl<CS, E, EM, F, OF, S> ExecutesInput<E, EM> for StdFuzzer<CS, F, OF, S>
where where
CS: Scheduler<S::Input, S>, CS: Scheduler<S::Input, S>,
F: Feedback<<Self as UsesState>::State>,
OF: Feedback<<Self as UsesState>::State>,
E: Executor<EM, Self, State = S> + HasObservers, E: Executor<EM, Self, State = S> + HasObservers,
E::Observers: ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State>, E::Observers: ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State>,
EM: UsesState<State = Self::State>, EM: UsesState<State = Self::State>,

View File

@ -48,7 +48,7 @@ pub use owned_map::*;
/// ``` /// ```
/// # use libafl::corpus::InMemoryCorpus; /// # use libafl::corpus::InMemoryCorpus;
/// # use libafl::feedbacks::{Feedback, MapFeedbackMetadata}; /// # use libafl::feedbacks::{Feedback, MapFeedbackMetadata};
/// use libafl::feedbacks::MaxMapFeedback; /// use libafl::feedbacks::{MaxMapFeedback, StateInitializer};
/// # use libafl::inputs::BytesInput; /// # use libafl::inputs::BytesInput;
/// use libafl::observers::{StdMapObserver, CanTrack}; /// use libafl::observers::{StdMapObserver, CanTrack};
/// use libafl::schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}; /// use libafl::schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler};

View File

@ -27,7 +27,7 @@ use crate::{observers::Observer, Error};
/// corpus::{Corpus, InMemoryCorpus, Testcase}, /// corpus::{Corpus, InMemoryCorpus, Testcase},
/// events::{EventFirer, NopEventManager}, /// events::{EventFirer, NopEventManager},
/// executors::{CommandExecutor, ExitKind}, /// executors::{CommandExecutor, ExitKind},
/// feedbacks::Feedback, /// feedbacks::{Feedback, StateInitializer},
/// inputs::{BytesInput, UsesInput}, /// inputs::{BytesInput, UsesInput},
/// mutators::{MutationResult, NopMutator}, /// mutators::{MutationResult, NopMutator},
/// observers::{ObserversTuple, StdErrObserver, StdOutObserver}, /// observers::{ObserversTuple, StdErrObserver, StdOutObserver},
@ -53,21 +53,22 @@ use crate::{observers::Observer, Error};
/// stderr_observer: Handle<StdErrObserver>, /// stderr_observer: Handle<StdErrObserver>,
/// } /// }
/// ///
/// impl<S> Feedback<S> for ExportStdXObserver /// impl<S> StateInitializer<S> for ExportStdXObserver {}
///
///
/// impl<EM, I, OT, S> Feedback<EM, I, OT, S> for ExportStdXObserver
/// where /// where
/// S: State /// S: State,
/// OT: MatchNameRef
/// { /// {
/// fn is_interesting<EM, OT>( /// fn is_interesting(
/// &mut self, /// &mut self,
/// _state: &mut S, /// _state: &mut S,
/// _manager: &mut EM, /// _manager: &mut EM,
/// _input: &<S>::Input, /// _input: &I,
/// observers: &OT, /// observers: &OT,
/// _exit_kind: &ExitKind, /// _exit_kind: &ExitKind,
/// ) -> Result<bool, Error> /// ) -> Result<bool, Error>
/// where
/// EM: EventFirer<State = S>,
/// OT: ObserversTuple<S::Input, S>,
/// { /// {
/// unsafe { /// unsafe {
/// STDOUT = observers.get(&self.stdout_observer).unwrap().stdout.clone(); /// STDOUT = observers.get(&self.stdout_observer).unwrap().stdout.clone();

View File

@ -447,8 +447,8 @@ where
OT: ObserversTuple<Self::Input, Self::State>, OT: ObserversTuple<Self::Input, Self::State>,
PS: PushStage<CS, EM, OT, Z>, PS: PushStage<CS, EM, OT, Z>,
Z: ExecutesInput<E, EM> Z: ExecutesInput<E, EM>
+ ExecutionProcessor + ExecutionProcessor<EM, OT>
+ EvaluatorObservers<OT> + EvaluatorObservers<EM, OT>
+ HasScheduler<Scheduler = CS>, + HasScheduler<Scheduler = CS>,
{ {
fn perform( fn perform(

View File

@ -40,7 +40,7 @@ where
EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId, EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId,
OT: ObserversTuple<Z::Input, Z::State>, OT: ObserversTuple<Z::Input, Z::State>,
Z::State: HasRand + HasCorpus, Z::State: HasRand + HasCorpus,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>, Z: ExecutionProcessor<EM, OT> + EvaluatorObservers<EM, OT> + HasScheduler<Scheduler = CS>,
{ {
/// The [`crate::state::State`] /// The [`crate::state::State`]
pub state: Z::State, pub state: Z::State,
@ -59,7 +59,7 @@ where
EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId, EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId,
OT: ObserversTuple<Z::Input, Z::State>, OT: ObserversTuple<Z::Input, Z::State>,
Z::State: HasRand + HasCorpus, Z::State: HasRand + HasCorpus,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>, Z: ExecutionProcessor<EM, OT> + EvaluatorObservers<EM, OT> + HasScheduler<Scheduler = CS>,
{ {
/// Create a new `PushStageSharedState` that can be used by all [`PushStage`]s /// Create a new `PushStageSharedState` that can be used by all [`PushStage`]s
#[must_use] #[must_use]
@ -82,7 +82,7 @@ where
EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId, EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId,
OT: ObserversTuple<Z::Input, Z::State>, OT: ObserversTuple<Z::Input, Z::State>,
Z::State: HasRand + HasCorpus, Z::State: HasRand + HasCorpus,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>, Z: ExecutionProcessor<EM, OT> + EvaluatorObservers<EM, OT> + HasScheduler<Scheduler = CS>,
{ {
/// If this stage has already been initalized. /// If this stage has already been initalized.
/// This gets reset to `false` after one iteration of the stage is done. /// This gets reset to `false` after one iteration of the stage is done.
@ -110,7 +110,7 @@ where
EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId, EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId,
OT: ObserversTuple<Z::Input, Z::State>, OT: ObserversTuple<Z::Input, Z::State>,
Z::State: HasRand + HasCorpus, Z::State: HasRand + HasCorpus,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>, Z: ExecutionProcessor<EM, OT> + EvaluatorObservers<EM, OT> + HasScheduler<Scheduler = CS>,
{ {
/// Create a new [`PushStageHelper`] /// Create a new [`PushStageHelper`]
#[must_use] #[must_use]
@ -177,7 +177,7 @@ where
Z::State: HasRand + HasExecutions + HasMetadata + HasCorpus + HasLastReportTime, Z::State: HasRand + HasExecutions + HasMetadata + HasCorpus + HasLastReportTime,
EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId + ProgressReporter, EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId + ProgressReporter,
OT: ObserversTuple<Z::Input, Z::State>, OT: ObserversTuple<Z::Input, Z::State>,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>, Z: ExecutionProcessor<EM, OT> + EvaluatorObservers<EM, OT> + HasScheduler<Scheduler = CS>,
{ {
/// Gets the [`PushStageHelper`] /// Gets the [`PushStageHelper`]
fn push_stage_helper(&self) -> &PushStageHelper<CS, EM, OT, Z>; fn push_stage_helper(&self) -> &PushStageHelper<CS, EM, OT, Z>;

View File

@ -48,7 +48,7 @@ where
M: Mutator<Z::Input, Z::State>, M: Mutator<Z::Input, Z::State>,
OT: ObserversTuple<Z::Input, Z::State> + Serialize, OT: ObserversTuple<Z::Input, Z::State> + Serialize,
Z::State: HasRand + HasCorpus + Clone + Debug, Z::State: HasRand + HasCorpus + Clone + Debug,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>, Z: ExecutionProcessor<EM, OT> + EvaluatorObservers<EM, OT> + HasScheduler<Scheduler = CS>,
{ {
current_corpus_id: Option<CorpusId>, current_corpus_id: Option<CorpusId>,
testcases_to_do: usize, testcases_to_do: usize,
@ -66,7 +66,7 @@ where
M: Mutator<Z::Input, Z::State>, M: Mutator<Z::Input, Z::State>,
OT: ObserversTuple<Z::Input, Z::State> + Serialize, OT: ObserversTuple<Z::Input, Z::State> + Serialize,
Z::State: HasCorpus + HasRand + Clone + Debug, Z::State: HasCorpus + HasRand + Clone + Debug,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>, Z: ExecutionProcessor<EM, OT> + EvaluatorObservers<EM, OT> + HasScheduler<Scheduler = CS>,
{ {
/// Gets the number of iterations as a random number /// Gets the number of iterations as a random number
#[allow(clippy::unused_self, clippy::unnecessary_wraps)] // TODO: we should put this function into a trait later #[allow(clippy::unused_self, clippy::unnecessary_wraps)] // TODO: we should put this function into a trait later
@ -87,7 +87,7 @@ where
M: Mutator<Z::Input, Z::State>, M: Mutator<Z::Input, Z::State>,
OT: ObserversTuple<Z::Input, Z::State> + Serialize, OT: ObserversTuple<Z::Input, Z::State> + Serialize,
Z::State: HasCorpus + HasRand + HasExecutions + HasLastReportTime + HasMetadata + Clone + Debug, Z::State: HasCorpus + HasRand + HasExecutions + HasLastReportTime + HasMetadata + Clone + Debug,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>, Z: ExecutionProcessor<EM, OT> + EvaluatorObservers<EM, OT> + HasScheduler<Scheduler = CS>,
<<Z as UsesState>::State as HasCorpus>::Corpus: Corpus<Input = Z::Input>, //delete me <<Z as UsesState>::State as HasCorpus>::Corpus: Corpus<Input = Z::Input>, //delete me
{ {
#[inline] #[inline]
@ -196,7 +196,7 @@ where
M: Mutator<Z::Input, Z::State>, M: Mutator<Z::Input, Z::State>,
OT: ObserversTuple<Z::Input, Z::State> + Serialize, OT: ObserversTuple<Z::Input, Z::State> + Serialize,
Z::State: HasCorpus + HasRand + HasExecutions + HasMetadata + HasLastReportTime + Clone + Debug, Z::State: HasCorpus + HasRand + HasExecutions + HasMetadata + HasLastReportTime + Clone + Debug,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>, Z: ExecutionProcessor<EM, OT> + EvaluatorObservers<EM, OT> + HasScheduler<Scheduler = CS>,
<<Z as UsesState>::State as HasCorpus>::Corpus: Corpus<Input = Z::Input>, //delete me <<Z as UsesState>::State as HasCorpus>::Corpus: Corpus<Input = Z::Input>, //delete me
{ {
type Item = Result<<Z::State as UsesInput>::Input, Error>; type Item = Result<<Z::State as UsesInput>::Input, Error>;
@ -213,7 +213,7 @@ where
M: Mutator<Z::Input, Z::State>, M: Mutator<Z::Input, Z::State>,
OT: ObserversTuple<Z::Input, Z::State> + Serialize, OT: ObserversTuple<Z::Input, Z::State> + Serialize,
Z::State: HasCorpus + HasRand + Clone + Debug, Z::State: HasCorpus + HasRand + Clone + Debug,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>, Z: ExecutionProcessor<EM, OT> + EvaluatorObservers<EM, OT> + HasScheduler<Scheduler = CS>,
{ {
/// Creates a new default mutational stage /// Creates a new default mutational stage
#[must_use] #[must_use]

View File

@ -253,7 +253,8 @@ where
SP: ShMemProvider, SP: ShMemProvider,
E: HasObservers + Executor<EM, Z, State = S>, E: HasObservers + Executor<EM, Z, State = S>,
for<'a> E::Observers: Deserialize<'a>, for<'a> E::Observers: Deserialize<'a>,
Z: EvaluatorObservers<E::Observers, State = S> + ExecutionProcessor<State = S>, Z: EvaluatorObservers<EM, E::Observers, State = S>
+ ExecutionProcessor<EM, E::Observers, State = S>,
IC: InputConverter<From = S::Input, To = DI>, IC: InputConverter<From = S::Input, To = DI>,
ICB: InputConverter<From = DI, To = S::Input>, ICB: InputConverter<From = DI, To = S::Input>,
DI: Input, DI: Input,

View File

@ -8,7 +8,7 @@ use core::{borrow::BorrowMut, fmt::Debug, hash::Hash, marker::PhantomData};
use ahash::RandomState; use ahash::RandomState;
use libafl_bolts::{ use libafl_bolts::{
tuples::{Handle, Handled, MatchNameRef}, tuples::{Handle, Handled, MatchName, MatchNameRef},
HasLen, Named, HasLen, Named,
}; };
use serde::Serialize; use serde::Serialize;
@ -19,7 +19,7 @@ use crate::{
corpus::{Corpus, HasCurrentCorpusId, Testcase}, corpus::{Corpus, HasCurrentCorpusId, Testcase},
events::EventFirer, events::EventFirer,
executors::{ExitKind, HasObservers}, executors::{ExitKind, HasObservers},
feedbacks::{Feedback, FeedbackFactory, HasObserverHandle}, feedbacks::{Feedback, FeedbackFactory, HasObserverHandle, StateInitializer},
inputs::UsesInput, inputs::UsesInput,
mark_feature_time, mark_feature_time,
mutators::{MutationResult, Mutator}, mutators::{MutationResult, Mutator},
@ -47,7 +47,7 @@ where
E: UsesState<State = Self::State> + HasObservers, E: UsesState<State = Self::State> + HasObservers,
E::Observers: ObserversTuple<Self::Input, Self::State> + Serialize, E::Observers: ObserversTuple<Self::Input, Self::State> + Serialize,
EM: UsesState<State = Self::State> + EventFirer, EM: UsesState<State = Self::State> + EventFirer,
F: Feedback<Self::State>, F: Feedback<EM, Self::Input, E::Observers, Self::State>,
Self::State: HasMaxSize + HasCorpus + HasSolutions + HasExecutions + HasCurrentTestcase, Self::State: HasMaxSize + HasCorpus + HasSolutions + HasExecutions + HasCurrentTestcase,
Self::Input: MutatedTransform<Self::Input, Self::State, Post = IP> + Clone + Hash + HasLen, Self::Input: MutatedTransform<Self::Input, Self::State, Post = IP> + Clone + Hash + HasLen,
IP: Clone + MutatedTransformPost<Self::State>, IP: Clone + MutatedTransformPost<Self::State>,
@ -56,7 +56,8 @@ where
+ HasScheduler + HasScheduler
+ HasFeedback + HasFeedback
+ ExecutesInput<E, EM> + ExecutesInput<E, EM>
+ ExecutionProcessor, + ExecutionProcessor<EM, E::Observers>,
Z::Feedback: Feedback<EM, Self::Input, E::Observers, Self::State>,
Z::Scheduler: RemovableScheduler<Self::Input, Self::State>, Z::Scheduler: RemovableScheduler<Self::Input, Self::State>,
<<Self as UsesState>::State as HasCorpus>::Corpus: Corpus<Input = Self::Input>, <<Self as UsesState>::State as HasCorpus>::Corpus: Corpus<Input = Self::Input>,
{ {
@ -239,16 +240,17 @@ where
impl<E, EM, F, FF, IP, M, Z> Stage<E, EM, Z> for StdTMinMutationalStage<E, EM, F, FF, IP, M, Z> impl<E, EM, F, FF, IP, M, Z> Stage<E, EM, Z> for StdTMinMutationalStage<E, EM, F, FF, IP, M, Z>
where where
Z: HasScheduler + ExecutionProcessor + ExecutesInput<E, EM> + HasFeedback, Z: HasScheduler + ExecutionProcessor<EM, E::Observers> + ExecutesInput<E, EM> + HasFeedback,
Z::Scheduler: RemovableScheduler<Self::Input, Self::State>, Z::Scheduler: RemovableScheduler<Self::Input, Self::State>,
E: HasObservers + UsesState<State = Z::State>, E: HasObservers + UsesState<State = Z::State>,
E::Observers: ObserversTuple<Self::Input, Self::State> + Serialize, E::Observers: ObserversTuple<Self::Input, Self::State> + Serialize,
EM: EventFirer<State = Self::State>, EM: EventFirer<State = Self::State>,
FF: FeedbackFactory<F, E::Observers>, FF: FeedbackFactory<F, E::Observers>,
F: Feedback<Self::State>, F: Feedback<EM, Self::Input, E::Observers, Self::State>,
Self::Input: MutatedTransform<Self::Input, Self::State, Post = IP> + Clone + HasLen + Hash, Self::Input: MutatedTransform<Self::Input, Self::State, Post = IP> + Clone + HasLen + Hash,
Z::State: Z::State:
HasMetadata + HasExecutions + HasSolutions + HasCorpus + HasMaxSize + HasNamedMetadata, HasMetadata + HasExecutions + HasSolutions + HasCorpus + HasMaxSize + HasNamedMetadata,
Z::Feedback: Feedback<EM, Self::Input, E::Observers, Self::State>,
M: Mutator<Self::Input, Self::State>, M: Mutator<Self::Input, Self::State>,
IP: MutatedTransformPost<Self::State> + Clone, IP: MutatedTransformPost<Self::State> + Clone,
<<Self as UsesState>::State as HasCorpus>::Corpus: Corpus<Input = Self::Input>, // delete me <<Self as UsesState>::State as HasCorpus>::Corpus: Corpus<Input = Self::Input>, // delete me
@ -302,13 +304,13 @@ pub static TMIN_STAGE_NAME: &str = "tmin";
impl<E, EM, F, FF, IP, M, Z> TMinMutationalStage<E, EM, F, IP, M, Z> impl<E, EM, F, FF, IP, M, Z> TMinMutationalStage<E, EM, F, IP, M, Z>
for StdTMinMutationalStage<E, EM, F, FF, IP, M, Z> for StdTMinMutationalStage<E, EM, F, FF, IP, M, Z>
where where
Z: HasScheduler + ExecutionProcessor + ExecutesInput<E, EM> + HasFeedback, Z: HasScheduler + ExecutionProcessor<EM, E::Observers> + ExecutesInput<E, EM> + HasFeedback,
Z::Scheduler: RemovableScheduler<Self::Input, Self::State>, Z::Scheduler: RemovableScheduler<Self::Input, Self::State>,
E: HasObservers + UsesState<State = Z::State>, E: HasObservers + UsesState<State = Z::State>,
E::Observers: ObserversTuple<Self::Input, Self::State> + Serialize, E::Observers: ObserversTuple<Self::Input, Self::State> + Serialize,
EM: EventFirer<State = Self::State>, EM: EventFirer<State = Self::State>,
FF: FeedbackFactory<F, E::Observers>, FF: FeedbackFactory<F, E::Observers>,
F: Feedback<Self::State>, F: Feedback<EM, Self::Input, E::Observers, Self::State>,
Self::Input: MutatedTransform<Self::Input, Self::State, Post = IP> + Clone + HasLen + Hash, Self::Input: MutatedTransform<Self::Input, Self::State, Post = IP> + Clone + HasLen + Hash,
Z::State: HasMetadata Z::State: HasMetadata
+ HasExecutions + HasExecutions
@ -317,6 +319,7 @@ where
+ HasMaxSize + HasMaxSize
+ HasNamedMetadata + HasNamedMetadata
+ HasCurrentTestcase, + HasCurrentTestcase,
Z::Feedback: Feedback<EM, Self::Input, E::Observers, Self::State>,
M: Mutator<Self::Input, Self::State>, M: Mutator<Self::Input, Self::State>,
IP: MutatedTransformPost<Self::State> + Clone, IP: MutatedTransformPost<Self::State> + Clone,
<<Self as UsesState>::State as HasCorpus>::Corpus: Corpus<Input = Self::Input>, // delete me <<Self as UsesState>::State as HasCorpus>::Corpus: Corpus<Input = Self::Input>, // delete me
@ -391,24 +394,23 @@ impl<C, M, S> HasObserverHandle for MapEqualityFeedback<C, M, S> {
} }
} }
impl<C, M, S> Feedback<S> for MapEqualityFeedback<C, M, S> impl<C, M, S> StateInitializer<S> for MapEqualityFeedback<C, M, S> {}
impl<C, EM, I, M, OT, S> Feedback<EM, I, OT, S> for MapEqualityFeedback<C, M, S>
where where
M: MapObserver, M: MapObserver,
C: AsRef<M>, C: AsRef<M>,
S: State, S: State,
OT: MatchName,
{ {
fn is_interesting<EM, OT>( fn is_interesting(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_input: &S::Input, _input: &I,
observers: &OT, observers: &OT,
_exit_kind: &ExitKind, _exit_kind: &ExitKind,
) -> Result<bool, Error> ) -> Result<bool, Error> {
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S::Input, S>,
{
let obs = observers let obs = observers
.get(self.observer_handle()) .get(self.observer_handle())
.expect("Should have been provided valid observer name."); .expect("Should have been provided valid observer name.");

View File

@ -33,7 +33,7 @@ use crate::monitors::ScalabilityMonitor;
use crate::{ use crate::{
corpus::{Corpus, CorpusId, HasCurrentCorpusId, HasTestcase, InMemoryCorpus, Testcase}, corpus::{Corpus, CorpusId, HasCurrentCorpusId, HasTestcase, InMemoryCorpus, Testcase},
events::{Event, EventFirer, LogSeverity}, events::{Event, EventFirer, LogSeverity},
feedbacks::Feedback, feedbacks::StateInitializer,
fuzzer::{Evaluator, ExecuteInputResult}, fuzzer::{Evaluator, ExecuteInputResult},
generators::Generator, generators::Generator,
inputs::{Input, NopInput, UsesInput}, inputs::{Input, NopInput, UsesInput},
@ -1161,8 +1161,8 @@ where
objective: &mut O, objective: &mut O,
) -> Result<Self, Error> ) -> Result<Self, Error>
where where
F: Feedback<Self>, F: StateInitializer<Self>,
O: Feedback<Self>, O: StateInitializer<Self>,
C: Serialize + DeserializeOwned, C: Serialize + DeserializeOwned,
SC: Serialize + DeserializeOwned, SC: Serialize + DeserializeOwned,
{ {

View File

@ -14,11 +14,10 @@ use frida_gum::interceptor::Interceptor;
use frida_gum::ModuleDetails; use frida_gum::ModuleDetails;
use libafl::{ use libafl::{
corpus::Testcase, corpus::Testcase,
events::EventFirer,
executors::ExitKind, executors::ExitKind,
feedbacks::Feedback, feedbacks::{Feedback, StateInitializer},
inputs::HasTargetBytes, inputs::HasTargetBytes,
observers::{Observer, ObserversTuple}, observers::Observer,
state::State, state::State,
Error, HasMetadata, Error, HasMetadata,
}; };
@ -647,24 +646,23 @@ pub struct AsanErrorsFeedback<S> {
phantom: PhantomData<S>, phantom: PhantomData<S>,
} }
impl<S> Feedback<S> for AsanErrorsFeedback<S> impl<S> StateInitializer<S> for AsanErrorsFeedback<S> {}
impl<EM, OT, S> Feedback<EM, S::Input, OT, S> for AsanErrorsFeedback<S>
where where
S: State + Debug, S: State + Debug,
S::Input: HasTargetBytes, S::Input: HasTargetBytes,
OT: MatchNameRef,
{ {
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
fn is_interesting<EM, OT>( fn is_interesting(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_input: &S::Input, _input: &S::Input,
observers: &OT, observers: &OT,
_exit_kind: &ExitKind, _exit_kind: &ExitKind,
) -> Result<bool, Error> ) -> Result<bool, Error> {
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S::Input, S>,
{
let observer = observers let observer = observers
.get(&self.observer_handle) .get(&self.observer_handle)
.expect("An AsanErrorsFeedback needs an AsanErrorsObserver"); .expect("An AsanErrorsFeedback needs an AsanErrorsObserver");
@ -677,16 +675,13 @@ where
} }
} }
fn append_metadata<EM, OT>( fn append_metadata(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_observers: &OT, _observers: &OT,
testcase: &mut Testcase<S::Input>, testcase: &mut Testcase<S::Input>,
) -> Result<(), Error> ) -> Result<(), Error> {
where
OT: ObserversTuple<S::Input, S>,
{
if let Some(errors) = &self.errors { if let Some(errors) = &self.errors {
testcase.add_metadata(errors.clone()); testcase.add_metadata(errors.clone());
} }

View File

@ -5,15 +5,13 @@ use std::borrow::Cow;
use libafl::{ use libafl::{
alloc, alloc,
corpus::Testcase, corpus::Testcase,
events::EventFirer,
executors::ExitKind, executors::ExitKind,
feedbacks::{Feedback, MinMapFeedback}, feedbacks::{Feedback, MinMapFeedback, StateInitializer},
inputs::{BytesInput, Input}, inputs::{BytesInput, Input},
observers::ObserversTuple,
state::State, state::State,
Error, HasMetadata, Error, HasMetadata,
}; };
use libafl_bolts::{impl_serdeany, Named}; use libafl_bolts::{impl_serdeany, tuples::MatchNameRef, Named};
use libafl_targets::OomFeedback; use libafl_targets::OomFeedback;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -43,22 +41,20 @@ impl Named for LibfuzzerKeepFeedback {
} }
} }
impl<S> Feedback<S> for LibfuzzerKeepFeedback impl<S> StateInitializer<S> for LibfuzzerKeepFeedback {}
impl<EM, OT, S> Feedback<EM, S::Input, OT, S> for LibfuzzerKeepFeedback
where where
S: State, S: State,
{ {
fn is_interesting<EM, OT>( fn is_interesting(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_input: &S::Input, _input: &S::Input,
_observers: &OT, _observers: &OT,
_exit_kind: &ExitKind, _exit_kind: &ExitKind,
) -> Result<bool, Error> ) -> Result<bool, Error> {
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S::Input, S>,
{
Ok(*self.keep.borrow()) Ok(*self.keep.borrow())
} }
@ -119,22 +115,21 @@ impl LibfuzzerCrashCauseFeedback {
} }
} }
impl<S> Feedback<S> for LibfuzzerCrashCauseFeedback impl<S> StateInitializer<S> for LibfuzzerCrashCauseFeedback {}
impl<EM, OT, S> Feedback<EM, BytesInput, OT, S> for LibfuzzerCrashCauseFeedback
where where
S: State<Input = BytesInput>, S: State<Input = BytesInput>,
OT: MatchNameRef,
{ {
fn is_interesting<EM, OT>( fn is_interesting(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_input: &S::Input, _input: &BytesInput,
_observers: &OT, _observers: &OT,
exit_kind: &ExitKind, exit_kind: &ExitKind,
) -> Result<bool, Error> ) -> Result<bool, Error> {
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S::Input, S>,
{
self.exit_kind = *exit_kind; self.exit_kind = *exit_kind;
Ok(false) Ok(false)
} }
@ -143,16 +138,13 @@ where
Ok(false) Ok(false)
} }
fn append_metadata<EM, OT>( fn append_metadata(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_observers: &OT, _observers: &OT,
testcase: &mut Testcase<S::Input>, testcase: &mut Testcase<BytesInput>,
) -> Result<(), Error> ) -> Result<(), Error> {
where
OT: ObserversTuple<S::Input, S>,
{
match self.exit_kind { match self.exit_kind {
ExitKind::Crash | ExitKind::Oom if OomFeedback::oomed() => { ExitKind::Crash | ExitKind::Oom if OomFeedback::oomed() => {
self.set_filename("oom", testcase); self.set_filename("oom", testcase);
@ -183,4 +175,4 @@ where
} }
} }
pub type ShrinkMapFeedback<C, O, T> = MinMapFeedback<C, MappedEdgeMapObserver<O, T>, usize>; pub type ShrinkMapFeedback<C, O, T> = MinMapFeedback<C, MappedEdgeMapObserver<O, T>>;

View File

@ -89,7 +89,7 @@ pub unsafe fn inproc_qemu_timeout_handler<E, EM, OF, Z>(
E: HasObservers + HasInProcessHooks<E::State> + Executor<EM, Z>, E: HasObservers + HasInProcessHooks<E::State> + Executor<EM, Z>,
E::Observers: ObserversTuple<E::Input, E::State>, E::Observers: ObserversTuple<E::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>, EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>, OF: Feedback<EM, E::Input, E::Observers, E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus, E::State: HasExecutions + HasSolutions + HasCorpus,
Z: HasObjective<Objective = OF, State = E::State>, Z: HasObjective<Objective = OF, State = E::State>,
<<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me <<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me
@ -139,9 +139,11 @@ where
where where
ED: EmulatorDriver<CM, ET, S, SM>, ED: EmulatorDriver<CM, ET, S, SM>,
EM: EventFirer<State = S> + EventRestarter<State = S>, EM: EventFirer<State = S> + EventRestarter<State = S>,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
S: Unpin + State + HasExecutions + HasCorpus + HasSolutions, S: Unpin + State + HasExecutions + HasCorpus + HasSolutions,
Z: HasObjective<Objective = OF, State = S> + HasScheduler<State = S> + ExecutionProcessor, Z: HasObjective<Objective = OF, State = S>
+ HasScheduler<State = S>
+ ExecutionProcessor<EM, OT>,
S::Solutions: Corpus<Input = S::Input>, //delete me S::Solutions: Corpus<Input = S::Input>, //delete me
<S::Corpus as Corpus>::Input: Clone, //delete me <S::Corpus as Corpus>::Input: Clone, //delete me
{ {
@ -328,6 +330,7 @@ where
S: State + HasSolutions, S: State + HasSolutions,
SP: ShMemProvider, SP: ShMemProvider,
Z: HasObjective<State = S>, Z: HasObjective<State = S>,
Z::Objective: Feedback<EM, S::Input, OT, S>,
{ {
pub fn new( pub fn new(
emulator: Emulator<CM, ED, ET, S, SM>, emulator: Emulator<CM, ED, ET, S, SM>,
@ -383,7 +386,7 @@ where
OT: ObserversTuple<S::Input, S> + Debug, OT: ObserversTuple<S::Input, S> + Debug,
ET: EmulatorModuleTuple<S>, ET: EmulatorModuleTuple<S>,
SP: ShMemProvider, SP: ShMemProvider,
OF: Feedback<S>, OF: Feedback<EM, S::Input, OT, S>,
Z: HasObjective<Objective = OF, State = S>, Z: HasObjective<Objective = OF, State = S>,
{ {
fn run_target( fn run_target(

View File

@ -2,7 +2,12 @@ use alloc::borrow::Cow;
use core::{ffi::c_void, fmt::Debug}; use core::{ffi::c_void, fmt::Debug};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use libafl::{executors::ExitKind, feedbacks::Feedback, observers::Observer, state::State, Error}; use libafl::{
executors::ExitKind,
feedbacks::{Feedback, StateInitializer},
observers::Observer,
Error,
};
use libafl_bolts::Named; use libafl_bolts::Named;
use libc::SIGABRT; use libc::SIGABRT;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -138,15 +143,14 @@ impl Named for OomFeedback {
} }
} }
impl<S> Feedback<S> for OomFeedback impl<S> StateInitializer<S> for OomFeedback {}
where
S: State, impl<EM, I, OT, S> Feedback<EM, I, OT, S> for OomFeedback {
{ fn is_interesting(
fn is_interesting<EM, OT>(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
_manager: &mut EM, _manager: &mut EM,
_input: &S::Input, _input: &I,
_observers: &OT, _observers: &OT,
_exit_kind: &ExitKind, _exit_kind: &ExitKind,
) -> Result<bool, Error> { ) -> Result<bool, Error> {

View File

@ -34,7 +34,7 @@ pub unsafe fn setup_asan_callback<E, EM, OF, Z>(_executor: &E, _event_mgr: &EM,
where where
E: Executor<EM, Z> + HasObservers, E: Executor<EM, Z> + HasObservers,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>, EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>, OF: Feedback<EM, E::Input, E::Observers, E::State>,
E::State: HasSolutions + HasCorpus + HasExecutions, E::State: HasSolutions + HasCorpus + HasExecutions,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>, E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
Z: HasObjective<Objective = OF, State = E::State>, Z: HasObjective<Objective = OF, State = E::State>,