Remove executor hooks (#124)

* remove HasExecHooks from Executor

* adapt the frida executor

* adapt frida and avoid recursive type infearence

* fix win build
This commit is contained in:
Andrea Fioraldi 2021-05-25 15:19:10 +02:00 committed by GitHub
parent 7493b59ba8
commit 46716e8090
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 143 additions and 349 deletions

View File

@ -20,7 +20,7 @@ use libafl::{
QueueCorpusScheduler, QueueCorpusScheduler,
}, },
executors::{ executors::{
inprocess::InProcessExecutor, timeout::TimeoutExecutor, Executor, ExitKind, HasExecHooks, inprocess::InProcessExecutor, timeout::TimeoutExecutor, Executor, ExitKind,
HasExecHooksTuple, HasObservers, HasObserversHooks, HasExecHooksTuple, HasObservers, HasObserversHooks,
}, },
feedback_or, feedback_or,
@ -65,7 +65,7 @@ where
I: Input + HasTargetBytes, I: Input + HasTargetBytes,
OT: ObserversTuple, OT: ObserversTuple,
{ {
base: TimeoutExecutor<InProcessExecutor<'a, H, I, OT, S>, I>, base: TimeoutExecutor<InProcessExecutor<'a, H, I, OT, S>>,
/// Frida's dynamic rewriting engine /// Frida's dynamic rewriting engine
stalker: Stalker<'a>, stalker: Stalker<'a>,
/// User provided callback for instrumentation /// User provided callback for instrumentation
@ -74,7 +74,7 @@ where
_phantom: PhantomData<&'b u8>, _phantom: PhantomData<&'b u8>,
} }
impl<'a, 'b, 'c, FH, H, I, OT, S> Executor<I> impl<'a, 'b, 'c, EM, FH, H, I, OT, S, Z> Executor<EM, I, S, Z>
for FridaInProcessExecutor<'a, 'b, 'c, FH, H, I, OT, S> for FridaInProcessExecutor<'a, 'b, 'c, FH, H, I, OT, S>
where where
FH: FridaHelper<'b>, FH: FridaHelper<'b>,
@ -84,7 +84,14 @@ where
{ {
/// Instruct the target about the input and run /// Instruct the target about the input and run
#[inline] #[inline]
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error> { fn run_target(
&mut self,
fuzzer: &mut Z,
state: &mut S,
mgr: &mut EM,
input: &I,
) -> Result<ExitKind, Error> {
self.helper.pre_exec(input);
if self.helper.stalker_enabled() { if self.helper.stalker_enabled() {
if self.followed { if self.followed {
self.stalker.activate(NativePointer( self.stalker.activate(NativePointer(
@ -96,7 +103,7 @@ where
.follow_me::<NoneEventSink>(self.helper.transformer(), None); .follow_me::<NoneEventSink>(self.helper.transformer(), None);
} }
} }
let res = self.base.run_target(input); let res = self.base.run_target(fuzzer, state, mgr, input);
if self.helper.stalker_enabled() { if self.helper.stalker_enabled() {
self.stalker.deactivate(); self.stalker.deactivate();
} }
@ -109,42 +116,8 @@ where
if self.helper.stalker_enabled() { if self.helper.stalker_enabled() {
self.stalker.deactivate(); self.stalker.deactivate();
} }
res
}
}
impl<'a, 'b, 'c, EM, FH, H, I, OT, S, Z> HasExecHooks<EM, I, S, Z>
for FridaInProcessExecutor<'a, 'b, 'c, FH, H, I, OT, S>
where
FH: FridaHelper<'b>,
H: FnMut(&I) -> ExitKind,
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
/// Called right before exexution starts
#[inline]
fn pre_exec(
&mut self,
fuzzer: &mut Z,
state: &mut S,
event_mgr: &mut EM,
input: &I,
) -> Result<(), Error> {
self.helper.pre_exec(input);
self.base.pre_exec(fuzzer, state, event_mgr, input)
}
/// Called right after execution finished.
#[inline]
fn post_exec(
&mut self,
fuzzer: &mut Z,
state: &mut S,
event_mgr: &mut EM,
input: &I,
) -> Result<(), Error> {
self.helper.post_exec(input); self.helper.post_exec(input);
self.base.post_exec(fuzzer, state, event_mgr, input) res
} }
} }

View File

@ -328,6 +328,7 @@ where
event: Event<I>, event: Event<I>,
) -> Result<(), Error> ) -> Result<(), Error>
where where
E: Executor<Self, I, S, Z>,
Z: IfInteresting<I, S> + IsInteresting<I, OT, S>, Z: IfInteresting<I, S> + IsInteresting<I, OT, S>,
{ {
match event { match event {
@ -346,6 +347,7 @@ where
let observers: OT = postcard::from_bytes(&observers_buf)?; let observers: OT = postcard::from_bytes(&observers_buf)?;
// TODO include ExitKind in NewTestcase // TODO include ExitKind in NewTestcase
// TODO check for objective too
let is_interesting = let is_interesting =
fuzzer.is_interesting(state, self, &input, &observers, &ExitKind::Ok)?; fuzzer.is_interesting(state, self, &input, &observers, &ExitKind::Ok)?;
if fuzzer if fuzzer
@ -423,7 +425,7 @@ impl<E, I, OT, S, SP, ST, Z> EventProcessor<E, S, Z> for LlmpEventManager<I, OT,
where where
SP: ShMemProvider, SP: ShMemProvider,
ST: Stats, ST: Stats,
E: Executor<I>, E: Executor<Self, I, S, Z>,
I: Input, I: Input,
OT: ObserversTuple, OT: ObserversTuple,
Z: IfInteresting<I, S> + IsInteresting<I, OT, S>, //CE: CustomEvent<I>, Z: IfInteresting<I, S> + IsInteresting<I, OT, S>, //CE: CustomEvent<I>,
@ -469,7 +471,7 @@ impl<E, I, OT, S, SP, ST, Z> EventManager<E, I, S, Z> for LlmpEventManager<I, OT
where where
SP: ShMemProvider, SP: ShMemProvider,
ST: Stats, ST: Stats,
E: Executor<I>, E: Executor<Self, I, S, Z>,
I: Input, I: Input,
OT: ObserversTuple, OT: ObserversTuple,
Z: IfInteresting<I, S> + IsInteresting<I, OT, S>, //CE: CustomEvent<I>, Z: IfInteresting<I, S> + IsInteresting<I, OT, S>, //CE: CustomEvent<I>,
@ -573,7 +575,7 @@ where
impl<E, I, OT, S, SP, ST, Z> EventProcessor<E, S, Z> impl<E, I, OT, S, SP, ST, Z> EventProcessor<E, S, Z>
for LlmpRestartingEventManager<I, OT, S, SP, ST> for LlmpRestartingEventManager<I, OT, S, SP, ST>
where where
E: Executor<I>, E: Executor<LlmpEventManager<I, OT, S, SP, ST>, I, S, Z>,
I: Input, I: Input,
Z: IfInteresting<I, S> + IsInteresting<I, OT, S>, Z: IfInteresting<I, S> + IsInteresting<I, OT, S>,
OT: ObserversTuple, OT: ObserversTuple,
@ -589,7 +591,7 @@ where
impl<E, I, OT, S, SP, ST, Z> EventManager<E, I, S, Z> impl<E, I, OT, S, SP, ST, Z> EventManager<E, I, S, Z>
for LlmpRestartingEventManager<I, OT, S, SP, ST> for LlmpRestartingEventManager<I, OT, S, SP, ST>
where where
E: Executor<I>, E: Executor<LlmpEventManager<I, OT, S, SP, ST>, I, S, Z>,
I: Input, I: Input,
S: Serialize, S: Serialize,
Z: IfInteresting<I, S> + IsInteresting<I, OT, S>, Z: IfInteresting<I, S> + IsInteresting<I, OT, S>,

View File

@ -1,41 +1,22 @@
//! A `CombinedExecutor` wraps a primary executor and a secondary one //! A `CombinedExecutor` wraps a primary executor and a secondary one
use core::marker::PhantomData;
use crate::{ use crate::{
executors::{ executors::{Executor, ExitKind, HasExecHooksTuple, HasObservers, HasObserversHooks},
Executor, ExitKind, HasExecHooks, HasExecHooksTuple, HasObservers, HasObserversHooks,
},
inputs::Input, inputs::Input,
observers::ObserversTuple, observers::ObserversTuple,
Error, Error,
}; };
/// A [`CombinedExecutor`] wraps a primary executor, forwarding its methods, and a secondary one /// A [`CombinedExecutor`] wraps a primary executor, forwarding its methods, and a secondary one
pub struct CombinedExecutor<A, B, I> pub struct CombinedExecutor<A, B> {
where
A: Executor<I>,
B: Executor<I>,
I: Input,
{
primary: A, primary: A,
secondary: B, secondary: B,
phantom: PhantomData<I>,
} }
impl<A, B, I> CombinedExecutor<A, B, I> impl<A, B> CombinedExecutor<A, B> {
where
A: Executor<I>,
B: Executor<I>,
I: Input,
{
/// Create a new `CombinedExecutor`, wrapping the given `executor`s. /// Create a new `CombinedExecutor`, wrapping the given `executor`s.
pub fn new(primary: A, secondary: B) -> Self { pub fn new<EM, I, S, Z>(primary: A, secondary: B) -> Self {
Self { Self { primary, secondary }
primary,
secondary,
phantom: PhantomData,
}
} }
/// Retrieve the primary `Executor` that is wrapped by this `CombinedExecutor`. /// Retrieve the primary `Executor` that is wrapped by this `CombinedExecutor`.
@ -49,22 +30,26 @@ where
} }
} }
impl<A, B, I> Executor<I> for CombinedExecutor<A, B, I> impl<A, B, EM, I, S, Z> Executor<EM, I, S, Z> for CombinedExecutor<A, B>
where where
A: Executor<I>, A: Executor<EM, I, S, Z>,
B: Executor<I>, B: Executor<EM, I, S, Z>,
I: Input, I: Input,
{ {
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error> { fn run_target(
self.primary.run_target(input) &mut self,
fuzzer: &mut Z,
state: &mut S,
mgr: &mut EM,
input: &I,
) -> Result<ExitKind, Error> {
self.primary.run_target(fuzzer, state, mgr, input)
} }
} }
impl<A, B, I, OT> HasObservers<OT> for CombinedExecutor<A, B, I> impl<A, B, OT> HasObservers<OT> for CombinedExecutor<A, B>
where where
A: Executor<I> + HasObservers<OT>, A: HasObservers<OT>,
B: Executor<I>,
I: Input,
OT: ObserversTuple, OT: ObserversTuple,
{ {
#[inline] #[inline]
@ -78,40 +63,10 @@ where
} }
} }
impl<A, B, EM, I, OT, S, Z> HasObserversHooks<EM, I, OT, S, Z> for CombinedExecutor<A, B, I> impl<A, B, EM, I, OT, S, Z> HasObserversHooks<EM, I, OT, S, Z> for CombinedExecutor<A, B>
where where
A: Executor<I> + HasObservers<OT>, A: HasObservers<OT>,
B: Executor<I>,
I: Input, I: Input,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>, OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
{ {
} }
impl<A, B, EM, I, S, Z> HasExecHooks<EM, I, S, Z> for CombinedExecutor<A, B, I>
where
A: Executor<I> + HasExecHooks<EM, I, S, Z>,
B: Executor<I>,
I: Input,
{
#[inline]
fn pre_exec(
&mut self,
fuzzer: &mut Z,
state: &mut S,
mgr: &mut EM,
input: &I,
) -> Result<(), Error> {
self.primary.pre_exec(fuzzer, state, mgr, input)
}
#[inline]
fn post_exec(
&mut self,
fuzzer: &mut Z,
state: &mut S,
mgr: &mut EM,
input: &I,
) -> Result<(), Error> {
self.primary.post_exec(fuzzer, state, mgr, input)
}
}

View File

@ -13,9 +13,7 @@ use std::{
use crate::bolts::os::{dup2, pipes::Pipe}; use crate::bolts::os::{dup2, pipes::Pipe};
use crate::{ use crate::{
executors::{ executors::{Executor, ExitKind, HasExecHooksTuple, HasObservers, HasObserversHooks},
Executor, ExitKind, HasExecHooks, HasExecHooksTuple, HasObservers, HasObserversHooks,
},
inputs::{HasTargetBytes, Input}, inputs::{HasTargetBytes, Input},
observers::ObserversTuple, observers::ObserversTuple,
Error, Error,
@ -328,13 +326,19 @@ where
} }
} }
impl<I, OT> Executor<I> for ForkserverExecutor<I, OT> impl<EM, I, OT, S, Z> Executor<EM, I, S, Z> for ForkserverExecutor<I, OT>
where where
I: Input + HasTargetBytes, I: Input + HasTargetBytes,
OT: ObserversTuple, OT: ObserversTuple,
{ {
#[inline] #[inline]
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error> { fn run_target(
&mut self,
_fuzzer: &mut Z,
_state: &mut S,
_mgr: &mut EM,
input: &I,
) -> Result<ExitKind, Error> {
let mut exit_kind = ExitKind::Ok; let mut exit_kind = ExitKind::Ok;
// Write to testcase // Write to testcase
@ -377,13 +381,6 @@ where
} }
} }
impl<EM, I, OT, S, Z> HasExecHooks<EM, I, S, Z> for ForkserverExecutor<I, OT>
where
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
}
impl<I, OT> HasObservers<OT> for ForkserverExecutor<I, OT> impl<I, OT> HasObservers<OT> for ForkserverExecutor<I, OT>
where where
I: Input + HasTargetBytes, I: Input + HasTargetBytes,

