diff --git a/libafl/src/executors/inprocess.rs b/libafl/src/executors/inprocess.rs index d1db9b3470..94991b1ac7 100644 --- a/libafl/src/executors/inprocess.rs +++ b/libafl/src/executors/inprocess.rs @@ -1,16 +1,17 @@ //! The InProcess Executor is a libfuzzer-like executor, that will simply call a function. //! It should usually be paired with extra error-handling, such as a restarting event manager, to be effective. -use core::marker::PhantomData; - -#[cfg(unix)] use core::{ ptr::{self, write_volatile}, sync::atomic::{compiler_fence, Ordering}, + ffi::c_void, + marker::PhantomData }; #[cfg(unix)] -use crate::bolts::os::unix_signals::{c_void, setup_signal_handler}; +use crate::bolts::os::unix_signals::setup_signal_handler; +#[cfg(windows)] +use crate::bolts::os::windows_exceptions::setup_exception_handler; use crate::{ bolts::tuples::Named, @@ -61,6 +62,27 @@ where &mut data.current_input_ptr, _input as *const _ as *const c_void, ); + write_volatile( + &mut data.observers_ptr, + &self.observers as *const _ as *const c_void, + ); + // Direct raw pointers access /aliasing is pretty undefined behavior. + // Since the state and event may have moved in memory, refresh them right before the signal may happen + write_volatile(&mut data.state_ptr, _state as *mut _ as *mut c_void); + write_volatile(&mut data.event_mgr_ptr, _event_mgr as *mut _ as *mut c_void); + compiler_fence(Ordering::SeqCst); + } + #[cfg(windows)] + unsafe { + let data = &mut windows_exception_handler::GLOBAL_STATE; + write_volatile( + &mut data.current_input_ptr, + _input as *const _ as *const c_void, + ); + write_volatile( + &mut data.observers_ptr, + &self.observers as *const _ as *const c_void, + ); // Direct raw pointers access /aliasing is pretty undefined behavior. // Since the state and event may have moved in memory, refresh them right before the signal may happen write_volatile(&mut data.state_ptr, _state as *mut _ as *mut c_void); @@ -74,6 +96,16 @@ where fn run_target(&mut self, input: &I) -> Result { let bytes = input.target_bytes(); let ret = (self.harness_fn)(self, bytes.as_slice()); + Ok(ret) + } + + #[inline] + fn post_exec( + &mut self, + _state: &mut S, + _event_mgr: &mut EM, + _input: &I, + ) -> Result<(), Error> { #[cfg(unix)] unsafe { write_volatile( @@ -82,8 +114,17 @@ where ); compiler_fence(Ordering::SeqCst); } - Ok(ret) + #[cfg(windows)] + unsafe { + write_volatile( + &mut windows_exception_handler::GLOBAL_STATE.current_input_ptr, + ptr::null(), + ); + compiler_fence(Ordering::SeqCst); + } + Ok(()) } + } impl Named for InProcessExecutor @@ -140,10 +181,6 @@ where #[cfg(unix)] unsafe { let data = &mut unix_signal_handler::GLOBAL_STATE; - write_volatile( - &mut data.observers_ptr, - &observers as *const _ as *const c_void, - ); write_volatile( &mut data.crash_handler, unix_signal_handler::inproc_crash_handler::, @@ -156,6 +193,21 @@ where setup_signal_handler(data)?; compiler_fence(Ordering::SeqCst); } + #[cfg(windows)] + unsafe { + let data = &mut windows_exception_handler::GLOBAL_STATE; + write_volatile( + &mut data.crash_handler, + windows_exception_handler::inproc_crash_handler::, + ); + //write_volatile( + // &mut data.timeout_handler, + // windows_exception_handler::inproc_timeout_handler::, + //); + + setup_exception_handler(data)?; + compiler_fence(Ordering::SeqCst); + } Ok(Self { harness_fn, @@ -188,6 +240,8 @@ mod unix_signal_handler { state::{HasObjectives, HasSolutions}, }; + // TODO merge GLOBAL_STATE with the Windows one + /// Signal handling on unix systems needs some nasty unsafe. pub static mut GLOBAL_STATE: InProcessExecutorHandlerData = InProcessExecutorHandlerData { /// The state ptr for signal handling @@ -444,8 +498,8 @@ mod windows_exception_handler { current_input_ptr: ptr::null(), /// The crash handler fn crash_handler: nop_handler, - /// The timeout handler fn - timeout_handler: nop_handler, + // The timeout handler fn + //timeout_handler: nop_handler, }; pub struct InProcessExecutorHandlerData { @@ -536,7 +590,7 @@ mod windows_exception_handler { #[cfg(feature = "std")] println!("Bye!"); - unsafe { ExitProcess(1) }; + ExitProcess(1); } else { #[cfg(feature = "std")] { @@ -562,7 +616,7 @@ mod windows_exception_handler { } // TODO tell the parent to not restart - unsafe { ExitProcess(1) }; + ExitProcess(1); } } } diff --git a/libafl/src/executors/mod.rs b/libafl/src/executors/mod.rs index 77cfdda548..bf4f5ee47b 100644 --- a/libafl/src/executors/mod.rs +++ b/libafl/src/executors/mod.rs @@ -96,7 +96,7 @@ where /// Called right after execution finished. #[inline] - fn post_exec(&mut self, _state: &S, _event_mgr: &mut EM, _input: &I) -> Result<(), Error> + fn post_exec(&mut self, _state: &mut S, _event_mgr: &mut EM, _input: &I) -> Result<(), Error> where EM: EventManager, { diff --git a/libafl/src/executors/timeout.rs b/libafl/src/executors/timeout.rs index aa83b5069c..6acb753032 100644 --- a/libafl/src/executors/timeout.rs +++ b/libafl/src/executors/timeout.rs @@ -132,7 +132,7 @@ where #[inline] fn post_exec, S>( &mut self, - _state: &S, + _state: &mut S, _event_mgr: &mut EM, _input: &I, ) -> Result<(), Error> {