From cd7030443e6472bd43644df8b27404e241703243 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Wed, 17 Mar 2021 17:08:17 +0100 Subject: [PATCH] timeout executor file --- fuzzers/libfuzzer_libpng/src/fuzzer.rs | 2 +- libafl/src/executors/inprocess.rs | 153 ----------------------- libafl/src/executors/mod.rs | 2 + libafl/src/executors/timeout.rs | 165 +++++++++++++++++++++++++ 4 files changed, 168 insertions(+), 154 deletions(-) create mode 100644 libafl/src/executors/timeout.rs diff --git a/fuzzers/libfuzzer_libpng/src/fuzzer.rs b/fuzzers/libfuzzer_libpng/src/fuzzer.rs index 486dbd27ae..d78488d3fa 100644 --- a/fuzzers/libfuzzer_libpng/src/fuzzer.rs +++ b/fuzzers/libfuzzer_libpng/src/fuzzer.rs @@ -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, diff --git a/libafl/src/executors/inprocess.rs b/libafl/src/executors/inprocess.rs index beb34f71fb..e040bd18dd 100644 --- a/libafl/src/executors/inprocess.rs +++ b/libafl/src/executors/inprocess.rs @@ -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 -where - EX: Executor + HasObservers, - I: Input + HasTargetBytes, - OT: ObserversTuple, -{ - executor: EX, - exec_tmout: Duration, - phantom: PhantomData<(I, OT)>, -} - -impl Named for TimeoutExecutor -where - EX: Executor + HasObservers, - I: Input + HasTargetBytes, - OT: ObserversTuple, -{ - fn name(&self) -> &str { - self.executor.name() - } -} - -impl HasObservers for TimeoutExecutor -where - EX: Executor + HasObservers, - 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 TimeoutExecutor -where - EX: Executor + HasObservers, - I: Input + HasTargetBytes, - OT: ObserversTuple, -{ - pub fn new(executor: EX, exec_tmout: Duration) -> Self { - Self { - executor, - exec_tmout, - phantom: PhantomData, - } - } -} - -impl Executor for TimeoutExecutor -where - EX: Executor + HasObservers, - I: Input + HasTargetBytes, - OT: ObserversTuple, -{ - #[inline] - fn pre_exec, 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, 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 { - self.executor.run_target(input) - } -} - #[cfg(unix)] mod unix_signal_handler { use alloc::vec::Vec; diff --git a/libafl/src/executors/mod.rs b/libafl/src/executors/mod.rs index b3d25bc9ff..77cfdda548 100644 --- a/libafl/src/executors/mod.rs +++ b/libafl/src/executors/mod.rs @@ -2,6 +2,8 @@ pub mod inprocess; pub use inprocess::InProcessExecutor; +pub mod timeout; +pub use timeout::TimeoutExecutor; #[cfg(feature = "runtime")] pub mod runtime; diff --git a/libafl/src/executors/timeout.rs b/libafl/src/executors/timeout.rs new file mode 100644 index 0000000000..67be37a098 --- /dev/null +++ b/libafl/src/executors/timeout.rs @@ -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 +where + E: Executor + HasObservers, + I: Input + HasTargetBytes, + OT: ObserversTuple, +{ + executor: E, + exec_tmout: Duration, + phantom: PhantomData<(I, OT)>, +} + +impl Named for TimeoutExecutor +where + E: Executor + HasObservers, + I: Input + HasTargetBytes, + OT: ObserversTuple, +{ + fn name(&self) -> &str { + self.executor.name() + } +} + +impl HasObservers for TimeoutExecutor +where + E: Executor + HasObservers, + 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 TimeoutExecutor +where + E: Executor + HasObservers, + I: Input + HasTargetBytes, + OT: ObserversTuple, +{ + pub fn new(executor: E, exec_tmout: Duration) -> Self { + Self { + executor, + exec_tmout, + phantom: PhantomData, + } + } +} + +impl Executor for TimeoutExecutor +where + E: Executor + HasObservers, + I: Input + HasTargetBytes, + OT: ObserversTuple, +{ + #[inline] + fn pre_exec, 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, 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 { + self.executor.run_target(input) + } +} +