View File

@ -18,9 +18,7 @@ use crate::bolts::os::windows_exceptions::setup_exception_handler;
use crate::{ use crate::{
corpus::Corpus, corpus::Corpus,
events::{EventFirer, EventRestarter}, events::{EventFirer, EventRestarter},
executors::{ executors::{Executor, ExitKind, HasExecHooksTuple, HasObservers, HasObserversHooks},
Executor, ExitKind, HasExecHooks, HasExecHooksTuple, HasObservers, HasObserversHooks,
},
feedbacks::Feedback, feedbacks::Feedback,
fuzzer::HasObjective, fuzzer::HasObjective,
inputs::Input, inputs::Input,
@ -43,39 +41,26 @@ where
phantom: PhantomData<(I, S)>, phantom: PhantomData<(I, S)>,
} }
impl<'a, H, I, OT, S> Executor<I> for InProcessExecutor<'a, H, I, OT, S> impl<'a, EM, H, I, OT, S, Z> Executor<EM, I, S, Z> for InProcessExecutor<'a, H, I, OT, S>
where where
H: FnMut(&I) -> ExitKind, H: FnMut(&I) -> ExitKind,
I: Input, I: Input,
OT: ObserversTuple, OT: ObserversTuple,
{ {
#[inline] #[inline]
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error> { fn run_target(
let ret = (self.harness_fn)(input);
Ok(ret)
}
}
impl<'a, EM, H, I, OT, S, Z> HasExecHooks<EM, I, S, Z> for InProcessExecutor<'a, H, I, OT, S>
where
H: FnMut(&I) -> ExitKind,
I: Input,
OT: ObserversTuple,
{
#[inline]
fn pre_exec(
&mut self, &mut self,
_fuzzer: &mut Z, fuzzer: &mut Z,
_state: &mut S, state: &mut S,
_event_mgr: &mut EM, mgr: &mut EM,
_input: &I, input: &I,
) -> Result<(), Error> { ) -> Result<ExitKind, Error> {
#[cfg(unix)] #[cfg(unix)]
unsafe { unsafe {
let data = &mut unix_signal_handler::GLOBAL_STATE; let data = &mut unix_signal_handler::GLOBAL_STATE;
write_volatile( write_volatile(
&mut data.current_input_ptr, &mut data.current_input_ptr,
_input as *const _ as *const c_void, input as *const _ as *const c_void,
); );
write_volatile( write_volatile(
&mut data.observers_ptr, &mut data.observers_ptr,
@ -83,9 +68,9 @@ where
); );
// Direct raw pointers access /aliasing is pretty undefined behavior. // Direct raw pointers access /aliasing is pretty undefined behavior.
// Since the state and event may have moved in memory, refresh them right before the signal may happen // Since the state and event may have moved in memory, refresh them right before the signal may happen
write_volatile(&mut data.state_ptr, _state as *mut _ as *mut c_void); write_volatile(&mut data.state_ptr, state as *mut _ as *mut c_void);
write_volatile(&mut data.event_mgr_ptr, _event_mgr as *mut _ as *mut c_void); write_volatile(&mut data.event_mgr_ptr, mgr as *mut _ as *mut c_void);
write_volatile(&mut data.fuzzer_ptr, _fuzzer as *mut _ as *mut c_void); write_volatile(&mut data.fuzzer_ptr, fuzzer as *mut _ as *mut c_void);
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
} }
#[cfg(all(windows, feature = "std"))] #[cfg(all(windows, feature = "std"))]
@ -93,7 +78,7 @@ where
let data = &mut windows_exception_handler::GLOBAL_STATE; let data = &mut windows_exception_handler::GLOBAL_STATE;
write_volatile( write_volatile(
&mut data.current_input_ptr, &mut data.current_input_ptr,
_input as *const _ as *const c_void, input as *const _ as *const c_void,
); );
write_volatile( write_volatile(
&mut data.observers_ptr, &mut data.observers_ptr,
@ -101,22 +86,14 @@ where
); );
// Direct raw pointers access /aliasing is pretty undefined behavior. // Direct raw pointers access /aliasing is pretty undefined behavior.
// Since the state and event may have moved in memory, refresh them right before the signal may happen // Since the state and event may have moved in memory, refresh them right before the signal may happen
write_volatile(&mut data.state_ptr, _state as *mut _ as *mut c_void); write_volatile(&mut data.state_ptr, state as *mut _ as *mut c_void);
write_volatile(&mut data.event_mgr_ptr, _event_mgr as *mut _ as *mut c_void); write_volatile(&mut data.event_mgr_ptr, mgr as *mut _ as *mut c_void);
write_volatile(&mut data.fuzzer_ptr, _fuzzer as *mut _ as *mut c_void); write_volatile(&mut data.fuzzer_ptr, fuzzer as *mut _ as *mut c_void);
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
} }
Ok(())
}
#[inline] let ret = (self.harness_fn)(input);
fn post_exec(
&mut self,
_fuzzer: &mut Z,
_state: &mut S,
_event_mgr: &mut EM,
_input: &I,
) -> Result<(), Error> {
#[cfg(unix)] #[cfg(unix)]
unsafe { unsafe {
write_volatile( write_volatile(
@ -133,7 +110,8 @@ where
); );
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
} }
Ok(())
Ok(ret)
} }
} }
@ -742,6 +720,8 @@ mod tests {
phantom: PhantomData, phantom: PhantomData,
}; };
let input = NopInput {}; let input = NopInput {};
assert!(in_process_executor.run_target(&input).is_ok()); assert!(in_process_executor
.run_target(&mut (), &mut (), &mut (), &input)
.is_ok());
} }
} }

