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::tuples::Named;
use crate::AflError; 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. /// 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 /// The inmem executor harness
type HarnessFunction<I> = fn(&dyn Executor<I>, &[u8]) -> ExitKind; type HarnessFunction<I> = fn(&dyn Executor<I>, &[u8]) -> ExitKind;
@ -34,11 +34,11 @@ where
fn run_target(&mut self, input: &I) -> Result<ExitKind, AflError> { fn run_target(&mut self, input: &I) -> Result<ExitKind, AflError> {
let bytes = input.target_bytes(); let bytes = input.target_bytes();
unsafe { 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()); let ret = (self.harness)(self, bytes.as_slice());
unsafe { unsafe {
CURRENT_INMEMORY_EXECUTOR_PTR = ptr::null(); CURRENT_INPUT_PTR = ptr::null();
} }
Ok(ret) Ok(ret)
} }
@ -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,63 +97,97 @@ 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::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::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_INMEMORY_EXECUTOR_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")]
println!("Child crashed!"); println!("Child crashed!");
#[cfg(feature = "std")] #[cfg(feature = "std")]
let _ = stdout().flush(); 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); 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_INMEMORY_EXECUTOR_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 = (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.");
let _ = stdout().flush(); let _ = stdout().flush();
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"),
@ -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 { 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 {