diff --git a/afl/src/executors/inmemory.rs b/afl/src/executors/inmemory.rs index af404c0dad..6a34ae108f 100644 --- a/afl/src/executors/inmemory.rs +++ b/afl/src/executors/inmemory.rs @@ -7,9 +7,9 @@ use crate::observers::ObserversTuple; use crate::tuples::Named; use crate::AflError; -/// The (unsafe) pointer to the current inmem executor, for the current run. +/// The (unsafe) pointer to the current inmem input, for the current run. /// This is neede for certain non-rust side effects, as well as unix signal handling. -static mut CURRENT_INMEMORY_EXECUTOR_PTR: *const c_void = ptr::null(); +static mut CURRENT_INPUT_PTR: *const c_void = ptr::null(); /// The inmem executor harness type HarnessFunction = fn(&dyn Executor, &[u8]) -> ExitKind; @@ -34,11 +34,11 @@ where fn run_target(&mut self, input: &I) -> Result { let bytes = input.target_bytes(); unsafe { - CURRENT_INMEMORY_EXECUTOR_PTR = self as *const InMemoryExecutor as *const c_void; + CURRENT_INPUT_PTR = input as *const _ as *const c_void; } let ret = (self.harness)(self, bytes.as_slice()); unsafe { - CURRENT_INMEMORY_EXECUTOR_PTR = ptr::null(); + CURRENT_INPUT_PTR = ptr::null(); } Ok(ret) } @@ -76,10 +76,6 @@ where OT: ObserversTuple, { pub fn new(name: &'static str, harness_fn: HarnessFunction, observers: OT) -> Self { - #[cfg(feature = "std")] - unsafe { - os_signals::setup_crash_handlers::(); - } Self { harness: harness_fn, observers: observers, @@ -101,23 +97,35 @@ pub mod unix_signals { use std::io::{stdout, Write}; // Write brings flush() into scope use std::{mem, process, ptr}; - use crate::executors::inmemory::CURRENT_INMEMORY_EXECUTOR_PTR; + use crate::corpus::Corpus; + use crate::events::EventManager; + use crate::executors::inmemory::CURRENT_INPUT_PTR; + use crate::executors::Executor; + use crate::feedbacks::FeedbacksTuple; use crate::inputs::Input; + use crate::observers::ObserversTuple; + use crate::utils::Rand; - pub extern "C" fn libaflrs_executor_inmem_handle_crash( + static mut EVENT_MANAGER_PTR: *mut c_void = ptr::null_mut(); + + pub unsafe extern "C" fn libaflrs_executor_inmem_handle_crash( _sig: c_int, info: siginfo_t, _void: c_void, ) where + EM: EventManager, + C: Corpus, + E: Executor, + OT: ObserversTuple, + FT: FeedbacksTuple, I: Input, + R: Rand, { - unsafe { - if CURRENT_INMEMORY_EXECUTOR_PTR == ptr::null() { - println!( - "We died accessing addr {}, but are not in client...", - info.si_addr() as usize - ); - } + if CURRENT_INPUT_PTR == ptr::null() { + println!( + "We died accessing addr {}, but are not in client...", + info.si_addr() as usize + ); } #[cfg(feature = "std")] @@ -125,39 +133,61 @@ pub mod unix_signals { #[cfg(feature = "std")] let _ = stdout().flush(); - // TODO: LLMP + let input = (CURRENT_INPUT_PTR as *const I).as_ref().unwrap(); + let manager = (EVENT_MANAGER_PTR as *mut EM).as_mut().unwrap(); + + manager.crash(input).expect("Error in sending Crash event"); std::process::exit(139); } - pub extern "C" fn libaflrs_executor_inmem_handle_timeout( + pub unsafe extern "C" fn libaflrs_executor_inmem_handle_timeout( _sig: c_int, _info: siginfo_t, _void: c_void, ) where + EM: EventManager, + C: Corpus, + E: Executor, + OT: ObserversTuple, + FT: FeedbacksTuple, I: Input, + R: Rand, { dbg!("TIMEOUT/SIGUSR2 received"); - unsafe { - if CURRENT_INMEMORY_EXECUTOR_PTR == ptr::null() { - dbg!("TIMEOUT or SIGUSR2 happened, but currently not fuzzing."); - return; - } + if CURRENT_INPUT_PTR == ptr::null() { + dbg!("TIMEOUT or SIGUSR2 happened, but currently not fuzzing."); + return; } + + let input = (CURRENT_INPUT_PTR as *const I).as_ref().unwrap(); + let manager = (EVENT_MANAGER_PTR as *mut EM).as_mut().unwrap(); + + manager.timeout(input).expect("Error in sending Timeout event"); + // TODO: send LLMP. println!("Timeout in fuzz run."); let _ = stdout().flush(); process::abort(); } - pub unsafe fn setup_crash_handlers() + // TODO clearly state that manager should be static (maybe put the 'static lifetime?) + pub unsafe fn setup_crash_handlers(manager: &mut EM) where + EM: EventManager, + C: Corpus, + E: Executor, + OT: ObserversTuple, + FT: FeedbacksTuple, I: Input, + R: Rand, { + EVENT_MANAGER_PTR = manager as *mut _ as *mut c_void; + let mut sa: sigaction = mem::zeroed(); libc::sigemptyset(&mut sa.sa_mask as *mut libc::sigset_t); sa.sa_flags = SA_NODEFER | SA_SIGINFO; - sa.sa_sigaction = libaflrs_executor_inmem_handle_crash:: as usize; + sa.sa_sigaction = libaflrs_executor_inmem_handle_crash:: as usize; for (sig, msg) in &[ (SIGSEGV, "segfault"), (SIGBUS, "sigbus"), @@ -171,19 +201,19 @@ pub mod unix_signals { } } - sa.sa_sigaction = libaflrs_executor_inmem_handle_timeout:: as usize; + sa.sa_sigaction = libaflrs_executor_inmem_handle_timeout:: as usize; if sigaction(SIGUSR2, &mut sa as *mut sigaction, ptr::null_mut()) < 0 { panic!("Could not set up sigusr2 handler for timeouts"); } } } -#[cfg(feature = "std")] -#[cfg(unix)] -use unix_signals as os_signals; -#[cfg(feature = "std")] -#[cfg(not(unix))] -compile_error!("InMemoryExecutor not yet supported on this OS"); +//#[cfg(feature = "std")] +//#[cfg(unix)] +//use unix_signals as os_signals; +//#[cfg(feature = "std")] +//#[cfg(not(unix))] +//compile_error!("InMemoryExecutor not yet supported on this OS"); #[cfg(test)] mod tests {