Merge branch 'main' of https://github.com/domenukk/libAFLrs into main

This commit is contained in:
Dominik Maier 2020-12-19 05:44:12 +01:00
commit 77f57207f6

View File

@ -7,9 +7,9 @@ use crate::observers::ObserversTuple;
use crate::tuples::Named;
use crate::AflError;
/// The (unsafe) pointer to the current inmem executor, for the current run.
/// The (unsafe) pointer to the current inmem input, for the current run.
/// This is neede for certain non-rust side effects, as well as unix signal handling.
static mut CURRENT_INMEMORY_EXECUTOR_PTR: *const c_void = ptr::null();
static mut CURRENT_INPUT_PTR: *const c_void = ptr::null();
/// The inmem executor harness
type HarnessFunction<I> = fn(&dyn Executor<I>, &[u8]) -> ExitKind;
@ -34,11 +34,11 @@ where
fn run_target(&mut self, input: &I) -> Result<ExitKind, AflError> {
let bytes = input.target_bytes();
unsafe {
CURRENT_INMEMORY_EXECUTOR_PTR = self as *const InMemoryExecutor<I, OT> as *const c_void;
CURRENT_INPUT_PTR = input as *const _ as *const c_void;
}
let ret = (self.harness)(self, bytes.as_slice());
unsafe {
CURRENT_INMEMORY_EXECUTOR_PTR = ptr::null();
CURRENT_INPUT_PTR = ptr::null();
}
Ok(ret)
}
@ -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,63 +97,97 @@ pub mod unix_signals {
use std::io::{stdout, Write}; // Write brings flush() into scope
use std::{mem, process, ptr};
use crate::executors::inmemory::CURRENT_INMEMORY_EXECUTOR_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_INMEMORY_EXECUTOR_PTR == ptr::null() {
if CURRENT_INPUT_PTR == ptr::null() {
println!(
"We died accessing addr {}, but are not in client...",
info.si_addr() as usize
);
}
}
#[cfg(feature = "std")]
println!("Child crashed!");
#[cfg(feature = "std")]
let _ = stdout().flush();
// TODO: LLMP
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_INMEMORY_EXECUTOR_PTR == ptr::null() {
if CURRENT_INPUT_PTR == ptr::null() {
dbg!("TIMEOUT or SIGUSR2 happened, but currently not fuzzing.");
return;
}
}
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.");
let _ = stdout().flush();
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"),
@ -171,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 {