From 2474691623a22e8f89be831f63f5c988a9e4e5c4 Mon Sep 17 00:00:00 2001 From: "Dongjia \"toka\" Zhang" Date: Sat, 30 Sep 2023 18:34:08 +0200 Subject: [PATCH] Fix libjpeg fuzzer (#1582) * Revert "Insert into corpus if feedback is_interesting on crash/timeout (#1327)" This reverts commit 871dfa0a013f31f84e43e125105febca2f137049. * unused --- libafl/src/executors/inprocess.rs | 210 +++++++++-------------------- libafl_frida/src/executor.rs | 4 +- libafl_qemu/src/executor.rs | 18 +-- libafl_targets/src/windows_asan.rs | 15 +-- 4 files changed, 78 insertions(+), 169 deletions(-) diff --git a/libafl/src/executors/inprocess.rs b/libafl/src/executors/inprocess.rs index 488163c626..cb5b5a551c 100644 --- a/libafl/src/executors/inprocess.rs +++ b/libafl/src/executors/inprocess.rs @@ -25,7 +25,6 @@ use core::{ #[cfg(all(feature = "std", unix))] use std::intrinsics::transmute; -use libafl_bolts::current_time; #[cfg(all(unix, not(miri)))] use libafl_bolts::os::unix_signals::setup_signal_handler; #[cfg(all(feature = "std", unix))] @@ -50,11 +49,10 @@ use crate::{ events::{EventFirer, EventRestarter}, executors::{Executor, ExitKind, HasObservers}, feedbacks::Feedback, - fuzzer::{HasFeedback, HasObjective, HasScheduler}, + fuzzer::HasObjective, inputs::UsesInput, observers::{ObserversTuple, UsesObservers}, - schedulers::Scheduler, - state::{HasClientPerfMonitor, HasCorpus, HasExecutions, HasSolutions, UsesState}, + state::{HasClientPerfMonitor, HasCorpus, HasSolutions, UsesState}, Error, }; @@ -171,7 +169,7 @@ where H: FnMut(&::Input) -> ExitKind + ?Sized, HB: BorrowMut, OT: ObserversTuple, - S: HasSolutions + HasClientPerfMonitor + HasCorpus + HasExecutions, + S: HasSolutions + HasClientPerfMonitor + HasCorpus, { /// Create a new in mem executor. /// Caution: crash and restart in one of them will lead to odd behavior if multiple are used, @@ -179,7 +177,7 @@ where /// * `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 fn new( + pub fn new( harness_fn: HB, observers: OT, _fuzzer: &mut Z, @@ -189,13 +187,10 @@ where where Self: Executor, EM: EventFirer + EventRestarter, - CF: Feedback, OF: Feedback, - Z: HasObjective - + HasFeedback - + HasScheduler, + Z: HasObjective, { - let handlers = InProcessHandlers::new::()?; + let handlers = InProcessHandlers::new::()?; #[cfg(windows)] // Some initialization necessary for windows. unsafe { @@ -258,7 +253,7 @@ where H: FnMut(&::Input) -> ExitKind + ?Sized, HB: BorrowMut, OT: ObserversTuple, - S: HasSolutions + HasClientPerfMonitor + HasCorpus + HasExecutions, + S: HasSolutions + HasClientPerfMonitor + HasCorpus, { /// the timeout handler #[inline] @@ -348,30 +343,27 @@ impl InProcessHandlers { /// Create new [`InProcessHandlers`]. #[cfg(not(all(windows, feature = "std")))] - pub fn new() -> Result + pub fn new() -> Result where E: Executor + HasObservers, EM: EventFirer + EventRestarter, - CF: Feedback, OF: Feedback, - E::State: HasSolutions + HasClientPerfMonitor + HasCorpus + HasExecutions, - Z: HasObjective - + HasFeedback - + HasScheduler, + E::State: HasSolutions + HasClientPerfMonitor + HasCorpus, + Z: HasObjective, { #[cfg(unix)] #[cfg_attr(miri, allow(unused_variables))] unsafe { let data = &mut GLOBAL_STATE; #[cfg(feature = "std")] - unix_signal_handler::setup_panic_hook::(); + unix_signal_handler::setup_panic_hook::(); #[cfg(not(miri))] setup_signal_handler(data)?; compiler_fence(Ordering::SeqCst); Ok(Self { - crash_handler: unix_signal_handler::inproc_crash_handler:: + crash_handler: unix_signal_handler::inproc_crash_handler:: as *const c_void, - timeout_handler: unix_signal_handler::inproc_timeout_handler:: + timeout_handler: unix_signal_handler::inproc_timeout_handler:: as *const _, }) } @@ -381,28 +373,25 @@ impl InProcessHandlers { /// Create new [`InProcessHandlers`]. #[cfg(all(windows, feature = "std"))] - pub fn new() -> Result + pub fn new() -> Result where E: Executor + HasObservers + HasInProcessHandlers, EM: EventFirer + EventRestarter, - CF: Feedback, OF: Feedback, - E::State: HasSolutions + HasClientPerfMonitor + HasCorpus + HasExecutions, - Z: HasObjective - + HasFeedback - + HasScheduler, + E::State: HasSolutions + HasClientPerfMonitor + HasCorpus, + Z: HasObjective, { unsafe { let data = &mut GLOBAL_STATE; #[cfg(feature = "std")] - windows_exception_handler::setup_panic_hook::(); + windows_exception_handler::setup_panic_hook::(); setup_exception_handler(data)?; compiler_fence(Ordering::SeqCst); Ok(Self { - crash_handler: windows_exception_handler::inproc_crash_handler:: + crash_handler: windows_exception_handler::inproc_crash_handler:: as *const _, - timeout_handler: windows_exception_handler::inproc_timeout_handler:: + timeout_handler: windows_exception_handler::inproc_timeout_handler:: as *const c_void, }) } @@ -589,7 +578,7 @@ use crate::{ #[inline] #[allow(clippy::too_many_arguments)] /// Save state if it is an objective -pub fn run_observers_and_save_state( +pub fn run_observers_and_save_state( executor: &mut E, state: &mut E::State, input: &::Input, @@ -599,12 +588,9 @@ pub fn run_observers_and_save_state( ) where E: HasObservers, EM: EventFirer + EventRestarter, - CF: Feedback, OF: Feedback, - E::State: HasSolutions + HasClientPerfMonitor + HasCorpus + HasExecutions, - Z: HasObjective - + HasFeedback - + HasScheduler, + E::State: HasSolutions + HasClientPerfMonitor + HasCorpus, + Z: HasObjective, { let observers = executor.observers_mut(); @@ -612,44 +598,6 @@ pub fn run_observers_and_save_state( .post_exec_all(state, input, &exitkind) .expect("Observers post_exec_all failed"); - let interesting_for_corpus = fuzzer - .feedback_mut() - .is_interesting(state, event_mgr, input, observers, &exitkind) - .expect("In run_observers_and_save_state feedback failure."); - - if interesting_for_corpus { - let mut new_testcase = Testcase::with_executions(input.clone(), *state.executions()); - new_testcase.add_metadata(exitkind); - new_testcase.set_parent_id_optional(*state.corpus().current()); - fuzzer - .feedback_mut() - .append_metadata(state, observers, &mut new_testcase) - .expect("Failed adding metadata"); - let idx = state - .corpus_mut() - .add(new_testcase) - .expect("In run_observers_and_save_state corpus failure."); - fuzzer - .scheduler_mut() - .on_add(state, idx) - .expect("Could not add to scheduler in run_observers_and_save_state."); - event_mgr - .fire( - state, - Event::NewTestcase { - input: input.clone(), - observers_buf: None, - exit_kind: exitkind, - corpus_size: state.corpus().count(), - client_config: event_mgr.configuration(), - time: current_time(), - executions: *state.executions(), - forward_id: None, - }, - ) - .expect("Could not add the testcase in run_observers_and_save_state"); - } - let interesting = fuzzer .objective_mut() .is_interesting(state, event_mgr, input, observers, &exitkind) @@ -704,9 +652,9 @@ mod unix_signal_handler { Executor, ExitKind, HasObservers, }, feedbacks::Feedback, - fuzzer::{HasFeedback, HasObjective, HasScheduler}, + fuzzer::HasObjective, inputs::UsesInput, - state::{HasClientPerfMonitor, HasCorpus, HasExecutions, HasSolutions}, + state::{HasClientPerfMonitor, HasCorpus, HasSolutions}, }; pub(crate) type HandlerFuncPtr = @@ -762,16 +710,13 @@ mod unix_signal_handler { /// invokes the `post_exec` hook on all observer in case of panic #[cfg(feature = "std")] - pub fn setup_panic_hook() + pub fn setup_panic_hook() where E: HasObservers, EM: EventFirer + EventRestarter, - CF: Feedback, OF: Feedback, - E::State: HasSolutions + HasClientPerfMonitor + HasCorpus + HasExecutions, - Z: HasObjective - + HasFeedback - + HasScheduler, + E::State: HasSolutions + HasClientPerfMonitor + HasCorpus, + Z: HasObjective, { let old_hook = panic::take_hook(); panic::set_hook(Box::new(move |panic_info| { @@ -786,7 +731,7 @@ mod unix_signal_handler { let fuzzer = data.fuzzer_mut::(); let event_mgr = data.event_mgr_mut::(); - run_observers_and_save_state::( + run_observers_and_save_state::( executor, state, input, @@ -804,7 +749,7 @@ mod unix_signal_handler { } #[cfg(unix)] - pub(crate) unsafe fn inproc_timeout_handler( + pub(crate) unsafe fn inproc_timeout_handler( _signal: Signal, _info: siginfo_t, _context: &mut ucontext_t, @@ -812,12 +757,9 @@ mod unix_signal_handler { ) where E: HasObservers, EM: EventFirer + EventRestarter, - CF: Feedback, OF: Feedback, - E::State: HasSolutions + HasClientPerfMonitor + HasCorpus + HasExecutions, - Z: HasObjective - + HasFeedback - + HasScheduler, + E::State: HasSolutions + HasClientPerfMonitor + HasCorpus, + Z: HasObjective, { if !data.timeout_executor_ptr.is_null() && data.timeout_executor_mut::().handle_timeout(data) @@ -838,7 +780,7 @@ mod unix_signal_handler { log::error!("Timeout in fuzz run."); - run_observers_and_save_state::( + run_observers_and_save_state::( executor, state, input, @@ -854,7 +796,7 @@ mod unix_signal_handler { /// Will be used for signal handling. /// It will store the current State to shmem, then exit. #[allow(clippy::too_many_lines)] - pub(crate) unsafe fn inproc_crash_handler( + pub(crate) unsafe fn inproc_crash_handler( signal: Signal, _info: siginfo_t, _context: &mut ucontext_t, @@ -862,12 +804,9 @@ mod unix_signal_handler { ) where E: Executor + HasObservers, EM: EventFirer + EventRestarter, - CF: Feedback, OF: Feedback, - E::State: HasSolutions + HasClientPerfMonitor + HasCorpus + HasExecutions, - Z: HasObjective - + HasFeedback - + HasScheduler, + E::State: HasSolutions + HasClientPerfMonitor + HasCorpus, + Z: HasObjective, { #[cfg(all(target_os = "android", target_arch = "aarch64"))] let _context = &mut *(((_context as *mut _ as *mut libc::c_void as usize) + 128) @@ -898,7 +837,7 @@ mod unix_signal_handler { log::error!("{}", std::str::from_utf8(&bsod).unwrap()); } - run_observers_and_save_state::( + run_observers_and_save_state::( executor, state, input, @@ -969,23 +908,20 @@ pub mod windows_asan_handler { Executor, ExitKind, HasObservers, }, feedbacks::Feedback, - fuzzer::{HasFeedback, HasObjective, HasScheduler}, + fuzzer::HasObjective, inputs::UsesInput, - state::{HasClientPerfMonitor, HasCorpus, HasExecutions, HasSolutions}, + state::{HasClientPerfMonitor, HasCorpus, HasSolutions}, }; /// # Safety /// ASAN deatch handler - pub unsafe extern "C" fn asan_death_handler() + pub unsafe extern "C" fn asan_death_handler() where E: Executor + HasObservers, EM: EventFirer + EventRestarter, - CF: Feedback, OF: Feedback, - E::State: HasSolutions + HasClientPerfMonitor + HasCorpus + HasExecutions, - Z: HasObjective - + HasFeedback - + HasScheduler, + E::State: HasSolutions + HasClientPerfMonitor + HasCorpus, + Z: HasObjective, { let data = &mut GLOBAL_STATE; data.set_in_handler(true); @@ -1040,7 +976,7 @@ pub mod windows_asan_handler { // Make sure we don't crash in the crash handler forever. let input = data.take_current_input::<::Input>(); - run_observers_and_save_state::( + run_observers_and_save_state::( executor, state, input, @@ -1085,9 +1021,9 @@ mod windows_exception_handler { Executor, ExitKind, HasObservers, }, feedbacks::Feedback, - fuzzer::{HasFeedback, HasObjective, HasScheduler}, + fuzzer::HasObjective, inputs::UsesInput, - state::{HasClientPerfMonitor, HasCorpus, HasExecutions, HasSolutions}, + state::{HasClientPerfMonitor, HasCorpus, HasSolutions}, }; pub(crate) type HandlerFuncPtr = @@ -1123,16 +1059,13 @@ mod windows_exception_handler { /// invokes the `post_exec` hook on all observer in case of panic #[cfg(feature = "std")] - pub fn setup_panic_hook() + pub fn setup_panic_hook() where E: HasObservers, EM: EventFirer + EventRestarter, - CF: Feedback, OF: Feedback, - E::State: HasSolutions + HasClientPerfMonitor + HasCorpus + HasExecutions, - Z: HasObjective - + HasFeedback - + HasScheduler, + E::State: HasSolutions + HasClientPerfMonitor + HasCorpus, + Z: HasObjective, { let old_hook = panic::take_hook(); panic::set_hook(Box::new(move |panic_info| { @@ -1165,7 +1098,7 @@ mod windows_exception_handler { let input = data.take_current_input::<::Input>(); - run_observers_and_save_state::( + run_observers_and_save_state::( executor, state, input, @@ -1184,19 +1117,16 @@ mod windows_exception_handler { } /// Timeout handler for windows - pub unsafe extern "system" fn inproc_timeout_handler( + pub unsafe extern "system" fn inproc_timeout_handler( _p0: *mut u8, global_state: *mut c_void, _p1: *mut u8, ) where E: HasObservers + HasInProcessHandlers, EM: EventFirer + EventRestarter, - CF: Feedback, OF: Feedback, - E::State: HasSolutions + HasClientPerfMonitor + HasCorpus + HasExecutions, - Z: HasObjective - + HasFeedback - + HasScheduler, + E::State: HasSolutions + HasClientPerfMonitor + HasCorpus, + Z: HasObjective, { let data: &mut InProcessExecutorHandlerData = &mut *(global_state as *mut InProcessExecutorHandlerData); @@ -1230,7 +1160,7 @@ mod windows_exception_handler { .unwrap(); data.timeout_input_ptr = ptr::null_mut(); - run_observers_and_save_state::( + run_observers_and_save_state::( executor, state, input, @@ -1251,18 +1181,15 @@ mod windows_exception_handler { } #[allow(clippy::too_many_lines)] - pub(crate) unsafe fn inproc_crash_handler( + pub(crate) unsafe fn inproc_crash_handler( exception_pointers: *mut EXCEPTION_POINTERS, data: &mut InProcessExecutorHandlerData, ) where E: Executor + HasObservers, EM: EventFirer + EventRestarter, - CF: Feedback, OF: Feedback, - E::State: HasSolutions + HasClientPerfMonitor + HasCorpus + HasExecutions, - Z: HasObjective - + HasFeedback - + HasScheduler, + E::State: HasSolutions + HasClientPerfMonitor + HasCorpus, + Z: HasObjective, { // Have we set a timer_before? if data.ptp_timer.is_some() { @@ -1352,7 +1279,7 @@ mod windows_exception_handler { if is_crash { let input = data.take_current_input::<::Input>(); - run_observers_and_save_state::( + run_observers_and_save_state::( executor, state, input, @@ -1870,11 +1797,11 @@ impl<'a, H, OT, S, SP> InProcessForkExecutor<'a, H, OT, S, SP> where H: FnMut(&S::Input) -> ExitKind + ?Sized, OT: ObserversTuple, - S: UsesInput + HasCorpus, + S: UsesInput, SP: ShMemProvider, { /// Creates a new [`InProcessForkExecutor`] - pub fn new( + pub fn new( harness_fn: &'a mut H, observers: OT, _fuzzer: &mut Z, @@ -1884,12 +1811,9 @@ where ) -> Result where EM: EventFirer + EventRestarter, - CF: Feedback, OF: Feedback, S: HasSolutions + HasClientPerfMonitor, - Z: HasObjective - + HasFeedback - + HasScheduler, + Z: HasObjective, { let handlers = InChildProcessHandlers::new::()?; Ok(Self { @@ -1918,13 +1842,13 @@ where impl<'a, H, OT, S, SP> TimeoutInProcessForkExecutor<'a, H, OT, S, SP> where H: FnMut(&S::Input) -> ExitKind + ?Sized, - S: UsesInput + HasCorpus, + S: UsesInput, OT: ObserversTuple, SP: ShMemProvider, { /// Creates a new [`TimeoutInProcessForkExecutor`] #[cfg(target_os = "linux")] - pub fn new( + pub fn new( harness_fn: &'a mut H, observers: OT, _fuzzer: &mut Z, @@ -1935,12 +1859,9 @@ where ) -> Result where EM: EventFirer + EventRestarter, - CF: Feedback, OF: Feedback, S: HasSolutions + HasClientPerfMonitor, - Z: HasObjective - + HasFeedback - + HasScheduler, + Z: HasObjective, { let handlers = InChildProcessHandlers::with_timeout::()?; let milli_sec = timeout.as_millis(); @@ -1969,7 +1890,7 @@ where /// Creates a new [`TimeoutInProcessForkExecutor`], non linux #[cfg(not(target_os = "linux"))] - pub fn new( + pub fn new( harness_fn: &'a mut H, observers: OT, _fuzzer: &mut Z, @@ -1980,12 +1901,9 @@ where ) -> Result where EM: EventFirer + EventRestarter, - CF: Feedback, OF: Feedback, S: HasSolutions + HasClientPerfMonitor, - Z: HasObjective - + HasFeedback - + HasScheduler, + Z: HasObjective, { let handlers = InChildProcessHandlers::with_timeout::()?; let milli_sec = timeout.as_millis(); diff --git a/libafl_frida/src/executor.rs b/libafl_frida/src/executor.rs index 2b28931c9a..65024d1810 100644 --- a/libafl_frida/src/executor.rs +++ b/libafl_frida/src/executor.rs @@ -8,7 +8,7 @@ use frida_gum::{ #[cfg(windows)] use libafl::{ executors::inprocess::{HasInProcessHandlers, InProcessHandlers}, - state::{HasClientPerfMonitor, HasCorpus, HasExecutions, HasSolutions}, + state::{HasClientPerfMonitor, HasCorpus, HasSolutions}, }; use libafl::{ executors::{Executor, ExitKind, HasObservers, InProcessExecutor}, @@ -231,7 +231,7 @@ impl<'a, 'b, 'c, H, OT, RT, S> HasInProcessHandlers for FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S> where H: FnMut(&S::Input) -> ExitKind, - S: UsesInput + HasClientPerfMonitor + HasSolutions + HasCorpus + HasExecutions, + S: UsesInput + HasClientPerfMonitor + HasSolutions + HasCorpus, S::Input: HasTargetBytes, OT: ObserversTuple, RT: FridaRuntimeTuple, diff --git a/libafl_qemu/src/executor.rs b/libafl_qemu/src/executor.rs index 2262fd8ae7..581e24183c 100644 --- a/libafl_qemu/src/executor.rs +++ b/libafl_qemu/src/executor.rs @@ -11,7 +11,7 @@ use libafl::{ events::{EventFirer, EventRestarter}, executors::{Executor, ExitKind, HasObservers, InProcessExecutor}, feedbacks::Feedback, - fuzzer::{HasFeedback, HasObjective, HasScheduler}, + fuzzer::HasObjective, inputs::UsesInput, observers::{ObserversTuple, UsesObservers}, state::{HasClientPerfMonitor, HasCorpus, HasExecutions, HasSolutions, State, UsesState}, @@ -56,7 +56,7 @@ where OT: ObserversTuple, QT: QemuHelperTuple, { - pub fn new( + pub fn new( hooks: &'a mut QemuHooks<'a, QT, S>, harness_fn: &'a mut H, observers: OT, @@ -66,12 +66,9 @@ where ) -> Result where EM: EventFirer + EventRestarter, - CF: Feedback, OF: Feedback, S: State + HasExecutions + HasCorpus + HasSolutions + HasClientPerfMonitor, - Z: HasObjective - + HasFeedback - + HasScheduler, + Z: HasObjective, { Ok(Self { first_exec: true, @@ -207,12 +204,12 @@ where impl<'a, H, OT, QT, S, SP> QemuForkExecutor<'a, H, OT, QT, S, SP> where H: FnMut(&S::Input) -> ExitKind, - S: UsesInput + HasCorpus, + S: UsesInput, OT: ObserversTuple, QT: QemuHelperTuple, SP: ShMemProvider, { - pub fn new( + pub fn new( hooks: &'a mut QemuHooks<'a, QT, S>, harness_fn: &'a mut H, observers: OT, @@ -223,12 +220,9 @@ where ) -> Result where EM: EventFirer + EventRestarter, - CF: Feedback, OF: Feedback, S: HasSolutions + HasClientPerfMonitor, - Z: HasObjective - + HasFeedback - + HasScheduler, + Z: HasObjective, { assert!(!QT::HOOKS_DO_SIDE_EFFECTS, "When using QemuForkExecutor, the hooks must not do any side effect as they will happen in the child process and then discarded"); diff --git a/libafl_targets/src/windows_asan.rs b/libafl_targets/src/windows_asan.rs index 3a89a49c67..e062980362 100644 --- a/libafl_targets/src/windows_asan.rs +++ b/libafl_targets/src/windows_asan.rs @@ -4,8 +4,8 @@ use libafl::{ events::{EventFirer, EventRestarter}, executors::{inprocess::windows_asan_handler::asan_death_handler, Executor, HasObservers}, feedbacks::Feedback, - state::{HasClientPerfMonitor, HasCorpus, HasExecutions, HasSolutions}, - HasFeedback, HasObjective, HasScheduler, + state::{HasClientPerfMonitor, HasCorpus, HasSolutions}, + HasObjective, }; /// Asan death callback type @@ -27,16 +27,13 @@ extern "C" { /// /// # Safety /// Calls the unsafe `__sanitizer_set_death_callback` symbol, but should be safe to call otherwise. -pub unsafe fn setup_asan_callback(_executor: &E, _event_mgr: &EM, _fuzzer: &Z) +pub unsafe fn setup_asan_callback(_executor: &E, _event_mgr: &EM, _fuzzer: &Z) where E: Executor + HasObservers, EM: EventFirer + EventRestarter, - CF: Feedback, OF: Feedback, - E::State: HasSolutions + HasClientPerfMonitor + HasCorpus + HasExecutions, - Z: HasObjective - + HasFeedback - + HasScheduler, + E::State: HasSolutions + HasClientPerfMonitor + HasCorpus, + Z: HasObjective, { - __sanitizer_set_death_callback(asan_death_handler::); + __sanitizer_set_death_callback(asan_death_handler::); }