View File

@ -13,8 +13,6 @@ pub use forkserver::{Forkserver, ForkserverExecutor, OutFile};
pub mod combined; pub mod combined;
pub use combined::CombinedExecutor; pub use combined::CombinedExecutor;
use core::marker::PhantomData;
use crate::{ use crate::{
bolts::serdeany::SerdeAny, bolts::serdeany::SerdeAny,
inputs::{HasTargetBytes, Input}, inputs::{HasTargetBytes, Input},
@ -184,25 +182,35 @@ where
} }
/// An executor takes the given inputs, and runs the harness/target. /// An executor takes the given inputs, and runs the harness/target.
pub trait Executor<I> pub trait Executor<EM, I, S, Z>
where where
I: Input, I: Input,
{ {
/// Instruct the target about the input and run /// Instruct the target about the input and run
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error>; fn run_target(
&mut self,
fuzzer: &mut Z,
state: &mut S,
mgr: &mut EM,
input: &I,
) -> Result<ExitKind, Error>;
} }
/// A simple executor that does nothing. /// A simple executor that does nothing.
/// If intput len is 0, `run_target` will return Err /// If intput len is 0, `run_target` will return Err
struct NopExecutor<EM, I, S> { struct NopExecutor {}
phantom: PhantomData<(EM, I, S)>,
}
impl<EM, I, S> Executor<I> for NopExecutor<EM, I, S> impl<EM, I, S, Z> Executor<EM, I, S, Z> for NopExecutor
where where
I: Input + HasTargetBytes, I: Input + HasTargetBytes,
{ {
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error> { fn run_target(
&mut self,
_fuzzer: &mut Z,
_state: &mut S,
_mgr: &mut EM,
input: &I,
) -> Result<ExitKind, Error> {
if input.target_bytes().as_slice().is_empty() { if input.target_bytes().as_slice().is_empty() {
Err(Error::Empty("Input Empty".into())) Err(Error::Empty("Input Empty".into()))
} else { } else {
@ -211,13 +219,8 @@ where
} }
} }
impl<EM, I, S, Z> HasExecHooks<EM, I, S, Z> for NopExecutor<EM, I, S> where I: Input + HasTargetBytes
{}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use core::marker::PhantomData;
use super::{Executor, NopExecutor}; use super::{Executor, NopExecutor};
use crate::inputs::BytesInput; use crate::inputs::BytesInput;
@ -225,10 +228,12 @@ mod test {
fn nop_executor() { fn nop_executor() {
let empty_input = BytesInput::new(vec![]); let empty_input = BytesInput::new(vec![]);
let nonempty_input = BytesInput::new(vec![1u8]); let nonempty_input = BytesInput::new(vec![1u8]);
let mut executor = NopExecutor::<(), _, ()> { let mut executor = NopExecutor {};
phantom: PhantomData, assert!(executor
}; .run_target(&mut (), &mut (), &mut (), &empty_input)
assert!(executor.run_target(&empty_input).is_err()); .is_err());
assert!(executor.run_target(&nonempty_input).is_ok()); assert!(executor
.run_target(&mut (), &mut (), &mut (), &nonempty_input)
.is_ok());
} }
} }

View File

@ -1,11 +1,9 @@
//! A `TimeoutExecutor` sets a timeout before each target run //! A `TimeoutExecutor` sets a timeout before each target run
use core::{marker::PhantomData, time::Duration}; use core::time::Duration;
use crate::{ use crate::{
executors::{ executors::{Executor, ExitKind, HasExecHooksTuple, HasObservers, HasObserversHooks},
Executor, ExitKind, HasExecHooks, HasExecHooksTuple, HasObservers, HasObserversHooks,
},
inputs::Input, inputs::Input,
observers::ObserversTuple, observers::ObserversTuple,
Error, Error,
@ -39,28 +37,18 @@ extern "C" {
const ITIMER_REAL: c_int = 0; const ITIMER_REAL: c_int = 0;
/// The timeout excutor is a wrapper that set a timeout before each run /// The timeout excutor is a wrapper that set a timeout before each run
pub struct TimeoutExecutor<E, I> pub struct TimeoutExecutor<E> {
where
E: Executor<I>,
I: Input,
{
executor: E, executor: E,
exec_tmout: Duration, exec_tmout: Duration,
phantom: PhantomData<I>,
} }
impl<E, I> TimeoutExecutor<E, I> impl<E> TimeoutExecutor<E> {
where
E: Executor<I>,
I: Input,
{
/// Create a new `TimeoutExecutor`, wrapping the given `executor` and checking for timeouts. /// Create a new `TimeoutExecutor`, wrapping the given `executor` and checking for timeouts.
/// This should usually be used for `InProcess` fuzzing. /// This should usually be used for `InProcess` fuzzing.
pub fn new(executor: E, exec_tmout: Duration) -> Self { pub fn new(executor: E, exec_tmout: Duration) -> Self {
Self { Self {
executor, executor,
exec_tmout, exec_tmout,
phantom: PhantomData,
} }
} }
@ -70,54 +58,18 @@ where
} }
} }
impl<E, I> Executor<I> for TimeoutExecutor<E, I> impl<E, EM, I, S, Z> Executor<EM, I, S, Z> for TimeoutExecutor<E>
where where
E: Executor<I>, E: Executor<EM, I, S, Z>,
I: Input, I: Input,
{ {
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error> { fn run_target(
self.executor.run_target(input)
}
}
impl<E, I, OT> HasObservers<OT> for TimeoutExecutor<E, I>
where
E: Executor<I> + HasObservers<OT>,
I: Input,
OT: ObserversTuple,
{
#[inline]
fn observers(&self) -> &OT {
self.executor.observers()
}
#[inline]
fn observers_mut(&mut self) -> &mut OT {
self.executor.observers_mut()
}
}
impl<E, EM, I, OT, S, Z> HasObserversHooks<EM, I, OT, S, Z> for TimeoutExecutor<E, I>
where
E: Executor<I> + HasObservers<OT>,
I: Input,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
{
}
impl<E, EM, I, S, Z> HasExecHooks<EM, I, S, Z> for TimeoutExecutor<E, I>
where
E: Executor<I> + HasExecHooks<EM, I, S, Z>,
I: Input,
{
#[inline]
fn pre_exec(
&mut self, &mut self,
fuzzer: &mut Z, fuzzer: &mut Z,
state: &mut S, state: &mut S,
mgr: &mut EM, mgr: &mut EM,
input: &I, input: &I,
) -> Result<(), Error> { ) -> Result<ExitKind, Error> {
#[cfg(unix)] #[cfg(unix)]
unsafe { unsafe {
let milli_sec = self.exec_tmout.as_millis(); let milli_sec = self.exec_tmout.as_millis();
@ -143,17 +95,9 @@ where
// TODO // TODO
let _ = self.exec_tmout.as_millis(); let _ = self.exec_tmout.as_millis();
} }
self.executor.pre_exec(fuzzer, state, mgr, input)
}
#[inline] let ret = self.executor.run_target(fuzzer, state, mgr, input);
fn post_exec(
&mut self,
fuzzer: &mut Z,
state: &mut S,
mgr: &mut EM,
input: &I,
) -> Result<(), Error> {
#[cfg(unix)] #[cfg(unix)]
unsafe { unsafe {
let it_value = Timeval { let it_value = Timeval {
@ -177,6 +121,31 @@ where
{ {
// TODO // TODO
} }
self.executor.post_exec(fuzzer, state, mgr, input)
ret
} }
} }
impl<E, OT> HasObservers<OT> for TimeoutExecutor<E>
where
E: HasObservers<OT>,
OT: ObserversTuple,
{
#[inline]
fn observers(&self) -> &OT {
self.executor.observers()
}
#[inline]
fn observers_mut(&mut self) -> &mut OT {
self.executor.observers_mut()
}
}
impl<E, EM, I, OT, S, Z> HasObserversHooks<EM, I, OT, S, Z> for TimeoutExecutor<E>
where
E: HasObservers<OT>,
I: Input,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
{
}

View File

@ -265,61 +265,6 @@ where
} }
} }
/*if self.indexes.is_none() && self.novelties.is_none() {
for i in 0..size {
let history = map_state.history_map[i];
let item = observer.map()[i];
let reduced = R::reduce(history, item);
if history != reduced {
map_state.history_map[i] = reduced;
interesting = true;
}
}
} else if self.indexes.is_some() && self.novelties.is_none() {
for i in 0..size {
let history = map_state.history_map[i];
let item = observer.map()[i];
// TODO maybe walk again the histroy map only when it is interesting is more efficient
if item != initial {
self.indexes.as_mut().unwrap().push(i);
}
let reduced = R::reduce(history, item);
if history != reduced {
map_state.history_map[i] = reduced;
interesting = true;
}
}
} else if self.indexes.is_none() && self.novelties.is_some() {
for i in 0..size {
let history = map_state.history_map[i];
let item = observer.map()[i];
let reduced = R::reduce(history, item);
if history != reduced {
map_state.history_map[i] = reduced;
interesting = true;
self.novelties.as_mut().unwrap().push(i);
}
}
} else {
for i in 0..size {
let history = map_state.history_map[i];
let item = observer.map()[i];
if item != initial {
self.indexes.as_mut().unwrap().push(i);
}
let reduced = R::reduce(history, item);
if history != reduced {
map_state.history_map[i] = reduced;
interesting = true;
self.novelties.as_mut().unwrap().push(i);
}
}
}*/
if interesting { if interesting {
let mut filled = 0; let mut filled = 0;
for i in 0..size { for i in 0..size {

View File

@ -4,9 +4,7 @@ use crate::{
bolts::current_time, bolts::current_time,
corpus::{Corpus, CorpusScheduler, Testcase}, corpus::{Corpus, CorpusScheduler, Testcase},
events::{Event, EventFirer, EventManager}, events::{Event, EventFirer, EventManager},
executors::{ executors::{Executor, ExitKind, HasExecHooksTuple, HasObservers, HasObserversHooks},
Executor, ExitKind, HasExecHooks, HasExecHooksTuple, HasObservers, HasObserversHooks,
},
feedbacks::Feedback, feedbacks::Feedback,
inputs::Input, inputs::Input,
mark_feature_time, mark_feature_time,
@ -321,10 +319,7 @@ impl<C, CS, E, EM, F, I, OF, OT, S, SC> Evaluator<E, EM, I, S>
where where
C: Corpus<I>, C: Corpus<I>,
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
E: Executor<I> E: Executor<EM, I, S, Self> + HasObservers<OT> + HasObserversHooks<EM, I, OT, S, Self>,
+ HasObservers<OT>
+ HasExecHooks<EM, I, S, Self>
+ HasObserversHooks<EM, I, OT, S, Self>,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Self>, OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Self>,
EM: EventManager<E, I, S, Self>, EM: EventManager<E, I, S, Self>,
F: Feedback<I, S>, F: Feedback<I, S>,
@ -521,10 +516,7 @@ where
input: &I, input: &I,
) -> Result<ExecuteInputResult, Error> ) -> Result<ExecuteInputResult, Error>
where where
E: Executor<I> E: Executor<EM, I, S, Self> + HasObservers<OT> + HasObserversHooks<EM, I, OT, S, Self>,
+ HasObservers<OT>
+ HasExecHooks<EM, I, S, Self>
+ HasObserversHooks<EM, I, OT, S, Self>,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Self>, OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Self>,
EM: EventManager<E, I, S, Self>, EM: EventManager<E, I, S, Self>,
{ {
@ -533,17 +525,9 @@ where
mark_feature_time!(state, PerfFeature::PreExecObservers); mark_feature_time!(state, PerfFeature::PreExecObservers);
start_timer!(state); start_timer!(state);
executor.pre_exec(self, state, event_mgr, input)?; let exit_kind = executor.run_target(self, state, event_mgr, input)?;
mark_feature_time!(state, PerfFeature::PreExec);
start_timer!(state);
let exit_kind = executor.run_target(input)?;
mark_feature_time!(state, PerfFeature::TargetExecution); mark_feature_time!(state, PerfFeature::TargetExecution);
start_timer!(state);
executor.post_exec(self, state, event_mgr, input)?;
mark_feature_time!(state, PerfFeature::PostExec);
*state.executions_mut() += 1; *state.executions_mut() += 1;
start_timer!(state); start_timer!(state);

View File

@ -2,7 +2,7 @@ use core::{marker::PhantomData, mem::drop};
use crate::{ use crate::{
corpus::Corpus, corpus::Corpus,
executors::{Executor, HasExecHooks, HasExecHooksTuple, HasObservers, HasObserversHooks}, executors::{Executor, HasExecHooksTuple, HasObservers, HasObserversHooks},
inputs::Input, inputs::Input,
mark_feature_time, mark_feature_time,
observers::ObserversTuple, observers::ObserversTuple,
@ -21,10 +21,7 @@ pub struct TracingStage<C, EM, I, OT, S, TE, Z>
where where
I: Input, I: Input,
C: Corpus<I>, C: Corpus<I>,
TE: Executor<I> TE: Executor<EM, I, S, Z> + HasObservers<OT> + HasObserversHooks<EM, I, OT, S, Z>,
+ HasObservers<OT>
+ HasExecHooks<EM, I, S, Z>
+ HasObserversHooks<EM, I, OT, S, Z>,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>, OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
S: HasClientPerfStats + HasExecutions + HasCorpus<C, I>, S: HasClientPerfStats + HasExecutions + HasCorpus<C, I>,
{ {
@ -37,10 +34,7 @@ impl<E, C, EM, I, OT, S, TE, Z> Stage<E, EM, S, Z> for TracingStage<C, EM, I, OT
where where
I: Input, I: Input,
C: Corpus<I>, C: Corpus<I>,
TE: Executor<I> TE: Executor<EM, I, S, Z> + HasObservers<OT> + HasObserversHooks<EM, I, OT, S, Z>,
+ HasObservers<OT>
+ HasExecHooks<EM, I, S, Z>
+ HasObserversHooks<EM, I, OT, S, Z>,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>, OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
S: HasClientPerfStats + HasExecutions + HasCorpus<C, I>, S: HasClientPerfStats + HasExecutions + HasCorpus<C, I>,
{ {
@ -68,19 +62,12 @@ where
mark_feature_time!(state, PerfFeature::PreExecObservers); mark_feature_time!(state, PerfFeature::PreExecObservers);
start_timer!(state); start_timer!(state);
self.tracer_executor drop(
.pre_exec(fuzzer, state, manager, &input)?; self.tracer_executor
mark_feature_time!(state, PerfFeature::PreExec); .run_target(fuzzer, state, manager, &input)?,
);
start_timer!(state);
drop(self.tracer_executor.run_target(&input)?);
mark_feature_time!(state, PerfFeature::TargetExecution); mark_feature_time!(state, PerfFeature::TargetExecution);
start_timer!(state);
self.tracer_executor
.post_exec(fuzzer, state, manager, &input)?;
mark_feature_time!(state, PerfFeature::PostExec);
*state.executions_mut() += 1; *state.executions_mut() += 1;
start_timer!(state); start_timer!(state);
@ -96,10 +83,7 @@ impl<C, EM, I, OT, S, TE, Z> TracingStage<C, EM, I, OT, S, TE, Z>
where where
I: Input, I: Input,
C: Corpus<I>, C: Corpus<I>,
TE: Executor<I> TE: Executor<EM, I, S, Z> + HasObservers<OT> + HasObserversHooks<EM, I, OT, S, Z>,
+ HasObservers<OT>
+ HasExecHooks<EM, I, S, Z>
+ HasObserversHooks<EM, I, OT, S, Z>,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>, OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
S: HasClientPerfStats + HasExecutions + HasCorpus<C, I>, S: HasClientPerfStats + HasExecutions + HasCorpus<C, I>,
{ {