fire events in signal handlers

This commit is contained in:
Andrea Fioraldi 2020-12-18 10:19:35 +01:00
parent b3d7843922
commit 8bd29f855f

View File

@ -76,10 +76,6 @@ where
OT: ObserversTuple, OT: ObserversTuple,
{ {
pub fn new(name: &'static str, harness_fn: HarnessFunction<I>, observers: OT) -> Self { pub fn new(name: &'static str, harness_fn: HarnessFunction<I>, observers: OT) -> Self {
#[cfg(feature = "std")]
unsafe {
os_signals::setup_crash_handlers::<I>();
}
Self { Self {
harness: harness_fn, harness: harness_fn,
observers: observers, observers: observers,
@ -101,23 +97,35 @@ pub mod unix_signals {
use std::io::{stdout, Write}; // Write brings flush() into scope use std::io::{stdout, Write}; // Write brings flush() into scope
use std::{mem, process, ptr}; use std::{mem, process, ptr};
use crate::corpus::Corpus;
use crate::events::EventManager;
use crate::executors::inmemory::CURRENT_INPUT_PTR; use crate::executors::inmemory::CURRENT_INPUT_PTR;
use crate::executors::Executor;
use crate::feedbacks::FeedbacksTuple;
use crate::inputs::Input; use crate::inputs::Input;
use crate::observers::ObserversTuple;
use crate::utils::Rand;
pub extern "C" fn libaflrs_executor_inmem_handle_crash<I>( static mut EVENT_MANAGER_PTR: *mut c_void = ptr::null_mut();
pub unsafe extern "C" fn libaflrs_executor_inmem_handle_crash<EM, C, E, OT, FT, I, R>(
_sig: c_int, _sig: c_int,
info: siginfo_t, info: siginfo_t,
_void: c_void, _void: c_void,
) where ) where
EM: EventManager<C, E, OT, FT, I, R>,
C: Corpus<I, R>,
E: Executor<I>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
I: Input, I: Input,
R: Rand,
{ {
unsafe { if CURRENT_INPUT_PTR == ptr::null() {
if CURRENT_INPUT_PTR == ptr::null() { println!(
println!( "We died accessing addr {}, but are not in client...",
"We died accessing addr {}, but are not in client...", info.si_addr() as usize
info.si_addr() as usize );
);
}
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
@ -125,31 +133,37 @@ pub mod unix_signals {
#[cfg(feature = "std")] #[cfg(feature = "std")]
let _ = stdout().flush(); let _ = stdout().flush();
let _input = unsafe { let input = (CURRENT_INPUT_PTR as *const I).as_ref().unwrap();
(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); std::process::exit(139);
} }
pub extern "C" fn libaflrs_executor_inmem_handle_timeout<I>( pub unsafe extern "C" fn libaflrs_executor_inmem_handle_timeout<EM, C, E, OT, FT, I, R>(
_sig: c_int, _sig: c_int,
_info: siginfo_t, _info: siginfo_t,
_void: c_void, _void: c_void,
) where ) where
EM: EventManager<C, E, OT, FT, I, R>,
C: Corpus<I, R>,
E: Executor<I>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
I: Input, I: Input,
R: Rand,
{ {
dbg!("TIMEOUT/SIGUSR2 received"); dbg!("TIMEOUT/SIGUSR2 received");
unsafe { if CURRENT_INPUT_PTR == ptr::null() {
if CURRENT_INPUT_PTR == ptr::null() { dbg!("TIMEOUT or SIGUSR2 happened, but currently not fuzzing.");
dbg!("TIMEOUT or SIGUSR2 happened, but currently not fuzzing."); return;
return;
}
} }
let _input = unsafe { let input = (CURRENT_INPUT_PTR as *const I).as_ref().unwrap();
(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. // TODO: send LLMP.
println!("Timeout in fuzz run."); println!("Timeout in fuzz run.");
@ -157,14 +171,23 @@ pub mod unix_signals {
process::abort(); process::abort();
} }
pub unsafe fn setup_crash_handlers<I>() // TODO clearly state that manager should be static (maybe put the 'static lifetime?)
pub unsafe fn setup_crash_handlers<EM, C, E, OT, FT, I, R>(manager: &mut EM)
where where
EM: EventManager<C, E, OT, FT, I, R>,
C: Corpus<I, R>,
E: Executor<I>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
I: Input, I: Input,
R: Rand,
{ {
EVENT_MANAGER_PTR = manager as *mut _ as *mut c_void;
let mut sa: sigaction = mem::zeroed(); let mut sa: sigaction = mem::zeroed();
libc::sigemptyset(&mut sa.sa_mask as *mut libc::sigset_t); libc::sigemptyset(&mut sa.sa_mask as *mut libc::sigset_t);
sa.sa_flags = SA_NODEFER | SA_SIGINFO; sa.sa_flags = SA_NODEFER | SA_SIGINFO;
sa.sa_sigaction = libaflrs_executor_inmem_handle_crash::<I> as usize; sa.sa_sigaction = libaflrs_executor_inmem_handle_crash::<EM, C, E, OT, FT, I, R> as usize;
for (sig, msg) in &[ for (sig, msg) in &[
(SIGSEGV, "segfault"), (SIGSEGV, "segfault"),
(SIGBUS, "sigbus"), (SIGBUS, "sigbus"),
@ -178,19 +201,19 @@ pub mod unix_signals {
} }
} }
sa.sa_sigaction = libaflrs_executor_inmem_handle_timeout::<I> as usize; sa.sa_sigaction = libaflrs_executor_inmem_handle_timeout::<EM, C, E, OT, FT, I, R> as usize;
if sigaction(SIGUSR2, &mut sa as *mut sigaction, ptr::null_mut()) < 0 { if sigaction(SIGUSR2, &mut sa as *mut sigaction, ptr::null_mut()) < 0 {
panic!("Could not set up sigusr2 handler for timeouts"); panic!("Could not set up sigusr2 handler for timeouts");
} }
} }
} }
#[cfg(feature = "std")] //#[cfg(feature = "std")]
#[cfg(unix)] //#[cfg(unix)]
use unix_signals as os_signals; //use unix_signals as os_signals;
#[cfg(feature = "std")] //#[cfg(feature = "std")]
#[cfg(not(unix))] //#[cfg(not(unix))]
compile_error!("InMemoryExecutor not yet supported on this OS"); //compile_error!("InMemoryExecutor not yet supported on this OS");
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {