Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sure EM and Z remain consistent in InProcessExecutor #2873

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 25 additions & 21 deletions libafl/src/executors/inprocess/inner.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use core::{
ffi::c_void,
fmt::{self, Debug, Formatter},
marker::PhantomData,
ptr::{self, null, write_volatile},
sync::atomic::{compiler_fence, Ordering},
time::Duration,
Expand Down Expand Up @@ -33,14 +34,17 @@ use crate::{
};

/// 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
pub(super) observers: OT,
// Crash and timeout hah
/// Crash and timeout hah
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*hooks

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol

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
OT: Debug,
{
Expand All @@ -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;

#[inline]
Expand All @@ -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
OT: ObserversTuple<I, S>,
{
Expand All @@ -76,7 +80,7 @@ where
/// the code.
// TODO: Remove EM and Z from function bound and add it to struct instead to avoid possible type confusion
#[inline]
pub unsafe fn enter_target<EM, Z>(
pub unsafe fn enter_target(
&mut self,
fuzzer: &mut Z,
state: &mut S,
Expand Down Expand Up @@ -111,13 +115,7 @@ where

/// This function marks the boundary between the fuzzer and the target
#[inline]
pub fn leave_target<EM, Z>(
&mut self,
_fuzzer: &mut Z,
_state: &mut S,
_mgr: &mut EM,
_input: &I,
) {
pub fn leave_target(&mut self, _fuzzer: &mut Z, _state: &mut S, _mgr: &mut EM, _input: &I) {
unsafe {
let data = &raw mut GLOBAL_STATE;

Expand All @@ -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
HT: ExecutorHooksTuple<I, S>,
OT: ObserversTuple<I, S>,
S: HasExecutions + HasSolutions<I>,
{
/// 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,
observers: OT,
fuzzer: &mut Z,
Expand All @@ -150,7 +148,7 @@ where
S: HasCurrentTestcase<I> + HasSolutions<I>,
Z: HasObjective<Objective = OF>,
{
Self::with_timeout_generic::<E, EM, OF, Z>(
Self::with_timeout_generic::<E, OF>(
user_hooks,
observers,
fuzzer,
Expand All @@ -162,7 +160,7 @@ where

/// Create a new in mem executor with the default timeout and use batch mode(5 sec)
#[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,
observers: OT,
fuzzer: &mut Z,
Expand All @@ -179,7 +177,7 @@ where
S: HasCurrentTestcase<I> + HasSolutions<I>,
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,
)?;
me.hooks_mut().0.timer_mut().batch_mode = true;
Expand All @@ -194,7 +192,7 @@ where
/// * `observers` - the observers observing the target during execution
///
/// 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,
observers: OT,
_fuzzer: &mut Z,
Expand Down Expand Up @@ -238,7 +236,11 @@ where
*hooks.0.millis_sec_mut() = timeout.as_millis() as i64;
}

Ok(Self { observers, hooks })
Ok(Self {
observers,
hooks,
phantom: PhantomData,
})
}

/// The inprocess handlers
Expand All @@ -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
#[inline]
fn inprocess_hooks(&self) -> &InProcessHooks<I, S> {
Expand Down
55 changes: 30 additions & 25 deletions libafl/src/executors/inprocess/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,29 +40,32 @@ pub mod inner;
pub mod stateful;

/// 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
pub type HookableInProcessExecutor<'a, H, HT, I, OT, S> =
GenericInProcessExecutor<H, &'a mut H, HT, I, OT, S>;
pub type HookableInProcessExecutor<'a, EM, H, HT, I, OT, S, Z> =
GenericInProcessExecutor<EM, H, &'a mut H, HT, I, OT, S, Z>;
/// 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,
Box<dyn FnMut(&I) -> ExitKind>,
(),
I,
OT,
S,
Z,
>;

/// 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,
inner: GenericInProcessExecutorInner<HT, I, OT, S>,
inner: GenericInProcessExecutorInner<EM, HT, I, OT, S, Z>,
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
OT: Debug,
{
Expand All @@ -75,7 +78,7 @@ where
}

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
S: HasExecutions,
OT: ObserversTuple<I, S>,
Expand Down Expand Up @@ -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;

#[inline]
Expand All @@ -120,15 +125,15 @@ 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
H: FnMut(&I) -> ExitKind + Sized,
OT: ObserversTuple<I, S>,
S: HasCurrentTestcase<I> + HasExecutions + HasSolutions<I>,
I: Input,
{
/// 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,
observers: OT,
fuzzer: &mut Z,
Expand All @@ -140,7 +145,7 @@ where
OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>,
{
Self::with_timeout_generic::<EM, OF, Z>(
Self::with_timeout_generic::<OF>(
tuple_list!(),
harness_fn,
observers,
Expand All @@ -153,7 +158,7 @@ where

/// Create a new in mem executor with the default timeout and use batch mode(5 sec)
#[cfg(all(feature = "std", target_os = "linux"))]
pub fn batched_timeout<EM, OF, Z>(
pub fn batched_timeout<OF>(
harness_fn: &'a mut H,
observers: OT,
fuzzer: &mut Z,
Expand All @@ -166,7 +171,7 @@ where
OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>,
{
let inner = GenericInProcessExecutorInner::batched_timeout_generic::<Self, EM, OF, Z>(
let inner = GenericInProcessExecutorInner::batched_timeout_generic::<Self, OF>(
tuple_list!(),
observers,
fuzzer,
Expand All @@ -190,7 +195,7 @@ where
/// * `observers` - the observers observing the target during execution
///
/// 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,
observers: OT,
fuzzer: &mut Z,
Expand All @@ -203,7 +208,7 @@ where
OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>,
{
let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, EM, OF, Z>(
let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, OF>(
tuple_list!(),
observers,
fuzzer,
Expand All @@ -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
H: FnMut(&I) -> ExitKind + Sized,
HB: BorrowMut<H>,
Expand All @@ -230,7 +235,7 @@ where
I: Input,
{
/// 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,
harness_fn: HB,
observers: OT,
Expand All @@ -243,7 +248,7 @@ where
OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>,
{
Self::with_timeout_generic::<EM, OF, Z>(
Self::with_timeout_generic::<OF>(
user_hooks,
harness_fn,
observers,
Expand All @@ -256,7 +261,7 @@ where

/// Create a new in mem executor with the default timeout and use batch mode(5 sec)
#[cfg(all(feature = "std", target_os = "linux"))]
pub fn batched_timeout_generic<EM, OF, Z>(
pub fn batched_timeout_generic<OF>(
user_hooks: HT,
harness_fn: HB,
observers: OT,
Expand All @@ -271,7 +276,7 @@ where
OF: Feedback<EM, I, OT, S>,
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,
)?;

Expand All @@ -290,7 +295,7 @@ where
/// * `observers` - the observers observing the target during execution
///
/// 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,
harness_fn: HB,
observers: OT,
Expand All @@ -304,7 +309,7 @@ where
OF: Feedback<EM, I, OT, S>,
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,
)?;

Expand Down Expand Up @@ -349,8 +354,8 @@ pub trait HasInProcessHooks<I, S> {
fn inprocess_hooks_mut(&mut self) -> &mut InProcessHooks<I, S>;
}

impl<H, HB, HT, I, OT, S> HasInProcessHooks<I, S>
for GenericInProcessExecutor<H, HB, HT, I, OT, S>
impl<EM, H, HB, HT, I, OT, S, Z> HasInProcessHooks<I, S>
for GenericInProcessExecutor<EM, H, HB, HT, I, OT, S, Z>
{
/// the timeout handler
#[inline]
Expand Down
Loading
Loading