timeout executor file

This commit is contained in:
Andrea Fioraldi 2021-03-17 17:08:17 +01:00
parent 5d92871b27
commit cd7030443e
4 changed files with 168 additions and 154 deletions

View File

@ -12,7 +12,7 @@ use libafl::{
QueueCorpusScheduler, QueueCorpusScheduler,
}, },
events::setup_restarting_mgr, events::setup_restarting_mgr,
executors::{inprocess::InProcessExecutor, inprocess::TimeoutExecutor, Executor, ExitKind}, executors::{inprocess::InProcessExecutor, TimeoutExecutor, Executor, ExitKind},
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback}, feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
fuzzer::{Fuzzer, HasCorpusScheduler, StdFuzzer}, fuzzer::{Fuzzer, HasCorpusScheduler, StdFuzzer},
inputs::Input, inputs::Input,

View File

@ -3,13 +3,6 @@
use core::marker::PhantomData; use core::marker::PhantomData;
#[cfg(unix)]
use core::time::Duration;
#[cfg(unix)]
use std::os::raw::c_int;
#[cfg(unix)]
use std::ptr::null_mut;
#[cfg(unix)] #[cfg(unix)]
use core::{ use core::{
ptr::{self, write_volatile}, ptr::{self, write_volatile},
@ -172,152 +165,6 @@ where
} }
} }
#[repr(C)]
#[cfg(unix)]
struct Timeval {
pub tv_sec: i64,
pub tv_usec: i64,
}
#[repr(C)]
#[cfg(unix)]
struct Itimerval {
pub it_interval: Timeval,
pub it_value: Timeval,
}
#[cfg(unix)]
extern "C" {
fn setitimer(which: c_int, new_value: *mut Itimerval, old_value: *mut Itimerval) -> c_int;
}
#[cfg(unix)]
const ITIMER_REAL: c_int = 0;
//timeout excutor wrap a InProcessExecutor
#[cfg(unix)]
pub struct TimeoutExecutor<I, OT, EX>
where
EX: Executor<I> + HasObservers<OT>,
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
executor: EX,
exec_tmout: Duration,
phantom: PhantomData<(I, OT)>,
}
impl<I, OT, EX> Named for TimeoutExecutor<I, OT, EX>
where
EX: Executor<I> + HasObservers<OT>,
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
fn name(&self) -> &str {
self.executor.name()
}
}
impl<I, OT, EX> HasObservers<OT> for TimeoutExecutor<I, OT, EX>
where
EX: Executor<I> + HasObservers<OT>,
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
#[inline]
fn observers(&self) -> &OT {
self.executor.observers()
}
#[inline]
fn observers_mut(&mut self) -> &mut OT {
self.executor.observers_mut()
}
}
impl<I, OT, EX> TimeoutExecutor<I, OT, EX>
where
EX: Executor<I> + HasObservers<OT>,
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
pub fn new(executor: EX, exec_tmout: Duration) -> Self {
Self {
executor,
exec_tmout,
phantom: PhantomData,
}
}
}
impl<I, OT, EX> Executor<I> for TimeoutExecutor<I, OT, EX>
where
EX: Executor<I> + HasObservers<OT>,
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
#[inline]
fn pre_exec<EM: EventManager<I, S>, S>(
&mut self,
_state: &mut S,
_event_mgr: &mut EM,
_input: &I,
) -> Result<(), Error> {
unsafe {
let milli_sec = self.exec_tmout.as_millis();
let it_value = Timeval {
tv_sec: (milli_sec / 1000) as i64,
tv_usec: (milli_sec % 1000) as i64,
};
let it_interval = Timeval {
tv_sec: 0,
tv_usec: 0,
};
setitimer(
ITIMER_REAL,
&mut Itimerval {
it_interval,
it_value,
},
null_mut(),
);
}
self.executor.pre_exec(_state, _event_mgr, _input)
}
#[inline]
fn post_exec<EM: EventManager<I, S>, S>(
&mut self,
_state: &S,
_event_mgr: &mut EM,
_input: &I,
) -> Result<(), Error> {
unsafe {
let it_value = Timeval {
tv_sec: 0,
tv_usec: 0,
};
let it_interval = Timeval {
tv_sec: 0,
tv_usec: 0,
};
setitimer(
ITIMER_REAL,
&mut Itimerval {
it_interval,
it_value,
},
null_mut(),
);
}
self.executor.post_exec(_state, _event_mgr, _input)
}
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error> {
self.executor.run_target(input)
}
}
#[cfg(unix)] #[cfg(unix)]
mod unix_signal_handler { mod unix_signal_handler {
use alloc::vec::Vec; use alloc::vec::Vec;

View File

@ -2,6 +2,8 @@
pub mod inprocess; pub mod inprocess;
pub use inprocess::InProcessExecutor; pub use inprocess::InProcessExecutor;
pub mod timeout;
pub use timeout::TimeoutExecutor;
#[cfg(feature = "runtime")] #[cfg(feature = "runtime")]
pub mod runtime; pub mod runtime;

View File

@ -0,0 +1,165 @@
//! A TimeoutExecutor set a timeout before each target run
use core::{marker::PhantomData, time::Duration};
use crate::{
bolts::tuples::Named,
events::EventManager,
executors::{Executor, ExitKind, HasObservers},
inputs::{HasTargetBytes, Input},
observers::ObserversTuple,
Error,
};
#[cfg(unix)]
use std::os::raw::c_int;
#[cfg(unix)]
use std::ptr::null_mut;
#[repr(C)]
#[cfg(unix)]
struct Timeval {
pub tv_sec: i64,
pub tv_usec: i64,
}
#[repr(C)]
#[cfg(unix)]
struct Itimerval {
pub it_interval: Timeval,
pub it_value: Timeval,
}
#[cfg(unix)]
extern "C" {
fn setitimer(which: c_int, new_value: *mut Itimerval, old_value: *mut Itimerval) -> c_int;
}
#[cfg(unix)]
const ITIMER_REAL: c_int = 0;
/// The timeout excutor is a wrapper that set a timeout before each run
pub struct TimeoutExecutor<E, I, OT>
where
E: Executor<I> + HasObservers<OT>,
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
executor: E,
exec_tmout: Duration,
phantom: PhantomData<(I, OT)>,
}
impl<E, I, OT> Named for TimeoutExecutor<E, I, OT>
where
E: Executor<I> + HasObservers<OT>,
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
fn name(&self) -> &str {
self.executor.name()
}
}
impl<E, I, OT> HasObservers<OT> for TimeoutExecutor<E, I, OT>
where
E: Executor<I> + HasObservers<OT>,
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
#[inline]
fn observers(&self) -> &OT {
self.executor.observers()
}
#[inline]
fn observers_mut(&mut self) -> &mut OT {
self.executor.observers_mut()
}
}
impl<E, I, OT> TimeoutExecutor<E, I, OT>
where
E: Executor<I> + HasObservers<OT>,
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
pub fn new(executor: E, exec_tmout: Duration) -> Self {
Self {
executor,
exec_tmout,
phantom: PhantomData,
}
}
}
impl<E, I, OT> Executor<I> for TimeoutExecutor<E, I, OT>
where
E: Executor<I> + HasObservers<OT>,
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
#[inline]
fn pre_exec<EM: EventManager<I, S>, S>(
&mut self,
_state: &mut S,
_event_mgr: &mut EM,
_input: &I,
) -> Result<(), Error> {
#[cfg(unix)]
unsafe {
let milli_sec = self.exec_tmout.as_millis();
let it_value = Timeval {
tv_sec: (milli_sec / 1000) as i64,
tv_usec: (milli_sec % 1000) as i64,
};
let it_interval = Timeval {
tv_sec: 0,
tv_usec: 0,
};
setitimer(
ITIMER_REAL,
&mut Itimerval {
it_interval,
it_value,
},
null_mut(),
);
}
self.executor.pre_exec(_state, _event_mgr, _input)
}
#[inline]
fn post_exec<EM: EventManager<I, S>, S>(
&mut self,
_state: &S,
_event_mgr: &mut EM,
_input: &I,
) -> Result<(), Error> {
#[cfg(unix)]
unsafe {
let it_value = Timeval {
tv_sec: 0,
tv_usec: 0,
};
let it_interval = Timeval {
tv_sec: 0,
tv_usec: 0,
};
setitimer(
ITIMER_REAL,
&mut Itimerval {
it_interval,
it_value,
},
null_mut(),
);
}
self.executor.post_exec(_state, _event_mgr, _input)
}
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error> {
self.executor.run_target(input)
}
}