From d4de6f86da7f8017197d4ce6a17d02c7f0302635 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 28 Oct 2020 18:43:59 +0100 Subject: [PATCH] added sighandlers --- Cargo.toml | 3 +- src/executors/mod.rs | 83 ++++++++++++++++++++++++++++++++++++++++++++ src/utils.rs | 2 +- 3 files changed, 86 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ee4bf652e1..574c3c8763 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,4 +12,5 @@ criterion = "0.3" # Benchmarking [dependencies] xxhash-rust = { version = "0.8.0-beta.4", features = ["xxh3"] } # xxh3 hashing for rust thiserror = "1.0" # A nicer way to write Errors -hashbrown = "0.9" # A faster hashmap, nostd compatible \ No newline at end of file +hashbrown = "0.9" # A faster hashmap, nostd compatible +libc = "0.2" # For (*nix) libc diff --git a/src/executors/mod.rs b/src/executors/mod.rs index e9682040a6..6e35650d88 100644 --- a/src/executors/mod.rs +++ b/src/executors/mod.rs @@ -38,6 +38,81 @@ pub struct InMemoryExecutor { static mut CURRENT_INMEMORY_EXECUTOR_PTR: *const InMemoryExecutor = ptr::null(); +#[cfg(unix)] +pub mod unix_signals { + + extern crate libc; + use self::libc::{c_int, c_void, sigaction, siginfo_t}; + // Unhandled signals: SIGALRM, SIGHUP, SIGINT, SIGKILL, SIGQUIT, SIGTERM + use self::libc::{ + SA_NODEFER, SA_SIGINFO, SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGPIPE, SIGSEGV, SIGUSR2, + }; + use std::io::{stdout, Write}; // Write brings flush() into scope + use std::{mem, process, ptr}; + + use crate::executors::CURRENT_INMEMORY_EXECUTOR_PTR; + + pub extern "C" fn libaflrs_executor_inmem_handle_crash( + _sig: c_int, + info: siginfo_t, + _void: c_void, + ) { + unsafe { + if CURRENT_INMEMORY_EXECUTOR_PTR == ptr::null() { + println!( + "We died accessing addr {}, but are not in client...", + info.si_addr() as usize + ); + } + } + // TODO: LLMP + println!("Child crashed!"); + let _ = stdout().flush(); + } + + pub extern "C" fn libaflrs_executor_inmem_handle_timeout( + _sig: c_int, + _info: siginfo_t, + _void: c_void, + ) { + dbg!("TIMEOUT/SIGUSR2 received"); + unsafe { + if CURRENT_INMEMORY_EXECUTOR_PTR == ptr::null() { + dbg!("TIMEOUT or SIGUSR2 happened, but currently not fuzzing."); + return; + } + } + // TODO: send LLMP. + println!("Timeout in fuzz run."); + let _ = stdout().flush(); + process::abort(); + } + + pub unsafe fn setup_crash_handlers() { + 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; + for (sig, msg) in vec![ + (SIGSEGV, "segfault"), + (SIGBUS, "sigbus"), + (SIGABRT, "sigabrt"), + (SIGILL, "illegal instruction"), + (SIGFPE, "fp exception"), + (SIGPIPE, "pipe"), + ] { + if sigaction(sig, &mut sa as *mut sigaction, ptr::null_mut()) < 0 { + panic!("Could not set up {} handler", &msg); + } + } + + 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"); + } + } +} + impl Executor for InMemoryExecutor { fn run_target(&mut self) -> Result { let bytes = match self.base.cur_input.as_ref() { @@ -123,4 +198,12 @@ mod tests { in_mem_executor.add_observer(Box::new(nopserver)); assert_eq!(in_mem_executor.post_exec_observers().is_err(), true); } + + #[test] + fn test_inmem_exec() { + let mut in_mem_executor = InMemoryExecutor::new(test_harness_fn_nop); + let nopserver = Nopserver {}; + in_mem_executor.add_observer(Box::new(nopserver)); + assert_eq!(in_mem_executor.post_exec_observers().is_err(), true); + } } diff --git a/src/utils.rs b/src/utils.rs index 36da82184c..e53e4fd51e 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -119,6 +119,6 @@ mod tests { assert_eq!(next_pow2(2), 2); assert_eq!(next_pow2(3), 4); assert_eq!(next_pow2(1000), 1024); - assert_eq!(next_pow2(u32::MAX as u64), (u32::MAX as u64) + 1); + assert_eq!(next_pow2(0xFFFFFFFF as u64), (0xFFFFFFFF as u64) + 1); } }