Skip to content

Commit

Permalink
Remove LibAFL InProcess Executor Timeout (#77)
Browse files Browse the repository at this point in the history
  • Loading branch information
novafacing authored Apr 12, 2024
1 parent d3072c1 commit 6695934
Show file tree
Hide file tree
Showing 9 changed files with 510 additions and 41 deletions.
12 changes: 0 additions & 12 deletions docs/src/config/common-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,6 @@ Note that this timeout is in virtual time, not real time. This means that whethe
simulation runs faster or slower than real time, the timeout will be accurate to the
target software's execution speed.

The fuzzing executor also has a timeout, which runs in real time. This timeout
is intended to detect situations where the fuzzer reaches a broken state where
it is no longer able to iterate (e.g. the virtual time timeout is not working)
and stop. By default, this timeout is set to 60 seconds and resets each
iteration. Only iterations which take more than 60 seconds will trigger the
timeout, but some very large fuzzing cases could exceed this time. To increase
it, for example to set the timeout to 10 minutes:

```python
@tsffs.executor_timeout = 600
```

### Setting Exception Solutions

The primary way TSFFS detects bugs is via CPU exceptions that are raised, but should not
Expand Down
2 changes: 1 addition & 1 deletion simics-rs/cargo-simics-build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ impl App {

let mut signed = Sign::new(&module_cdylib)?;

let mut signed_module_cdylib = module_cdylib
let signed_module_cdylib = module_cdylib
.parent()
.ok_or_else(|| Error::NoParentDirectory {
path: module_cdylib.to_path_buf(),
Expand Down
150 changes: 150 additions & 0 deletions src/fuzzer/executors/inprocess/inner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
use core::{
ffi::c_void,
fmt::{self, Debug, Formatter},
marker::PhantomData,
};

use libafl::{
events::{EventFirer, EventRestarter},
executors::{hooks::ExecutorHooksTuple, HasObservers},
fuzzer::HasObjective,
inputs::UsesInput,
observers::{ObserversTuple, UsesObservers},
state::{HasCorpus, HasExecutions, HasSolutions, State, UsesState},
Error,
};

/// The internal state of `GenericInProcessExecutor`.
pub(crate) struct GenericInProcessExecutorInner<HT, OT, S>
where
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
S: State,
{
/// The observers, observing each run
pub(super) observers: OT,
// Crash and timeout hah
pub(super) hooks: HT,
phantom: PhantomData<S>,
}

impl<HT, OT, S> Debug for GenericInProcessExecutorInner<HT, OT, S>
where
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S> + Debug,
S: State,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("GenericInProcessExecutorState")
.field("observers", &self.observers)
.finish_non_exhaustive()
}
}

impl<HT, OT, S> UsesState for GenericInProcessExecutorInner<HT, OT, S>
where
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
S: State,
{
type State = S;
}

impl<HT, OT, S> UsesObservers for GenericInProcessExecutorInner<HT, OT, S>
where
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
S: State,
{
type Observers = OT;
}

impl<HT, OT, S> HasObservers for GenericInProcessExecutorInner<HT, OT, S>
where
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
S: State,
{
#[inline]
fn observers(&self) -> &OT {
&self.observers
}

#[inline]
fn observers_mut(&mut self) -> &mut OT {
&mut self.observers
}
}

impl<HT, OT, S> GenericInProcessExecutorInner<HT, OT, S>
where
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
S: State,
{
/// This function marks the boundary between the fuzzer and the target
#[inline]
pub(crate) unsafe fn enter_target<EM, Z>(
&mut self,
_fuzzer: &mut Z,
_state: &mut <Self as UsesState>::State,
_mgr: &mut EM,
_input: &<Self as UsesInput>::Input,
_executor_ptr: *const c_void,
) {
}

/// This function marks the boundary between the fuzzer and the target
#[inline]
pub(crate) fn leave_target<EM, Z>(
&mut self,
_fuzzer: &mut Z,
_state: &mut <Self as UsesState>::State,
_mgr: &mut EM,
_input: &<Self as UsesInput>::Input,
) {
}
}

impl<HT, OT, S> GenericInProcessExecutorInner<HT, OT, S>
where
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
S: HasExecutions + HasSolutions + HasCorpus + State,
{
/// Create a new in mem executor.
/// Caution: crash and restart in one of them will lead to odd behavior if multiple are used,
/// depending on different corpus or state.
/// * `hooks` - the hooks run before and after the harness's execution
/// * `harness_fn` - the harness, executing the function
/// * `observers` - the observers observing the target during execution
/// This may return an error on unix, if signal handler setup fails
pub(crate) fn new<EM, OF, Z>(
hooks: HT,
observers: OT,
_fuzzer: &mut Z,
_event_mgr: &mut EM,
) -> Result<Self, Error>
where
EM: EventFirer<State = S> + EventRestarter,
Z: HasObjective<Objective = OF, State = S>,
{
Ok(Self {
observers,
hooks,
phantom: PhantomData,
})
}

/// The inprocess handlers
#[inline]
pub(crate) fn hooks(&self) -> &HT {
&self.hooks
}

/// The inprocess handlers (mutable)
#[inline]
pub(crate) fn hooks_mut(&mut self) -> &mut HT {
&mut self.hooks
}
}
Loading

0 comments on commit 6695934

Please sign in to comment.