Make sure EM and Z remain consistent in InProcessExecutor (#2873)

* Make sure EM and Z remain consistent in InProcessExecutor

* first make them compile

* a

* hah

* fix intel pt

* decouple fuzzer from em

* lol

* 3

* fix tcp

* fix

* fix

* fix

* fixer

* std

* fixer

* plz

* plzplzplz

* plzplzplzplz

* mm

* more

* symbol

* a

* a

* mm

* mmm

* mmmm

* mmmmm

* ff

---------

Co-authored-by: Toka <tokazerkje@outlook.com>
This commit is contained in:
Dominik Maier 2025-02-01 08:23:40 +01:00 committed by GitHub
parent 6cd97e7105
commit 84702d12a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 124 additions and 103 deletions

View File

@ -122,8 +122,8 @@ pub fn main() {
} }
.build(); .build();
type PTInProcessExecutor<'a, H, I, OT, S, T> = type PTInProcessExecutor<'a, EM, H, I, OT, S, T, Z> =
GenericInProcessExecutor<H, &'a mut H, (IntelPTHook<T>, ()), I, OT, S>; GenericInProcessExecutor<EM, H, &'a mut H, (IntelPTHook<T>, ()), I, OT, S, Z>;
// Create the executor for an in-process function with just one observer // Create the executor for an in-process function with just one observer
let mut executor = PTInProcessExecutor::with_timeout_generic( let mut executor = PTInProcessExecutor::with_timeout_generic(
tuple_list!(pt_hook), tuple_list!(pt_hook),

View File

@ -1,6 +1,7 @@
use core::{ use core::{
ffi::c_void, ffi::c_void,
fmt::{self, Debug, Formatter}, fmt::{self, Debug, Formatter},
marker::PhantomData,
ptr::{self, null, write_volatile}, ptr::{self, null, write_volatile},
sync::atomic::{compiler_fence, Ordering}, sync::atomic::{compiler_fence, Ordering},
time::Duration, time::Duration,
@ -33,14 +34,17 @@ use crate::{
}; };
/// The internal state of `GenericInProcessExecutor`. /// The internal state of `GenericInProcessExecutor`.
pub struct GenericInProcessExecutorInner<HT, I, OT, S> { pub struct GenericInProcessExecutorInner<EM, HT, I, OT, S, Z> {
/// The observers, observing each run /// The observers, observing each run
pub(super) observers: OT, pub(super) observers: OT,
// Crash and timeout hah /// Crash and timeout hooks
pub(super) hooks: (InProcessHooks<I, S>, HT), pub(super) hooks: (InProcessHooks<I, S>, HT),
/// `EM` and `Z` need to be tracked here to remain stable,
/// else we can run into type confusions between [`Self::enter_target`] and [`Self::leave_target`].
phantom: PhantomData<(EM, Z)>,
} }
impl<HT, I, OT, S> Debug for GenericInProcessExecutorInner<HT, I, OT, S> impl<EM, HT, I, OT, S, Z> Debug for GenericInProcessExecutorInner<EM, HT, I, OT, S, Z>
where where
OT: Debug, OT: Debug,
{ {
@ -51,7 +55,7 @@ where
} }
} }
impl<HT, I, OT, S> HasObservers for GenericInProcessExecutorInner<HT, I, OT, S> { impl<EM, HT, I, OT, S, Z> HasObservers for GenericInProcessExecutorInner<EM, HT, I, OT, S, Z> {
type Observers = OT; type Observers = OT;
#[inline] #[inline]
@ -65,7 +69,7 @@ impl<HT, I, OT, S> HasObservers for GenericInProcessExecutorInner<HT, I, OT, S>
} }
} }
impl<HT, I, OT, S> GenericInProcessExecutorInner<HT, I, OT, S> impl<EM, HT, I, OT, S, Z> GenericInProcessExecutorInner<EM, HT, I, OT, S, Z>
where where
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
{ {
@ -76,7 +80,7 @@ where
/// the code. /// the code.
// TODO: Remove EM and Z from function bound and add it to struct instead to avoid possible type confusion // TODO: Remove EM and Z from function bound and add it to struct instead to avoid possible type confusion
#[inline] #[inline]
pub unsafe fn enter_target<EM, Z>( pub unsafe fn enter_target(
&mut self, &mut self,
fuzzer: &mut Z, fuzzer: &mut Z,
state: &mut S, state: &mut S,
@ -111,13 +115,7 @@ where
/// This function marks the boundary between the fuzzer and the target /// This function marks the boundary between the fuzzer and the target
#[inline] #[inline]
pub fn leave_target<EM, Z>( pub fn leave_target(&mut self, _fuzzer: &mut Z, _state: &mut S, _mgr: &mut EM, _input: &I) {
&mut self,
_fuzzer: &mut Z,
_state: &mut S,
_mgr: &mut EM,
_input: &I,
) {
unsafe { unsafe {
let data = &raw mut GLOBAL_STATE; let data = &raw mut GLOBAL_STATE;
@ -127,14 +125,14 @@ where
} }
} }
impl<HT, I, OT, S> GenericInProcessExecutorInner<HT, I, OT, S> impl<EM, HT, I, OT, S, Z> GenericInProcessExecutorInner<EM, HT, I, OT, S, Z>
where where
HT: ExecutorHooksTuple<I, S>, HT: ExecutorHooksTuple<I, S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
S: HasExecutions + HasSolutions<I>, S: HasExecutions + HasSolutions<I>,
{ {
/// Create a new in mem executor with the default timeout (5 sec) /// Create a new in mem executor with the default timeout (5 sec)
pub fn generic<E, EM, OF, Z>( pub fn generic<E, OF>(
user_hooks: HT, user_hooks: HT,
observers: OT, observers: OT,
fuzzer: &mut Z, fuzzer: &mut Z,
@ -150,7 +148,7 @@ where
S: HasCurrentTestcase<I> + HasSolutions<I>, S: HasCurrentTestcase<I> + HasSolutions<I>,
Z: HasObjective<Objective = OF>, Z: HasObjective<Objective = OF>,
{ {
Self::with_timeout_generic::<E, EM, OF, Z>( Self::with_timeout_generic::<E, OF>(
user_hooks, user_hooks,
observers, observers,
fuzzer, fuzzer,
@ -162,7 +160,7 @@ where
/// Create a new in mem executor with the default timeout and use batch mode(5 sec) /// Create a new in mem executor with the default timeout and use batch mode(5 sec)
#[cfg(all(feature = "std", target_os = "linux"))] #[cfg(all(feature = "std", target_os = "linux"))]
pub fn batched_timeout_generic<E, EM, OF, Z>( pub fn batched_timeout_generic<E, OF>(
user_hooks: HT, user_hooks: HT,
observers: OT, observers: OT,
fuzzer: &mut Z, fuzzer: &mut Z,
@ -179,7 +177,7 @@ where
S: HasCurrentTestcase<I> + HasSolutions<I>, S: HasCurrentTestcase<I> + HasSolutions<I>,
Z: HasObjective<Objective = OF>, Z: HasObjective<Objective = OF>,
{ {
let mut me = Self::with_timeout_generic::<E, EM, OF, Z>( let mut me = Self::with_timeout_generic::<E, OF>(
user_hooks, observers, fuzzer, state, event_mgr, exec_tmout, user_hooks, observers, fuzzer, state, event_mgr, exec_tmout,
)?; )?;
me.hooks_mut().0.timer_mut().batch_mode = true; me.hooks_mut().0.timer_mut().batch_mode = true;
@ -194,7 +192,7 @@ where
/// * `observers` - the observers observing the target during execution /// * `observers` - the observers observing the target during execution
/// ///
/// This may return an error on unix, if signal handler setup fails /// This may return an error on unix, if signal handler setup fails
pub fn with_timeout_generic<E, EM, OF, Z>( pub fn with_timeout_generic<E, OF>(
user_hooks: HT, user_hooks: HT,
observers: OT, observers: OT,
_fuzzer: &mut Z, _fuzzer: &mut Z,
@ -238,7 +236,11 @@ where
*hooks.0.millis_sec_mut() = timeout.as_millis() as i64; *hooks.0.millis_sec_mut() = timeout.as_millis() as i64;
} }
Ok(Self { observers, hooks }) Ok(Self {
observers,
hooks,
phantom: PhantomData,
})
} }
/// The inprocess handlers /// The inprocess handlers
@ -254,7 +256,9 @@ where
} }
} }
impl<HT, I, OT, S> HasInProcessHooks<I, S> for GenericInProcessExecutorInner<HT, I, OT, S> { impl<EM, HT, I, OT, S, Z> HasInProcessHooks<I, S>
for GenericInProcessExecutorInner<EM, HT, I, OT, S, Z>
{
/// the timeout handler /// the timeout handler
#[inline] #[inline]
fn inprocess_hooks(&self) -> &InProcessHooks<I, S> { fn inprocess_hooks(&self) -> &InProcessHooks<I, S> {

View File

@ -40,29 +40,32 @@ pub mod inner;
pub mod stateful; pub mod stateful;
/// The process executor simply calls a target function, as mutable reference to a closure. /// The process executor simply calls a target function, as mutable reference to a closure.
pub type InProcessExecutor<'a, H, I, OT, S> = GenericInProcessExecutor<H, &'a mut H, (), I, OT, S>; pub type InProcessExecutor<'a, EM, H, I, OT, S, Z> =
GenericInProcessExecutor<EM, H, &'a mut H, (), I, OT, S, Z>;
/// The inprocess executor that allows hooks /// The inprocess executor that allows hooks
pub type HookableInProcessExecutor<'a, H, HT, I, OT, S> = pub type HookableInProcessExecutor<'a, EM, H, HT, I, OT, S, Z> =
GenericInProcessExecutor<H, &'a mut H, HT, I, OT, S>; GenericInProcessExecutor<EM, H, &'a mut H, HT, I, OT, S, Z>;
/// The process executor simply calls a target function, as boxed `FnMut` trait object /// The process executor simply calls a target function, as boxed `FnMut` trait object
pub type OwnedInProcessExecutor<I, OT, S> = GenericInProcessExecutor< pub type OwnedInProcessExecutor<EM, I, OT, S, Z> = GenericInProcessExecutor<
EM,
dyn FnMut(&I) -> ExitKind, dyn FnMut(&I) -> ExitKind,
Box<dyn FnMut(&I) -> ExitKind>, Box<dyn FnMut(&I) -> ExitKind>,
(), (),
I, I,
OT, OT,
S, S,
Z,
>; >;
/// The inmem executor simply calls a target function, then returns afterwards. /// The inmem executor simply calls a target function, then returns afterwards.
pub struct GenericInProcessExecutor<H, HB, HT, I, OT, S> { pub struct GenericInProcessExecutor<EM, H, HB, HT, I, OT, S, Z> {
harness_fn: HB, harness_fn: HB,
inner: GenericInProcessExecutorInner<HT, I, OT, S>, inner: GenericInProcessExecutorInner<EM, HT, I, OT, S, Z>,
phantom: PhantomData<(*const H, HB)>, phantom: PhantomData<(*const H, HB)>,
} }
impl<H, HB, HT, I, OT, S> Debug for GenericInProcessExecutor<H, HB, HT, I, OT, S> impl<EM, H, HB, HT, I, OT, S, Z> Debug for GenericInProcessExecutor<EM, H, HB, HT, I, OT, S, Z>
where where
OT: Debug, OT: Debug,
{ {
@ -75,7 +78,7 @@ where
} }
impl<EM, H, HB, HT, I, OT, S, Z> Executor<EM, I, S, Z> impl<EM, H, HB, HT, I, OT, S, Z> Executor<EM, I, S, Z>
for GenericInProcessExecutor<H, HB, HT, I, OT, S> for GenericInProcessExecutor<EM, H, HB, HT, I, OT, S, Z>
where where
S: HasExecutions, S: HasExecutions,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
@ -106,7 +109,9 @@ where
} }
} }
impl<H, HB, HT, I, OT, S> HasObservers for GenericInProcessExecutor<H, HB, HT, I, OT, S> { impl<EM, H, HB, HT, I, OT, S, Z> HasObservers
for GenericInProcessExecutor<EM, H, HB, HT, I, OT, S, Z>
{
type Observers = OT; type Observers = OT;
#[inline] #[inline]
@ -120,7 +125,7 @@ impl<H, HB, HT, I, OT, S> HasObservers for GenericInProcessExecutor<H, HB, HT, I
} }
} }
impl<'a, H, I, OT, S> InProcessExecutor<'a, H, I, OT, S> impl<'a, EM, H, I, OT, S, Z> InProcessExecutor<'a, EM, H, I, OT, S, Z>
where where
H: FnMut(&I) -> ExitKind + Sized, H: FnMut(&I) -> ExitKind + Sized,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
@ -128,7 +133,7 @@ where
I: Input, I: Input,
{ {
/// Create a new in mem executor with the default timeout (5 sec) /// Create a new in mem executor with the default timeout (5 sec)
pub fn new<EM, OF, Z>( pub fn new<OF>(
harness_fn: &'a mut H, harness_fn: &'a mut H,
observers: OT, observers: OT,
fuzzer: &mut Z, fuzzer: &mut Z,
@ -140,7 +145,7 @@ where
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>, Z: HasObjective<Objective = OF>,
{ {
Self::with_timeout_generic::<EM, OF, Z>( Self::with_timeout_generic::<OF>(
tuple_list!(), tuple_list!(),
harness_fn, harness_fn,
observers, observers,
@ -153,7 +158,7 @@ where
/// Create a new in mem executor with the default timeout and use batch mode(5 sec) /// Create a new in mem executor with the default timeout and use batch mode(5 sec)
#[cfg(all(feature = "std", target_os = "linux"))] #[cfg(all(feature = "std", target_os = "linux"))]
pub fn batched_timeout<EM, OF, Z>( pub fn batched_timeout<OF>(
harness_fn: &'a mut H, harness_fn: &'a mut H,
observers: OT, observers: OT,
fuzzer: &mut Z, fuzzer: &mut Z,
@ -166,7 +171,7 @@ where
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>, Z: HasObjective<Objective = OF>,
{ {
let inner = GenericInProcessExecutorInner::batched_timeout_generic::<Self, EM, OF, Z>( let inner = GenericInProcessExecutorInner::batched_timeout_generic::<Self, OF>(
tuple_list!(), tuple_list!(),
observers, observers,
fuzzer, fuzzer,
@ -190,7 +195,7 @@ where
/// * `observers` - the observers observing the target during execution /// * `observers` - the observers observing the target during execution
/// ///
/// This may return an error on unix, if signal handler setup fails /// This may return an error on unix, if signal handler setup fails
pub fn with_timeout<EM, OF, Z>( pub fn with_timeout<OF>(
harness_fn: &'a mut H, harness_fn: &'a mut H,
observers: OT, observers: OT,
fuzzer: &mut Z, fuzzer: &mut Z,
@ -203,7 +208,7 @@ where
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>, Z: HasObjective<Objective = OF>,
{ {
let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, EM, OF, Z>( let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, OF>(
tuple_list!(), tuple_list!(),
observers, observers,
fuzzer, fuzzer,
@ -220,7 +225,7 @@ where
} }
} }
impl<H, HB, HT, I, OT, S> GenericInProcessExecutor<H, HB, HT, I, OT, S> impl<EM, H, HB, HT, I, OT, S, Z> GenericInProcessExecutor<EM, H, HB, HT, I, OT, S, Z>
where where
H: FnMut(&I) -> ExitKind + Sized, H: FnMut(&I) -> ExitKind + Sized,
HB: BorrowMut<H>, HB: BorrowMut<H>,
@ -230,7 +235,7 @@ where
I: Input, I: Input,
{ {
/// Create a new in mem executor with the default timeout (5 sec) /// Create a new in mem executor with the default timeout (5 sec)
pub fn generic<EM, OF, Z>( pub fn generic<OF>(
user_hooks: HT, user_hooks: HT,
harness_fn: HB, harness_fn: HB,
observers: OT, observers: OT,
@ -243,7 +248,7 @@ where
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>, Z: HasObjective<Objective = OF>,
{ {
Self::with_timeout_generic::<EM, OF, Z>( Self::with_timeout_generic::<OF>(
user_hooks, user_hooks,
harness_fn, harness_fn,
observers, observers,
@ -256,7 +261,7 @@ where
/// Create a new in mem executor with the default timeout and use batch mode(5 sec) /// Create a new in mem executor with the default timeout and use batch mode(5 sec)
#[cfg(all(feature = "std", target_os = "linux"))] #[cfg(all(feature = "std", target_os = "linux"))]
pub fn batched_timeout_generic<EM, OF, Z>( pub fn batched_timeout_generic<OF>(
user_hooks: HT, user_hooks: HT,
harness_fn: HB, harness_fn: HB,
observers: OT, observers: OT,
@ -271,7 +276,7 @@ where
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>, Z: HasObjective<Objective = OF>,
{ {
let inner = GenericInProcessExecutorInner::batched_timeout_generic::<Self, EM, OF, Z>( let inner = GenericInProcessExecutorInner::batched_timeout_generic::<Self, OF>(
user_hooks, observers, fuzzer, state, event_mgr, exec_tmout, user_hooks, observers, fuzzer, state, event_mgr, exec_tmout,
)?; )?;
@ -290,7 +295,7 @@ where
/// * `observers` - the observers observing the target during execution /// * `observers` - the observers observing the target during execution
/// ///
/// This may return an error on unix, if signal handler setup fails /// This may return an error on unix, if signal handler setup fails
pub fn with_timeout_generic<EM, OF, Z>( pub fn with_timeout_generic<OF>(
user_hooks: HT, user_hooks: HT,
harness_fn: HB, harness_fn: HB,
observers: OT, observers: OT,
@ -304,7 +309,7 @@ where
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>, Z: HasObjective<Objective = OF>,
{ {
let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, EM, OF, Z>( let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, OF>(
user_hooks, observers, fuzzer, state, event_mgr, timeout, user_hooks, observers, fuzzer, state, event_mgr, timeout,
)?; )?;
@ -349,8 +354,8 @@ pub trait HasInProcessHooks<I, S> {
fn inprocess_hooks_mut(&mut self) -> &mut InProcessHooks<I, S>; fn inprocess_hooks_mut(&mut self) -> &mut InProcessHooks<I, S>;
} }
impl<H, HB, HT, I, OT, S> HasInProcessHooks<I, S> impl<EM, H, HB, HT, I, OT, S, Z> HasInProcessHooks<I, S>
for GenericInProcessExecutor<H, HB, HT, I, OT, S> for GenericInProcessExecutor<EM, H, HB, HT, I, OT, S, Z>
{ {
/// the timeout handler /// the timeout handler
#[inline] #[inline]

View File

@ -27,34 +27,37 @@ use crate::{
/// The process executor simply calls a target function, as mutable reference to a closure /// The process executor simply calls a target function, as mutable reference to a closure
/// The internal state of the executor is made available to the harness. /// The internal state of the executor is made available to the harness.
pub type StatefulInProcessExecutor<'a, ES, H, I, OT, S> = pub type StatefulInProcessExecutor<'a, EM, ES, H, I, OT, S, Z> =
StatefulGenericInProcessExecutor<ES, H, &'a mut H, (), I, OT, S>; StatefulGenericInProcessExecutor<EM, ES, H, &'a mut H, (), I, OT, S, Z>;
/// The process executor simply calls a target function, as boxed `FnMut` trait object /// The process executor simply calls a target function, as boxed `FnMut` trait object
/// The internal state of the executor is made available to the harness. /// The internal state of the executor is made available to the harness.
pub type OwnedInProcessExecutor<I, OT, S, ES> = StatefulGenericInProcessExecutor< pub type OwnedInProcessExecutor<EM, ES, I, OT, S, Z> = StatefulGenericInProcessExecutor<
EM,
ES,
dyn FnMut(&mut ES, &I) -> ExitKind, dyn FnMut(&mut ES, &I) -> ExitKind,
Box<dyn FnMut(&mut ES, &I) -> ExitKind>, Box<dyn FnMut(&mut ES, &I) -> ExitKind>,
(), (),
I, I,
OT, OT,
S, S,
ES, Z,
>; >;
/// The inmem executor simply calls a target function, then returns afterwards. /// The inmem executor simply calls a target function, then returns afterwards.
/// The harness can access the internal state of the executor. /// The harness can access the internal state of the executor.
pub struct StatefulGenericInProcessExecutor<ES, H, HB, HT, I, OT, S> { pub struct StatefulGenericInProcessExecutor<EM, ES, H, HB, HT, I, OT, S, Z> {
/// The harness function, being executed for each fuzzing loop execution /// The harness function, being executed for each fuzzing loop execution
harness_fn: HB, harness_fn: HB,
/// The state used as argument of the harness /// The state used as argument of the harness
pub exposed_executor_state: ES, pub exposed_executor_state: ES,
/// Inner state of the executor /// Inner state of the executor
pub inner: GenericInProcessExecutorInner<HT, I, OT, S>, pub inner: GenericInProcessExecutorInner<EM, HT, I, OT, S, Z>,
phantom: PhantomData<(ES, *const H)>, phantom: PhantomData<(ES, *const H)>,
} }
impl<H, HB, HT, I, OT, S, ES> Debug for StatefulGenericInProcessExecutor<ES, H, HB, HT, I, OT, S> impl<EM, ES, H, HB, HT, I, OT, S, Z> Debug
for StatefulGenericInProcessExecutor<EM, ES, H, HB, HT, I, OT, S, Z>
where where
OT: Debug, OT: Debug,
{ {
@ -67,7 +70,7 @@ where
} }
impl<EM, H, HB, HT, I, OT, S, Z, ES> Executor<EM, I, S, Z> impl<EM, H, HB, HT, I, OT, S, Z, ES> Executor<EM, I, S, Z>
for StatefulGenericInProcessExecutor<ES, H, HB, HT, I, OT, S> for StatefulGenericInProcessExecutor<EM, ES, H, HB, HT, I, OT, S, Z>
where where
H: FnMut(&mut ES, &mut S, &I) -> ExitKind + Sized, H: FnMut(&mut ES, &mut S, &I) -> ExitKind + Sized,
HB: BorrowMut<H>, HB: BorrowMut<H>,
@ -98,8 +101,8 @@ where
} }
} }
impl<H, HB, HT, I, OT, S, ES> HasObservers impl<EM, ES, H, HB, HT, I, OT, S, Z> HasObservers
for StatefulGenericInProcessExecutor<ES, H, HB, HT, I, OT, S> for StatefulGenericInProcessExecutor<EM, ES, H, HB, HT, I, OT, S, Z>
where where
H: FnMut(&mut ES, &mut S, &I) -> ExitKind + Sized, H: FnMut(&mut ES, &mut S, &I) -> ExitKind + Sized,
HB: BorrowMut<H>, HB: BorrowMut<H>,
@ -118,7 +121,7 @@ where
} }
} }
impl<'a, H, I, OT, S, ES> StatefulInProcessExecutor<'a, ES, H, I, OT, S> impl<'a, EM, ES, H, I, OT, S, Z> StatefulInProcessExecutor<'a, EM, ES, H, I, OT, S, Z>
where where
H: FnMut(&mut ES, &mut S, &I) -> ExitKind + Sized, H: FnMut(&mut ES, &mut S, &I) -> ExitKind + Sized,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
@ -126,7 +129,7 @@ where
I: Clone + Input, I: Clone + Input,
{ {
/// Create a new in mem executor with the default timeout (5 sec) /// Create a new in mem executor with the default timeout (5 sec)
pub fn new<EM, OF, Z>( pub fn new<OF>(
harness_fn: &'a mut H, harness_fn: &'a mut H,
exposed_executor_state: ES, exposed_executor_state: ES,
observers: OT, observers: OT,
@ -153,7 +156,7 @@ where
/// Create a new in mem executor with the default timeout and use batch mode(5 sec) /// Create a new in mem executor with the default timeout and use batch mode(5 sec)
#[cfg(all(feature = "std", target_os = "linux"))] #[cfg(all(feature = "std", target_os = "linux"))]
pub fn batched_timeout<EM, OF, Z>( pub fn batched_timeout<OF>(
harness_fn: &'a mut H, harness_fn: &'a mut H,
exposed_executor_state: ES, exposed_executor_state: ES,
observers: OT, observers: OT,
@ -167,7 +170,7 @@ where
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>, Z: HasObjective<Objective = OF>,
{ {
let inner = GenericInProcessExecutorInner::batched_timeout_generic::<Self, EM, OF, Z>( let inner = GenericInProcessExecutorInner::batched_timeout_generic::<Self, OF>(
tuple_list!(), tuple_list!(),
observers, observers,
fuzzer, fuzzer,
@ -192,7 +195,7 @@ where
/// * `observers` - the observers observing the target during execution /// * `observers` - the observers observing the target during execution
/// ///
/// This may return an error on unix, if signal handler setup fails /// This may return an error on unix, if signal handler setup fails
pub fn with_timeout<EM, OF, Z>( pub fn with_timeout<OF>(
harness_fn: &'a mut H, harness_fn: &'a mut H,
exposed_executor_state: ES, exposed_executor_state: ES,
observers: OT, observers: OT,
@ -206,7 +209,7 @@ where
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>, Z: HasObjective<Objective = OF>,
{ {
let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, EM, OF, Z>( let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, OF>(
tuple_list!(), tuple_list!(),
observers, observers,
fuzzer, fuzzer,
@ -224,7 +227,9 @@ where
} }
} }
impl<H, HB, HT, I, OT, S, ES> StatefulGenericInProcessExecutor<ES, H, HB, HT, I, OT, S> { impl<EM, ES, H, HB, HT, I, OT, S, Z>
StatefulGenericInProcessExecutor<EM, ES, H, HB, HT, I, OT, S, Z>
{
/// The executor state given to the harness /// The executor state given to the harness
pub fn exposed_executor_state(&self) -> &ES { pub fn exposed_executor_state(&self) -> &ES {
&self.exposed_executor_state &self.exposed_executor_state
@ -236,7 +241,8 @@ impl<H, HB, HT, I, OT, S, ES> StatefulGenericInProcessExecutor<ES, H, HB, HT, I,
} }
} }
impl<H, HB, HT, I, OT, S, ES> StatefulGenericInProcessExecutor<ES, H, HB, HT, I, OT, S> impl<EM, ES, H, HB, HT, I, OT, S, Z>
StatefulGenericInProcessExecutor<EM, ES, H, HB, HT, I, OT, S, Z>
where where
H: FnMut(&mut ES, &mut S, &I) -> ExitKind + Sized, H: FnMut(&mut ES, &mut S, &I) -> ExitKind + Sized,
HB: BorrowMut<H>, HB: BorrowMut<H>,
@ -246,7 +252,7 @@ where
S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>, S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>,
{ {
/// Create a new in mem executor with the default timeout (5 sec) /// Create a new in mem executor with the default timeout (5 sec)
pub fn generic<EM, OF, Z>( pub fn generic<OF>(
user_hooks: HT, user_hooks: HT,
harness_fn: HB, harness_fn: HB,
exposed_executor_state: ES, exposed_executor_state: ES,
@ -275,7 +281,7 @@ where
/// Create a new in mem executor with the default timeout and use batch mode(5 sec) /// Create a new in mem executor with the default timeout and use batch mode(5 sec)
#[cfg(all(feature = "std", target_os = "linux"))] #[cfg(all(feature = "std", target_os = "linux"))]
#[expect(clippy::too_many_arguments)] #[expect(clippy::too_many_arguments)]
pub fn batched_timeout_generic<EM, OF, Z>( pub fn batched_timeout_generic<OF>(
user_hooks: HT, user_hooks: HT,
harness_fn: HB, harness_fn: HB,
exposed_executor_state: ES, exposed_executor_state: ES,
@ -290,7 +296,7 @@ where
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>, Z: HasObjective<Objective = OF>,
{ {
let inner = GenericInProcessExecutorInner::batched_timeout_generic::<Self, EM, OF, Z>( let inner = GenericInProcessExecutorInner::batched_timeout_generic::<Self, OF>(
user_hooks, observers, fuzzer, state, event_mgr, exec_tmout, user_hooks, observers, fuzzer, state, event_mgr, exec_tmout,
)?; )?;
@ -311,7 +317,7 @@ where
/// ///
/// This may return an error on unix, if signal handler setup fails /// This may return an error on unix, if signal handler setup fails
#[expect(clippy::too_many_arguments)] #[expect(clippy::too_many_arguments)]
pub fn with_timeout_generic<EM, OF, Z>( pub fn with_timeout_generic<OF>(
user_hooks: HT, user_hooks: HT,
harness_fn: HB, harness_fn: HB,
exposed_executor_state: ES, exposed_executor_state: ES,
@ -326,7 +332,7 @@ where
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>, Z: HasObjective<Objective = OF>,
{ {
let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, EM, OF, Z>( let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, OF>(
user_hooks, observers, fuzzer, state, event_mgr, timeout, user_hooks, observers, fuzzer, state, event_mgr, timeout,
)?; )?;
@ -363,8 +369,8 @@ where
} }
} }
impl<H, HB, HT, I, OT, S, ES> HasInProcessHooks<I, S> impl<EM, ES, H, HB, HT, I, OT, S, Z> HasInProcessHooks<I, S>
for StatefulGenericInProcessExecutor<ES, H, HB, HT, I, OT, S> for StatefulGenericInProcessExecutor<EM, ES, H, HB, HT, I, OT, S, Z>
{ {
/// the timeout handler /// the timeout handler
#[inline] #[inline]

View File

@ -27,7 +27,7 @@ use crate::{
pub type StatefulInProcessForkExecutor<'a, EM, ES, H, I, OT, S, SP, Z> = pub type StatefulInProcessForkExecutor<'a, EM, ES, H, I, OT, S, SP, Z> =
StatefulGenericInProcessForkExecutor<'a, EM, ES, H, (), I, OT, S, SP, Z>; StatefulGenericInProcessForkExecutor<'a, EM, ES, H, (), I, OT, S, SP, Z>;
impl<'a, H, I, OT, S, SP, ES, EM, Z> StatefulInProcessForkExecutor<'a, EM, ES, H, I, OT, S, SP, Z> impl<'a, H, I, OT, S, SP, EM, ES, Z> StatefulInProcessForkExecutor<'a, EM, ES, H, I, OT, S, SP, Z>
where where
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
SP: ShMemProvider, SP: ShMemProvider,
@ -68,7 +68,7 @@ pub struct StatefulGenericInProcessForkExecutor<'a, EM, ES, H, HT, I, OT, S, SP,
pub inner: GenericInProcessForkExecutorInner<EM, HT, I, OT, S, SP, Z>, pub inner: GenericInProcessForkExecutorInner<EM, HT, I, OT, S, SP, Z>,
} }
impl<H, HT, I, OT, S, SP, ES, EM, Z> Debug impl<H, HT, I, OT, S, SP, EM, ES, Z> Debug
for StatefulGenericInProcessForkExecutor<'_, EM, ES, H, HT, I, OT, S, SP, Z> for StatefulGenericInProcessForkExecutor<'_, EM, ES, H, HT, I, OT, S, SP, Z>
where where
HT: Debug, HT: Debug,
@ -131,7 +131,7 @@ where
} }
} }
impl<'a, H, HT, I, OT, S, SP, ES, EM, Z> impl<'a, H, HT, I, OT, S, SP, EM, ES, Z>
StatefulGenericInProcessForkExecutor<'a, EM, ES, H, HT, I, OT, S, SP, Z> StatefulGenericInProcessForkExecutor<'a, EM, ES, H, HT, I, OT, S, SP, Z>
where where
HT: ExecutorHooksTuple<I, S>, HT: ExecutorHooksTuple<I, S>,
@ -178,7 +178,7 @@ where
} }
} }
impl<H, HT, I, OT, S, SP, ES, EM, Z> HasObservers impl<H, HT, I, OT, S, SP, EM, ES, Z> HasObservers
for StatefulGenericInProcessForkExecutor<'_, EM, ES, H, HT, I, OT, S, SP, Z> for StatefulGenericInProcessForkExecutor<'_, EM, ES, H, HT, I, OT, S, SP, Z>
{ {
type Observers = OT; type Observers = OT;

View File

@ -29,8 +29,8 @@ use crate::helper::{FridaInstrumentationHelper, FridaRuntimeTuple};
use crate::windows_hooks::initialize; use crate::windows_hooks::initialize;
/// The [`FridaInProcessExecutor`] is an [`Executor`] that executes the target in the same process, usinig [`frida`](https://frida.re/) for binary-only instrumentation. /// The [`FridaInProcessExecutor`] is an [`Executor`] that executes the target in the same process, usinig [`frida`](https://frida.re/) for binary-only instrumentation.
pub struct FridaInProcessExecutor<'a, 'b, 'c, H, I, OT, RT, S, TC> { pub struct FridaInProcessExecutor<'a, 'b, 'c, EM, H, I, OT, RT, S, TC, Z> {
base: InProcessExecutor<'a, H, I, OT, S>, base: InProcessExecutor<'a, EM, H, I, OT, S, Z>,
/// `thread_id` for the Stalker /// `thread_id` for the Stalker
thread_id: Option<u32>, thread_id: Option<u32>,
/// Frida's dynamic rewriting engine /// Frida's dynamic rewriting engine
@ -42,7 +42,8 @@ pub struct FridaInProcessExecutor<'a, 'b, 'c, H, I, OT, RT, S, TC> {
_phantom: PhantomData<&'b u8>, _phantom: PhantomData<&'b u8>,
} }
impl<H, I, OT, RT, S, TC> Debug for FridaInProcessExecutor<'_, '_, '_, H, I, OT, RT, S, TC> impl<EM, H, I, OT, RT, S, TC, Z> Debug
for FridaInProcessExecutor<'_, '_, '_, EM, H, I, OT, RT, S, TC, Z>
where where
OT: Debug, OT: Debug,
{ {
@ -56,7 +57,7 @@ where
} }
impl<EM, H, I, OT, RT, S, TC, Z> Executor<EM, I, S, Z> impl<EM, H, I, OT, RT, S, TC, Z> Executor<EM, I, S, Z>
for FridaInProcessExecutor<'_, '_, '_, H, I, OT, RT, S, TC> for FridaInProcessExecutor<'_, '_, '_, EM, H, I, OT, RT, S, TC, Z>
where where
H: FnMut(&I) -> ExitKind, H: FnMut(&I) -> ExitKind,
S: HasExecutions, S: HasExecutions,
@ -111,7 +112,9 @@ where
} }
} }
impl<H, I, OT, RT, S, TC> HasObservers for FridaInProcessExecutor<'_, '_, '_, H, I, OT, RT, S, TC> { impl<EM, H, I, OT, RT, S, TC, Z> HasObservers
for FridaInProcessExecutor<'_, '_, '_, EM, H, I, OT, RT, S, TC, Z>
{
type Observers = OT; type Observers = OT;
#[inline] #[inline]
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
@ -124,15 +127,15 @@ impl<H, I, OT, RT, S, TC> HasObservers for FridaInProcessExecutor<'_, '_, '_, H,
} }
} }
impl<'a, 'b, 'c, H, I, OT, RT, S> impl<'a, 'b, 'c, EM, H, I, OT, RT, S, Z>
FridaInProcessExecutor<'a, 'b, 'c, H, I, OT, RT, S, NopTargetBytesConverter<I>> FridaInProcessExecutor<'a, 'b, 'c, EM, H, I, OT, RT, S, NopTargetBytesConverter<I>, Z>
where where
RT: FridaRuntimeTuple, RT: FridaRuntimeTuple,
{ {
/// Creates a new [`FridaInProcessExecutor`]. /// Creates a new [`FridaInProcessExecutor`].
pub fn new( pub fn new(
gum: &'a Gum, gum: &'a Gum,
base: InProcessExecutor<'a, H, I, OT, S>, base: InProcessExecutor<'a, EM, H, I, OT, S, Z>,
helper: &'c mut FridaInstrumentationHelper<'b, RT>, helper: &'c mut FridaInstrumentationHelper<'b, RT>,
) -> Self { ) -> Self {
FridaInProcessExecutor::with_target_bytes_converter( FridaInProcessExecutor::with_target_bytes_converter(
@ -147,7 +150,7 @@ where
/// Creates a new [`FridaInProcessExecutor`] tracking the given `thread_id`. /// Creates a new [`FridaInProcessExecutor`] tracking the given `thread_id`.
pub fn on_thread( pub fn on_thread(
gum: &'a Gum, gum: &'a Gum,
base: InProcessExecutor<'a, H, I, OT, S>, base: InProcessExecutor<'a, EM, H, I, OT, S, Z>,
helper: &'c mut FridaInstrumentationHelper<'b, RT>, helper: &'c mut FridaInstrumentationHelper<'b, RT>,
thread_id: u32, thread_id: u32,
) -> Self { ) -> Self {
@ -161,14 +164,15 @@ where
} }
} }
impl<'a, 'b, 'c, H, I, OT, RT, S, TC> FridaInProcessExecutor<'a, 'b, 'c, H, I, OT, RT, S, TC> impl<'a, 'b, 'c, EM, H, I, OT, RT, S, TC, Z>
FridaInProcessExecutor<'a, 'b, 'c, EM, H, I, OT, RT, S, TC, Z>
where where
RT: FridaRuntimeTuple, RT: FridaRuntimeTuple,
{ {
/// Creates a new [`FridaInProcessExecutor`]. /// Creates a new [`FridaInProcessExecutor`].
pub fn with_target_bytes_converter( pub fn with_target_bytes_converter(
gum: &'a Gum, gum: &'a Gum,
base: InProcessExecutor<'a, H, I, OT, S>, base: InProcessExecutor<'a, EM, H, I, OT, S, Z>,
helper: &'c mut FridaInstrumentationHelper<'b, RT>, helper: &'c mut FridaInstrumentationHelper<'b, RT>,
thread_id: Option<u32>, thread_id: Option<u32>,
target_bytes_converter: TC, target_bytes_converter: TC,
@ -221,8 +225,8 @@ where
} }
#[cfg(windows)] #[cfg(windows)]
impl<'a, 'b, 'c, H, I, OT, RT, S, TC> HasInProcessHooks<I, S> impl<'a, 'b, 'c, EM, H, I, OT, RT, S, TC, Z> HasInProcessHooks<I, S>
for FridaInProcessExecutor<'a, 'b, 'c, H, I, OT, RT, S, TC> for FridaInProcessExecutor<'a, 'b, 'c, EM, H, I, OT, RT, S, TC, Z>
where where
H: FnMut(&I) -> ExitKind, H: FnMut(&I) -> ExitKind,
S: HasSolutions<I> + HasCurrentTestcase<I> + HasExecutions, S: HasSolutions<I> + HasCurrentTestcase<I> + HasExecutions,

View File

@ -42,11 +42,11 @@ use crate::EmulatorModules;
use crate::Qemu; use crate::Qemu;
use crate::{command::CommandManager, modules::EmulatorModuleTuple, Emulator, EmulatorDriver}; use crate::{command::CommandManager, modules::EmulatorModuleTuple, Emulator, EmulatorDriver};
type EmulatorInProcessExecutor<'a, C, CM, ED, ET, H, I, OT, S, SM> = type EmulatorInProcessExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> =
StatefulInProcessExecutor<'a, Emulator<C, CM, ED, ET, I, S, SM>, H, I, OT, S>; StatefulInProcessExecutor<'a, EM, Emulator<C, CM, ED, ET, I, S, SM>, H, I, OT, S, Z>;
pub struct QemuExecutor<'a, C, CM, ED, ET, H, I, OT, S, SM> { pub struct QemuExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> {
inner: EmulatorInProcessExecutor<'a, C, CM, ED, ET, H, I, OT, S, SM>, inner: EmulatorInProcessExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z>,
first_exec: bool, first_exec: bool,
} }
@ -133,7 +133,8 @@ pub unsafe fn inproc_qemu_timeout_handler<E, EM, ET, I, OF, S, Z>(
} }
} }
impl<C, CM, ED, ET, H, I, OT, S, SM> Debug for QemuExecutor<'_, C, CM, ED, ET, H, I, OT, S, SM> impl<C, CM, ED, EM, ET, H, I, OT, S, SM, Z> Debug
for QemuExecutor<'_, C, CM, ED, EM, ET, H, I, OT, S, SM, Z>
where where
OT: Debug, OT: Debug,
{ {
@ -144,7 +145,8 @@ where
} }
} }
impl<'a, C, CM, ED, ET, H, I, OT, S, SM> QemuExecutor<'a, C, CM, ED, ET, H, I, OT, S, SM> impl<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z>
QemuExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z>
where where
ET: EmulatorModuleTuple<I, S>, ET: EmulatorModuleTuple<I, S>,
H: FnMut(&mut Emulator<C, CM, ED, ET, I, S, SM>, &mut S, &I) -> ExitKind, H: FnMut(&mut Emulator<C, CM, ED, ET, I, S, SM>, &mut S, &I) -> ExitKind,
@ -152,7 +154,7 @@ where
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
S: Unpin + HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>, S: Unpin + HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>,
{ {
pub fn new<EM, OF, Z>( pub fn new<OF>(
emulator: Emulator<C, CM, ED, ET, I, S, SM>, emulator: Emulator<C, CM, ED, ET, I, S, SM>,
harness_fn: &'a mut H, harness_fn: &'a mut H,
observers: OT, observers: OT,
@ -207,7 +209,7 @@ where
} }
inner.inprocess_hooks_mut().timeout_handler = inproc_qemu_timeout_handler::< inner.inprocess_hooks_mut().timeout_handler = inproc_qemu_timeout_handler::<
StatefulInProcessExecutor<'a, Emulator<C, CM, ED, ET, I, S, SM>, H, I, OT, S>, StatefulInProcessExecutor<'a, EM, Emulator<C, CM, ED, ET, I, S, SM>, H, I, OT, S, Z>,
EM, EM,
ET, ET,
I, I,
@ -222,7 +224,7 @@ where
}) })
} }
pub fn inner(&self) -> &EmulatorInProcessExecutor<'a, C, CM, ED, ET, H, I, OT, S, SM> { pub fn inner(&self) -> &EmulatorInProcessExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> {
&self.inner &self.inner
} }
@ -233,13 +235,13 @@ where
pub fn inner_mut( pub fn inner_mut(
&mut self, &mut self,
) -> &mut EmulatorInProcessExecutor<'a, C, CM, ED, ET, H, I, OT, S, SM> { ) -> &mut EmulatorInProcessExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> {
&mut self.inner &mut self.inner
} }
} }
impl<C, CM, ED, EM, ET, H, I, OT, S, SM, Z> Executor<EM, I, S, Z> impl<C, CM, ED, EM, ET, H, I, OT, S, SM, Z> Executor<EM, I, S, Z>
for QemuExecutor<'_, C, CM, ED, ET, H, I, OT, S, SM> for QemuExecutor<'_, C, CM, ED, EM, ET, H, I, OT, S, SM, Z>
where where
C: Clone, C: Clone,
CM: CommandManager<C, ED, ET, I, S, SM, Commands = C>, CM: CommandManager<C, ED, ET, I, S, SM, Commands = C>,
@ -279,8 +281,8 @@ where
} }
} }
impl<C, CM, ED, ET, H, I, OT, S, SM> HasObservers impl<C, CM, ED, EM, ET, H, I, OT, S, SM, Z> HasObservers
for QemuExecutor<'_, C, CM, ED, ET, H, I, OT, S, SM> for QemuExecutor<'_, C, CM, ED, EM, ET, H, I, OT, S, SM, Z>
where where
ET: EmulatorModuleTuple<I, S>, ET: EmulatorModuleTuple<I, S>,
H: FnMut(&mut Emulator<C, CM, ED, ET, I, S, SM>, &mut S, &I) -> ExitKind, H: FnMut(&mut Emulator<C, CM, ED, ET, I, S, SM>, &mut S, &I) -> ExitKind,