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,
{
pub fn new(name: &'static str, harness_fn: HarnessFunction<I>, observers: OT) -> Self {
#[cfg(feature = "std")]
unsafe {
os_signals::setup_crash_handlers::<I>();
}
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::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<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,
info: siginfo_t,
_void: c_void,
) where
EM: EventManager<C, E, OT, FT, I, R>,
C: Corpus<I, R>,
E: Executor<I>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
I: Input,
R: Rand,
{
unsafe {
if CURRENT_INPUT_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,31 +133,37 @@ pub mod unix_signals {
#[cfg(feature = "std")]
let _ = stdout().flush();
let _input = unsafe {
(CURRENT_INPUT_PTR as *const I).as_ref().unwrap()
};
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<I>(
pub unsafe extern "C" fn libaflrs_executor_inmem_handle_timeout<EM, C, E, OT, FT, I, R>(
_sig: c_int,
_info: siginfo_t,
_void: c_void,
) where
EM: EventManager<C, E, OT, FT, I, R>,
C: Corpus<I, R>,
E: Executor<I>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
I: Input,
R: Rand,
{
dbg!("TIMEOUT/SIGUSR2 received");
unsafe {
if CURRENT_INPUT_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 = unsafe {
(CURRENT_INPUT_PTR as *const I).as_ref().unwrap()
};
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.");
@ -157,14 +171,23 @@ pub mod unix_signals {
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
EM: EventManager<C, E, OT, FT, I, R>,
C: Corpus<I, R>,
E: Executor<I>,
OT: ObserversTuple,
FT: FeedbacksTuple<I>,
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::<I> as usize;
sa.sa_sigaction = libaflrs_executor_inmem_handle_crash::<EM, C, E, OT, FT, I, R> as usize;
for (sig, msg) in &[
(SIGSEGV, "segfault"),
(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 {
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 {