timeout executor file
This commit is contained in:
parent
5d92871b27
commit
cd7030443e
@ -12,7 +12,7 @@ use libafl::{
|
||||
QueueCorpusScheduler,
|
||||
},
|
||||
events::setup_restarting_mgr,
|
||||
executors::{inprocess::InProcessExecutor, inprocess::TimeoutExecutor, Executor, ExitKind},
|
||||
executors::{inprocess::InProcessExecutor, TimeoutExecutor, Executor, ExitKind},
|
||||
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
||||
fuzzer::{Fuzzer, HasCorpusScheduler, StdFuzzer},
|
||||
inputs::Input,
|
||||
|
@ -3,13 +3,6 @@
|
||||
|
||||
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)]
|
||||
use core::{
|
||||
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)]
|
||||
mod unix_signal_handler {
|
||||
use alloc::vec::Vec;
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
pub mod inprocess;
|
||||
pub use inprocess::InProcessExecutor;
|
||||
pub mod timeout;
|
||||
pub use timeout::TimeoutExecutor;
|
||||
#[cfg(feature = "runtime")]
|
||||
pub mod runtime;
|
||||
|
||||
|
165
libafl/src/executors/timeout.rs
Normal file
165
libafl/src/executors/timeout.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user