From b321675aa9f90ab239affe1f458df254b26c8ecc Mon Sep 17 00:00:00 2001 From: toka Date: Tue, 16 Mar 2021 18:48:40 +0900 Subject: [PATCH] add TimeoutFeedback and send ExitKind::Timeout from the handler --- fuzzers/libfuzzer_libpng/harness.cc | 2 -- fuzzers/libfuzzer_libpng/src/fuzzer.rs | 8 +++--- libafl/src/executors/inprocess.rs | 39 +++++++++++++------------ libafl/src/feedbacks/mod.rs | 40 ++++++++++++++++++++++++++ libafl/src/observers/mod.rs | 2 +- 5 files changed, 65 insertions(+), 26 deletions(-) diff --git a/fuzzers/libfuzzer_libpng/harness.cc b/fuzzers/libfuzzer_libpng/harness.cc index 91c54a168c..65faff685d 100644 --- a/fuzzers/libfuzzer_libpng/harness.cc +++ b/fuzzers/libfuzzer_libpng/harness.cc @@ -17,7 +17,6 @@ #include #include #include -#include #include @@ -84,7 +83,6 @@ static const int kPngHeaderSize = 8; // Roughly follows the libpng book example: // http://www.libpng.org/pub/png/book/chapter13.html extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - sleep(3); if (size < kPngHeaderSize) { return 0; } diff --git a/fuzzers/libfuzzer_libpng/src/fuzzer.rs b/fuzzers/libfuzzer_libpng/src/fuzzer.rs index 23a0810297..4640433c40 100644 --- a/fuzzers/libfuzzer_libpng/src/fuzzer.rs +++ b/fuzzers/libfuzzer_libpng/src/fuzzer.rs @@ -11,7 +11,7 @@ use libafl::{ QueueCorpusScheduler, }, events::setup_restarting_mgr, - executors::{inprocess::InProcessExecutor, Executor, ExitKind, inprocess::TimeoutExecutor}, + executors::{inprocess::InProcessExecutor, Executor, ExitKind}, feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback}, fuzzer::{Fuzzer, HasCorpusScheduler, StdFuzzer}, inputs::Input, @@ -150,7 +150,7 @@ fn fuzz(corpus_dirs: Vec, objective_dir: PathBuf, broker_port: u16) -> &mut state, &mut restarting_mgr, )?; - let mut tmexecutor = TimeoutExecutor::new(executor, 2); + // The actual target run starts here. // Call LLVMFUzzerInitialize() if present. unsafe { @@ -163,7 +163,7 @@ fn fuzz(corpus_dirs: Vec, objective_dir: PathBuf, broker_port: u16) -> if state.corpus().count() < 1 { state .load_initial_inputs( - &mut tmexecutor, + &mut executor, &mut restarting_mgr, fuzzer.scheduler(), &corpus_dirs, @@ -175,7 +175,7 @@ fn fuzz(corpus_dirs: Vec, objective_dir: PathBuf, broker_port: u16) -> println!("We imported {} inputs from disk.", state.corpus().count()); } - fuzzer.fuzz_loop(&mut state, &mut tmexecutor, &mut restarting_mgr)?; + fuzzer.fuzz_loop(&mut state, &mut executor, &mut restarting_mgr)?; // Never reached Ok(()) diff --git a/libafl/src/executors/inprocess.rs b/libafl/src/executors/inprocess.rs index 8914d144f7..b7247617e7 100644 --- a/libafl/src/executors/inprocess.rs +++ b/libafl/src/executors/inprocess.rs @@ -213,7 +213,7 @@ where I: Input + HasTargetBytes, OT: ObserversTuple, { - fn name(&self) -> &str{ + fn name(&self) -> &str { self.executor.name() } } @@ -241,8 +241,8 @@ where I: Input + HasTargetBytes, OT: ObserversTuple, { - pub fn new(executor: EX, exec_tmout: u64) -> Self{ - Self{ + pub fn new(executor: EX, exec_tmout: u64) -> Self { + Self { executor, exec_tmout: Duration::from_secs(exec_tmout), phantom: PhantomData, @@ -257,20 +257,25 @@ where OT: ObserversTuple, { #[inline] - fn pre_exec, S>(&mut self, _state: &mut S, _event_mgr: &mut EM, _input: &I,) -> Result<(), Error>{ - unsafe{ + 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{ + let it_value = Timeval { tv_sec: (milli_sec / 1000) as i64, tv_usec: (milli_sec % 1000) as i64, }; - let it_interval = Timeval{ + let it_interval = Timeval { tv_sec: 0, tv_usec: 0, }; setitimer( ITIMER_REAL, - &mut Itimerval{ + &mut Itimerval { it_interval, it_value, }, @@ -280,21 +285,20 @@ where self.executor.pre_exec(_state, _event_mgr, _input) } - fn run_target(&mut self, input: &I) -> Result{ - + fn run_target(&mut self, input: &I) -> Result { let run_result = self.executor.run_target(input); - unsafe{ - let it_value = Timeval{ + unsafe { + let it_value = Timeval { tv_sec: 0, tv_usec: 0, }; - let it_interval = Timeval{ + let it_interval = Timeval { tv_sec: 0, tv_usec: 0, }; setitimer( ITIMER_REAL, - &mut Itimerval{ + &mut Itimerval { it_interval, it_value, }, @@ -305,7 +309,6 @@ where } } - #[cfg(unix)] mod unix_signal_handler { use alloc::vec::Vec; @@ -373,9 +376,7 @@ mod unix_signal_handler { Signal::SigUser2 | Signal::SigAlarm => { (data.timeout_handler)(signal, info, void, data) }, - _ => { - (data.crash_handler)(signal, info, void, data) - }, + _ => (data.crash_handler)(signal, info, void, data), } } } @@ -426,7 +427,7 @@ mod unix_signal_handler { let obj_fitness = state .objectives_mut() - .is_interesting_all(&input, observers, ExitKind::Crash) + .is_interesting_all(&input, observers, ExitKind::Timeout) .expect("In timeout handler objectives failure."); if obj_fitness > 0 { state diff --git a/libafl/src/feedbacks/mod.rs b/libafl/src/feedbacks/mod.rs index 79dddaaf5d..5a156539eb 100644 --- a/libafl/src/feedbacks/mod.rs +++ b/libafl/src/feedbacks/mod.rs @@ -157,6 +157,46 @@ impl Default for CrashFeedback { } } +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct TimeoutFeedback {} + +impl Feedback for TimeoutFeedback +where + I: Input, +{ + fn is_interesting( + &mut self, + _input: &I, + _observers: &OT, + exit_kind: ExitKind, + ) -> Result { + if exit_kind == ExitKind::Timeout { + Ok(1) + } else { + Ok(0) + } + } +} + +impl Named for TimeoutFeedback { + #[inline] + fn name(&self) -> &str { + "TimeoutFeedback" + } +} + +impl TimeoutFeedback { + pub fn new() -> Self { + Self {} + } +} + +impl Default for TimeoutFeedback { + fn default() -> Self { + Self::new() + } +} + /// Nop feedback that annotates execution time in the new testcase, if any #[derive(Serialize, Deserialize, Clone, Debug)] pub struct TimeFeedback { diff --git a/libafl/src/observers/mod.rs b/libafl/src/observers/mod.rs index 72a28db4b5..7404ceeeb9 100644 --- a/libafl/src/observers/mod.rs +++ b/libafl/src/observers/mod.rs @@ -153,4 +153,4 @@ mod tests { postcard::from_bytes(&vec).unwrap(); assert_eq!(obv.0.name(), obv2.0.name()); } -} \ No newline at end of file +}