diff --git a/libafl/src/executors/inprocess.rs b/libafl/src/executors/inprocess.rs index 46d366fd88..8ef12cc392 100644 --- a/libafl/src/executors/inprocess.rs +++ b/libafl/src/executors/inprocess.rs @@ -634,6 +634,42 @@ pub fn run_observers_and_save_state( log::info!("Bye!"); } +// TODO remove this after executor refactor and libafl qemu new executor +/// Expose a version of the crash handler that can be called from e.g. an emulator +#[cfg(any(unix, feature = "std"))] +pub fn generic_inproc_crash_handler() +where + E: Executor + HasObservers, + EM: EventFirer + EventRestarter, + OF: Feedback, + E::State: HasExecutions + HasSolutions + HasCorpus, + Z: HasObjective, +{ + let data = unsafe { &mut GLOBAL_STATE }; + let in_handler = data.set_in_handler(true); + + if data.is_valid() { + let executor = data.executor_mut::(); + // disarms timeout in case of TimeoutExecutor + executor.post_run_reset(); + let state = data.state_mut::(); + let event_mgr = data.event_mgr_mut::(); + let fuzzer = data.fuzzer_mut::(); + let input = data.take_current_input::<::Input>(); + + run_observers_and_save_state::( + executor, + state, + input, + fuzzer, + event_mgr, + ExitKind::Crash, + ); + } + + data.set_in_handler(in_handler); +} + /// The inprocess executor singal handling code for unix #[cfg(unix)] pub mod unix_signal_handler { diff --git a/libafl_qemu/libafl_qemu_build/src/build.rs b/libafl_qemu/libafl_qemu_build/src/build.rs index 7a24b06a21..fdcee927ae 100644 --- a/libafl_qemu/libafl_qemu_build/src/build.rs +++ b/libafl_qemu/libafl_qemu_build/src/build.rs @@ -8,7 +8,7 @@ use which::which; const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge"; const QEMU_DIRNAME: &str = "qemu-libafl-bridge"; -const QEMU_REVISION: &str = "c105904e6659b3fc90e938438a44254dfe47e1c3"; +const QEMU_REVISION: &str = "32206d23c33a55c9e519e4ae67038ab27d713a24"; fn build_dep_check(tools: &[&str]) { for tool in tools { diff --git a/libafl_qemu/src/executor.rs b/libafl_qemu/src/executor.rs index 225807f5ea..a5cfc0544e 100644 --- a/libafl_qemu/src/executor.rs +++ b/libafl_qemu/src/executor.rs @@ -59,16 +59,7 @@ where #[cfg(emulation_mode = "usermode")] extern "C" { // Original QEMU user signal handler - fn libafl_qemu_handle_crash(signal: i32, info: *mut siginfo_t, puc: *mut c_void) -> i32; -} - -#[cfg(emulation_mode = "usermode")] -static mut USE_LIBAFL_CRASH_HANDLER: bool = false; - -#[cfg(emulation_mode = "usermode")] -#[no_mangle] -pub unsafe extern "C" fn libafl_executor_reinstall_handlers() { - USE_LIBAFL_CRASH_HANDLER = true; + fn libafl_qemu_handle_crash(signal: i32, info: *mut siginfo_t, puc: *mut c_void); } #[cfg(emulation_mode = "usermode")] @@ -76,7 +67,7 @@ pub unsafe fn inproc_qemu_crash_handler( signal: Signal, info: &mut siginfo_t, mut context: Option<&mut ucontext_t>, - data: &mut InProcessExecutorHandlerData, + _data: &mut InProcessExecutorHandlerData, ) where E: Executor + HasObservers, EM: EventFirer + EventRestarter, @@ -84,20 +75,11 @@ pub unsafe fn inproc_qemu_crash_handler( E::State: HasExecutions + HasSolutions + HasCorpus, Z: HasObjective, { - let real_crash = if USE_LIBAFL_CRASH_HANDLER { - true - } else { - let puc = match &mut context { - Some(v) => (*v) as *mut ucontext_t as *mut c_void, - None => core::ptr::null_mut(), - }; - libafl_qemu_handle_crash(signal as i32, info, puc) != 0 + let puc = match &mut context { + Some(v) => (*v) as *mut ucontext_t as *mut c_void, + None => core::ptr::null_mut(), }; - if real_crash { - libafl::executors::inprocess::unix_signal_handler::inproc_crash_handler::( - signal, info, context, data, - ); - } + libafl_qemu_handle_crash(signal as i32, info, puc); } #[cfg(emulation_mode = "systemmode")] @@ -157,6 +139,21 @@ where inner.handlers_mut().crash_handler = inproc_qemu_crash_handler::, EM, OF, Z> as *const c_void; + + let handler = |hooks: &mut QemuHooks, host_sig| { + eprintln!("Crashed with signal {host_sig}"); + libafl::executors::inprocess::generic_inproc_crash_handler::< + InProcessExecutor<'a, H, OT, S>, + EM, + OF, + Z, + >(); + if let Some(cpu) = hooks.emulator().current_cpu() { + eprint!("Context:\n{}", cpu.display_context()); + } + }; + + hooks.crash_closure(Box::new(handler)); } #[cfg(emulation_mode = "systemmode")] {