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:
parent
7493b59ba8
commit
46716e8090
@ -20,7 +20,7 @@ use libafl::{
|
||||
QueueCorpusScheduler,
|
||||
},
|
||||
executors::{
|
||||
inprocess::InProcessExecutor, timeout::TimeoutExecutor, Executor, ExitKind, HasExecHooks,
|
||||
inprocess::InProcessExecutor, timeout::TimeoutExecutor, Executor, ExitKind,
|
||||
HasExecHooksTuple, HasObservers, HasObserversHooks,
|
||||
},
|
||||
feedback_or,
|
||||
@ -65,7 +65,7 @@ where
|
||||
I: Input + HasTargetBytes,
|
||||
OT: ObserversTuple,
|
||||
{
|
||||
base: TimeoutExecutor<InProcessExecutor<'a, H, I, OT, S>, I>,
|
||||
base: TimeoutExecutor<InProcessExecutor<'a, H, I, OT, S>>,
|
||||
/// Frida's dynamic rewriting engine
|
||||
stalker: Stalker<'a>,
|
||||
/// User provided callback for instrumentation
|
||||
@ -74,7 +74,7 @@ where
|
||||
_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>
|
||||
where
|
||||
FH: FridaHelper<'b>,
|
||||
@ -84,7 +84,14 @@ where
|
||||
{
|
||||
/// Instruct the target about the input and run
|
||||
#[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.followed {
|
||||
self.stalker.activate(NativePointer(
|
||||
@ -96,7 +103,7 @@ where
|
||||
.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() {
|
||||
self.stalker.deactivate();
|
||||
}
|
||||
@ -109,42 +116,8 @@ where
|
||||
if self.helper.stalker_enabled() {
|
||||
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.base.post_exec(fuzzer, state, event_mgr, input)
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,6 +328,7 @@ where
|
||||
event: Event<I>,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
E: Executor<Self, I, S, Z>,
|
||||
Z: IfInteresting<I, S> + IsInteresting<I, OT, S>,
|
||||
{
|
||||
match event {
|
||||
@ -346,6 +347,7 @@ where
|
||||
|
||||
let observers: OT = postcard::from_bytes(&observers_buf)?;
|
||||
// TODO include ExitKind in NewTestcase
|
||||
// TODO check for objective too
|
||||
let is_interesting =
|
||||
fuzzer.is_interesting(state, self, &input, &observers, &ExitKind::Ok)?;
|
||||
if fuzzer
|
||||
@ -423,7 +425,7 @@ impl<E, I, OT, S, SP, ST, Z> EventProcessor<E, S, Z> for LlmpEventManager<I, OT,
|
||||
where
|
||||
SP: ShMemProvider,
|
||||
ST: Stats,
|
||||
E: Executor<I>,
|
||||
E: Executor<Self, I, S, Z>,
|
||||
I: Input,
|
||||
OT: ObserversTuple,
|
||||
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
|
||||
SP: ShMemProvider,
|
||||
ST: Stats,
|
||||
E: Executor<I>,
|
||||
E: Executor<Self, I, S, Z>,
|
||||
I: Input,
|
||||
OT: ObserversTuple,
|
||||
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>
|
||||
for LlmpRestartingEventManager<I, OT, S, SP, ST>
|
||||
where
|
||||
E: Executor<I>,
|
||||
E: Executor<LlmpEventManager<I, OT, S, SP, ST>, I, S, Z>,
|
||||
I: Input,
|
||||
Z: IfInteresting<I, S> + IsInteresting<I, OT, S>,
|
||||
OT: ObserversTuple,
|
||||
@ -589,7 +591,7 @@ where
|
||||
impl<E, I, OT, S, SP, ST, Z> EventManager<E, I, S, Z>
|
||||
for LlmpRestartingEventManager<I, OT, S, SP, ST>
|
||||
where
|
||||
E: Executor<I>,
|
||||
E: Executor<LlmpEventManager<I, OT, S, SP, ST>, I, S, Z>,
|
||||
I: Input,
|
||||
S: Serialize,
|
||||
Z: IfInteresting<I, S> + IsInteresting<I, OT, S>,
|
||||
|
@ -1,41 +1,22 @@
|
||||
//! A `CombinedExecutor` wraps a primary executor and a secondary one
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use crate::{
|
||||
executors::{
|
||||
Executor, ExitKind, HasExecHooks, HasExecHooksTuple, HasObservers, HasObserversHooks,
|
||||
},
|
||||
executors::{Executor, ExitKind, HasExecHooksTuple, HasObservers, HasObserversHooks},
|
||||
inputs::Input,
|
||||
observers::ObserversTuple,
|
||||
Error,
|
||||
};
|
||||
|
||||
/// A [`CombinedExecutor`] wraps a primary executor, forwarding its methods, and a secondary one
|
||||
pub struct CombinedExecutor<A, B, I>
|
||||
where
|
||||
A: Executor<I>,
|
||||
B: Executor<I>,
|
||||
I: Input,
|
||||
{
|
||||
pub struct CombinedExecutor<A, B> {
|
||||
primary: A,
|
||||
secondary: B,
|
||||
phantom: PhantomData<I>,
|
||||
}
|
||||
|
||||
impl<A, B, I> CombinedExecutor<A, B, I>
|
||||
where
|
||||
A: Executor<I>,
|
||||
B: Executor<I>,
|
||||
I: Input,
|
||||
{
|
||||
impl<A, B> CombinedExecutor<A, B> {
|
||||
/// Create a new `CombinedExecutor`, wrapping the given `executor`s.
|
||||
pub fn new(primary: A, secondary: B) -> Self {
|
||||
Self {
|
||||
primary,
|
||||
secondary,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
pub fn new<EM, I, S, Z>(primary: A, secondary: B) -> Self {
|
||||
Self { primary, secondary }
|
||||
}
|
||||
|
||||
/// 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
|
||||
A: Executor<I>,
|
||||
B: Executor<I>,
|
||||
A: Executor<EM, I, S, Z>,
|
||||
B: Executor<EM, I, S, Z>,
|
||||
I: Input,
|
||||
{
|
||||
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error> {
|
||||
self.primary.run_target(input)
|
||||
fn run_target(
|
||||
&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
|
||||
A: Executor<I> + HasObservers<OT>,
|
||||
B: Executor<I>,
|
||||
I: Input,
|
||||
A: HasObservers<OT>,
|
||||
OT: ObserversTuple,
|
||||
{
|
||||
#[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
|
||||
A: Executor<I> + HasObservers<OT>,
|
||||
B: Executor<I>,
|
||||
A: HasObservers<OT>,
|
||||
I: Input,
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -13,9 +13,7 @@ use std::{
|
||||
|
||||
use crate::bolts::os::{dup2, pipes::Pipe};
|
||||
use crate::{
|
||||
executors::{
|
||||
Executor, ExitKind, HasExecHooks, HasExecHooksTuple, HasObservers, HasObserversHooks,
|
||||
},
|
||||
executors::{Executor, ExitKind, HasExecHooksTuple, HasObservers, HasObserversHooks},
|
||||
inputs::{HasTargetBytes, Input},
|
||||
observers::ObserversTuple,
|
||||
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
|
||||
I: Input + HasTargetBytes,
|
||||
OT: ObserversTuple,
|
||||
{
|
||||
#[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;
|
||||
|
||||
// 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>
|
||||
where
|
||||
I: Input + HasTargetBytes,
|
||||
|
@ -18,9 +18,7 @@ use crate::bolts::os::windows_exceptions::setup_exception_handler;
|
||||
use crate::{
|
||||
corpus::Corpus,
|
||||
events::{EventFirer, EventRestarter},
|
||||
executors::{
|
||||
Executor, ExitKind, HasExecHooks, HasExecHooksTuple, HasObservers, HasObserversHooks,
|
||||
},
|
||||
executors::{Executor, ExitKind, HasExecHooksTuple, HasObservers, HasObserversHooks},
|
||||
feedbacks::Feedback,
|
||||
fuzzer::HasObjective,
|
||||
inputs::Input,
|
||||
@ -43,39 +41,26 @@ where
|
||||
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
|
||||
H: FnMut(&I) -> ExitKind,
|
||||
I: Input,
|
||||
OT: ObserversTuple,
|
||||
{
|
||||
#[inline]
|
||||
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error> {
|
||||
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(
|
||||
fn run_target(
|
||||
&mut self,
|
||||
_fuzzer: &mut Z,
|
||||
_state: &mut S,
|
||||
_event_mgr: &mut EM,
|
||||
_input: &I,
|
||||
) -> Result<(), Error> {
|
||||
fuzzer: &mut Z,
|
||||
state: &mut S,
|
||||
mgr: &mut EM,
|
||||
input: &I,
|
||||
) -> Result<ExitKind, Error> {
|
||||
#[cfg(unix)]
|
||||
unsafe {
|
||||
let data = &mut unix_signal_handler::GLOBAL_STATE;
|
||||
write_volatile(
|
||||
&mut data.current_input_ptr,
|
||||
_input as *const _ as *const c_void,
|
||||
input as *const _ as *const c_void,
|
||||
);
|
||||
write_volatile(
|
||||
&mut data.observers_ptr,
|
||||
@ -83,9 +68,9 @@ where
|
||||
);
|
||||
// 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
|
||||
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.fuzzer_ptr, _fuzzer 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, mgr as *mut _ as *mut c_void);
|
||||
write_volatile(&mut data.fuzzer_ptr, fuzzer as *mut _ as *mut c_void);
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
}
|
||||
#[cfg(all(windows, feature = "std"))]
|
||||
@ -93,7 +78,7 @@ where
|
||||
let data = &mut windows_exception_handler::GLOBAL_STATE;
|
||||
write_volatile(
|
||||
&mut data.current_input_ptr,
|
||||
_input as *const _ as *const c_void,
|
||||
input as *const _ as *const c_void,
|
||||
);
|
||||
write_volatile(
|
||||
&mut data.observers_ptr,
|
||||
@ -101,22 +86,14 @@ where
|
||||
);
|
||||
// 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
|
||||
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.fuzzer_ptr, _fuzzer 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, mgr as *mut _ as *mut c_void);
|
||||
write_volatile(&mut data.fuzzer_ptr, fuzzer as *mut _ as *mut c_void);
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn post_exec(
|
||||
&mut self,
|
||||
_fuzzer: &mut Z,
|
||||
_state: &mut S,
|
||||
_event_mgr: &mut EM,
|
||||
_input: &I,
|
||||
) -> Result<(), Error> {
|
||||
let ret = (self.harness_fn)(input);
|
||||
|
||||
#[cfg(unix)]
|
||||
unsafe {
|
||||
write_volatile(
|
||||
@ -133,7 +110,8 @@ where
|
||||
);
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
}
|
||||
Ok(())
|
||||
|
||||
Ok(ret)
|
||||
}
|
||||
}
|
||||
|
||||
@ -742,6 +720,8 @@ mod tests {
|
||||
phantom: PhantomData,
|
||||
};
|
||||
let input = NopInput {};
|
||||
assert!(in_process_executor.run_target(&input).is_ok());
|
||||
assert!(in_process_executor
|
||||
.run_target(&mut (), &mut (), &mut (), &input)
|
||||
.is_ok());
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,6 @@ pub use forkserver::{Forkserver, ForkserverExecutor, OutFile};
|
||||
pub mod combined;
|
||||
pub use combined::CombinedExecutor;
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use crate::{
|
||||
bolts::serdeany::SerdeAny,
|
||||
inputs::{HasTargetBytes, Input},
|
||||
@ -184,25 +182,35 @@ where
|
||||
}
|
||||
|
||||
/// An executor takes the given inputs, and runs the harness/target.
|
||||
pub trait Executor<I>
|
||||
pub trait Executor<EM, I, S, Z>
|
||||
where
|
||||
I: Input,
|
||||
{
|
||||
/// 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.
|
||||
/// If intput len is 0, `run_target` will return Err
|
||||
struct NopExecutor<EM, I, S> {
|
||||
phantom: PhantomData<(EM, I, S)>,
|
||||
}
|
||||
struct NopExecutor {}
|
||||
|
||||
impl<EM, I, S> Executor<I> for NopExecutor<EM, I, S>
|
||||
impl<EM, I, S, Z> Executor<EM, I, S, Z> for NopExecutor
|
||||
where
|
||||
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() {
|
||||
Err(Error::Empty("Input Empty".into()))
|
||||
} 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)]
|
||||
mod test {
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use super::{Executor, NopExecutor};
|
||||
use crate::inputs::BytesInput;
|
||||
|
||||
@ -225,10 +228,12 @@ mod test {
|
||||
fn nop_executor() {
|
||||
let empty_input = BytesInput::new(vec![]);
|
||||
let nonempty_input = BytesInput::new(vec![1u8]);
|
||||
let mut executor = NopExecutor::<(), _, ()> {
|
||||
phantom: PhantomData,
|
||||
};
|
||||
assert!(executor.run_target(&empty_input).is_err());
|
||||
assert!(executor.run_target(&nonempty_input).is_ok());
|
||||
let mut executor = NopExecutor {};
|
||||
assert!(executor
|
||||
.run_target(&mut (), &mut (), &mut (), &empty_input)
|
||||
.is_err());
|
||||
assert!(executor
|
||||
.run_target(&mut (), &mut (), &mut (), &nonempty_input)
|
||||
.is_ok());
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,9 @@
|
||||
//! A `TimeoutExecutor` sets a timeout before each target run
|
||||
|
||||
use core::{marker::PhantomData, time::Duration};
|
||||
use core::time::Duration;
|
||||
|
||||
use crate::{
|
||||
executors::{
|
||||
Executor, ExitKind, HasExecHooks, HasExecHooksTuple, HasObservers, HasObserversHooks,
|
||||
},
|
||||
executors::{Executor, ExitKind, HasExecHooksTuple, HasObservers, HasObserversHooks},
|
||||
inputs::Input,
|
||||
observers::ObserversTuple,
|
||||
Error,
|
||||
@ -39,28 +37,18 @@ extern "C" {
|
||||
const ITIMER_REAL: c_int = 0;
|
||||
|
||||
/// The timeout excutor is a wrapper that set a timeout before each run
|
||||
pub struct TimeoutExecutor<E, I>
|
||||
where
|
||||
E: Executor<I>,
|
||||
I: Input,
|
||||
{
|
||||
pub struct TimeoutExecutor<E> {
|
||||
executor: E,
|
||||
exec_tmout: Duration,
|
||||
phantom: PhantomData<I>,
|
||||
}
|
||||
|
||||
impl<E, I> TimeoutExecutor<E, I>
|
||||
where
|
||||
E: Executor<I>,
|
||||
I: Input,
|
||||
{
|
||||
impl<E> TimeoutExecutor<E> {
|
||||
/// Create a new `TimeoutExecutor`, wrapping the given `executor` and checking for timeouts.
|
||||
/// This should usually be used for `InProcess` fuzzing.
|
||||
pub fn new(executor: E, exec_tmout: Duration) -> Self {
|
||||
Self {
|
||||
executor,
|
||||
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
|
||||
E: Executor<I>,
|
||||
E: Executor<EM, I, S, Z>,
|
||||
I: Input,
|
||||
{
|
||||
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error> {
|
||||
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(
|
||||
fn run_target(
|
||||
&mut self,
|
||||
fuzzer: &mut Z,
|
||||
state: &mut S,
|
||||
mgr: &mut EM,
|
||||
input: &I,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<ExitKind, Error> {
|
||||
#[cfg(unix)]
|
||||
unsafe {
|
||||
let milli_sec = self.exec_tmout.as_millis();
|
||||
@ -143,17 +95,9 @@ where
|
||||
// TODO
|
||||
let _ = self.exec_tmout.as_millis();
|
||||
}
|
||||
self.executor.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> {
|
||||
let ret = self.executor.run_target(fuzzer, state, mgr, input);
|
||||
|
||||
#[cfg(unix)]
|
||||
unsafe {
|
||||
let it_value = Timeval {
|
||||
@ -177,6 +121,31 @@ where
|
||||
{
|
||||
// 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>,
|
||||
{
|
||||
}
|
||||
|
@ -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 {
|
||||
let mut filled = 0;
|
||||
for i in 0..size {
|
||||
|
@ -4,9 +4,7 @@ use crate::{
|
||||
bolts::current_time,
|
||||
corpus::{Corpus, CorpusScheduler, Testcase},
|
||||
events::{Event, EventFirer, EventManager},
|
||||
executors::{
|
||||
Executor, ExitKind, HasExecHooks, HasExecHooksTuple, HasObservers, HasObserversHooks,
|
||||
},
|
||||
executors::{Executor, ExitKind, HasExecHooksTuple, HasObservers, HasObserversHooks},
|
||||
feedbacks::Feedback,
|
||||
inputs::Input,
|
||||
mark_feature_time,
|
||||
@ -321,10 +319,7 @@ impl<C, CS, E, EM, F, I, OF, OT, S, SC> Evaluator<E, EM, I, S>
|
||||
where
|
||||
C: Corpus<I>,
|
||||
CS: CorpusScheduler<I, S>,
|
||||
E: Executor<I>
|
||||
+ HasObservers<OT>
|
||||
+ HasExecHooks<EM, I, S, Self>
|
||||
+ HasObserversHooks<EM, I, OT, S, Self>,
|
||||
E: Executor<EM, I, S, Self> + HasObservers<OT> + HasObserversHooks<EM, I, OT, S, Self>,
|
||||
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Self>,
|
||||
EM: EventManager<E, I, S, Self>,
|
||||
F: Feedback<I, S>,
|
||||
@ -521,10 +516,7 @@ where
|
||||
input: &I,
|
||||
) -> Result<ExecuteInputResult, Error>
|
||||
where
|
||||
E: Executor<I>
|
||||
+ HasObservers<OT>
|
||||
+ HasExecHooks<EM, I, S, Self>
|
||||
+ HasObserversHooks<EM, I, OT, S, Self>,
|
||||
E: Executor<EM, I, S, Self> + HasObservers<OT> + HasObserversHooks<EM, I, OT, S, Self>,
|
||||
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Self>,
|
||||
EM: EventManager<E, I, S, Self>,
|
||||
{
|
||||
@ -533,17 +525,9 @@ where
|
||||
mark_feature_time!(state, PerfFeature::PreExecObservers);
|
||||
|
||||
start_timer!(state);
|
||||
executor.pre_exec(self, state, event_mgr, input)?;
|
||||
mark_feature_time!(state, PerfFeature::PreExec);
|
||||
|
||||
start_timer!(state);
|
||||
let exit_kind = executor.run_target(input)?;
|
||||
let exit_kind = executor.run_target(self, state, event_mgr, input)?;
|
||||
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;
|
||||
|
||||
start_timer!(state);
|
||||
|
@ -2,7 +2,7 @@ use core::{marker::PhantomData, mem::drop};
|
||||
|
||||
use crate::{
|
||||
corpus::Corpus,
|
||||
executors::{Executor, HasExecHooks, HasExecHooksTuple, HasObservers, HasObserversHooks},
|
||||
executors::{Executor, HasExecHooksTuple, HasObservers, HasObserversHooks},
|
||||
inputs::Input,
|
||||
mark_feature_time,
|
||||
observers::ObserversTuple,
|
||||
@ -21,10 +21,7 @@ pub struct TracingStage<C, EM, I, OT, S, TE, Z>
|
||||
where
|
||||
I: Input,
|
||||
C: Corpus<I>,
|
||||
TE: Executor<I>
|
||||
+ HasObservers<OT>
|
||||
+ HasExecHooks<EM, I, S, Z>
|
||||
+ HasObserversHooks<EM, I, OT, S, Z>,
|
||||
TE: Executor<EM, I, S, Z> + HasObservers<OT> + HasObserversHooks<EM, I, OT, S, Z>,
|
||||
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
|
||||
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
|
||||
I: Input,
|
||||
C: Corpus<I>,
|
||||
TE: Executor<I>
|
||||
+ HasObservers<OT>
|
||||
+ HasExecHooks<EM, I, S, Z>
|
||||
+ HasObserversHooks<EM, I, OT, S, Z>,
|
||||
TE: Executor<EM, I, S, Z> + HasObservers<OT> + HasObserversHooks<EM, I, OT, S, Z>,
|
||||
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
|
||||
S: HasClientPerfStats + HasExecutions + HasCorpus<C, I>,
|
||||
{
|
||||
@ -68,19 +62,12 @@ where
|
||||
mark_feature_time!(state, PerfFeature::PreExecObservers);
|
||||
|
||||
start_timer!(state);
|
||||
self.tracer_executor
|
||||
.pre_exec(fuzzer, state, manager, &input)?;
|
||||
mark_feature_time!(state, PerfFeature::PreExec);
|
||||
|
||||
start_timer!(state);
|
||||
drop(self.tracer_executor.run_target(&input)?);
|
||||
drop(
|
||||
self.tracer_executor
|
||||
.run_target(fuzzer, state, manager, &input)?,
|
||||
);
|
||||
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;
|
||||
|
||||
start_timer!(state);
|
||||
@ -96,10 +83,7 @@ impl<C, EM, I, OT, S, TE, Z> TracingStage<C, EM, I, OT, S, TE, Z>
|
||||
where
|
||||
I: Input,
|
||||
C: Corpus<I>,
|
||||
TE: Executor<I>
|
||||
+ HasObservers<OT>
|
||||
+ HasExecHooks<EM, I, S, Z>
|
||||
+ HasObserversHooks<EM, I, OT, S, Z>,
|
||||
TE: Executor<EM, I, S, Z> + HasObservers<OT> + HasObserversHooks<EM, I, OT, S, Z>,
|
||||
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
|
||||
S: HasClientPerfStats + HasExecutions + HasCorpus<C, I>,
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user