inmem fix v1
This commit is contained in:
parent
0fe2c49a17
commit
c9174ecb38
@ -214,13 +214,20 @@ where
|
||||
}
|
||||
|
||||
/// Runs the input and triggers observers and feedback
|
||||
pub fn evaluate_input<E, OT>(&mut self, input: &I, executor: &mut E) -> Result<u32, AflError>
|
||||
pub fn evaluate_input<C, E, EM, OT>(
|
||||
&mut self,
|
||||
input: &I,
|
||||
executor: &mut E,
|
||||
corpus: &C,
|
||||
event_mgr: &mut EM,
|
||||
) -> Result<u32, AflError>
|
||||
where
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
OT: ObserversTuple,
|
||||
{
|
||||
executor.pre_exec_observers()?;
|
||||
executor.run_target(&input)?;
|
||||
|
||||
executor.run_target(&input, &self, &corpus, &mut event_mgr)?;
|
||||
self.set_executions(self.executions() + 1);
|
||||
executor.post_exec_observers()?;
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
use alloc::boxed::Box;
|
||||
use core::{ffi::c_void, ptr};
|
||||
use os_signals::set_oncrash_ptrs;
|
||||
|
||||
use crate::{
|
||||
corpus::Corpus,
|
||||
@ -18,14 +19,10 @@ use crate::{
|
||||
#[cfg(unix)]
|
||||
use unix_signals as os_signals;
|
||||
|
||||
use self::os_signals::reset_oncrash_ptrs;
|
||||
#[cfg(feature = "std")]
|
||||
use self::os_signals::setup_crash_handlers;
|
||||
|
||||
/// 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_INPUT_PTR: *const c_void = ptr::null();
|
||||
static mut CURRENT_ON_CRASH_FN: *mut c_void = ptr::null_mut();
|
||||
|
||||
/// The inmem executor harness
|
||||
type HarnessFunction<I> = fn(&dyn Executor<I>, &[u8]) -> ExitKind;
|
||||
type OnCrashFunction<I, C, EM, FT, R> = dyn FnMut(ExitKind, &I, &State<I, R, FT>, &C, &mut EM);
|
||||
@ -60,16 +57,28 @@ where
|
||||
R: Rand,
|
||||
{
|
||||
#[inline]
|
||||
fn run_target(&mut self, input: &I) -> Result<ExitKind, AflError> {
|
||||
let bytes = input.target_bytes();
|
||||
fn run_target(
|
||||
&mut self,
|
||||
input: &I,
|
||||
state: State<I, R, FT>,
|
||||
corpus: &C,
|
||||
event_mgr: &EM,
|
||||
) -> Result<ExitKind, AflError> {
|
||||
#[cfg(unix)]
|
||||
unsafe {
|
||||
CURRENT_ON_CRASH_FN = &mut self.on_crash_fn as *mut _ as *mut c_void;
|
||||
CURRENT_INPUT_PTR = input as *const _ as *const c_void;
|
||||
set_oncrash_ptrs::<EM, C, OT, FT, I, R>(
|
||||
state,
|
||||
corpus,
|
||||
event_mgr,
|
||||
input,
|
||||
&mut self.on_crash_fn,
|
||||
);
|
||||
}
|
||||
let bytes = input.target_bytes();
|
||||
let ret = (self.harness_fn)(self, bytes.as_slice());
|
||||
#[cfg(unix)]
|
||||
unsafe {
|
||||
CURRENT_ON_CRASH_FN = ptr::null_mut();
|
||||
CURRENT_INPUT_PTR = ptr::null();
|
||||
reset_oncrash_ptrs::<EM, C, OT, FT, I, R>();
|
||||
}
|
||||
Ok(ret)
|
||||
}
|
||||
@ -137,7 +146,7 @@ where
|
||||
) -> Self {
|
||||
#[cfg(feature = "std")]
|
||||
unsafe {
|
||||
setup_crash_handlers::<EM, C, OT, FT, I, R>(_state, _corpus, _event_mgr);
|
||||
setup_crash_handlers::<EM, C, OT, FT, I, R>();
|
||||
}
|
||||
|
||||
Self {
|
||||
@ -149,6 +158,25 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
unsafe fn tidy_up_on_exit<EM>(mgr: &EM)
|
||||
where
|
||||
EM: EventManager<I>,
|
||||
I: Input,
|
||||
{
|
||||
|
||||
match manager.llmp {
|
||||
IsClient { client } => {
|
||||
let map = client.out_maps.last().unwrap();
|
||||
/// wait until we can drop the message safely.
|
||||
map.await_save_to_unmap_blocking();
|
||||
/// Make sure all pages are unmapped.
|
||||
drop(manager);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}*/
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg(unix)]
|
||||
pub mod unix_signals {
|
||||
@ -172,7 +200,7 @@ pub mod unix_signals {
|
||||
corpus::Corpus,
|
||||
engines::State,
|
||||
events::EventManager,
|
||||
executors::inmemory::{ExitKind, OnCrashFunction, CURRENT_INPUT_PTR, CURRENT_ON_CRASH_FN},
|
||||
executors::inmemory::{ExitKind, OnCrashFunction},
|
||||
feedbacks::FeedbacksTuple,
|
||||
inputs::Input,
|
||||
observers::ObserversTuple,
|
||||
@ -181,9 +209,13 @@ pub mod unix_signals {
|
||||
|
||||
/// Pointers to values only needed on crash. As the program will not continue after a crash,
|
||||
/// we should (tm) be okay with raw pointers here,
|
||||
static mut CORPUS_PTR: *const c_void = ptr::null_mut();
|
||||
static mut STATE_PTR: *const c_void = ptr::null_mut();
|
||||
static mut EVENT_MANAGER_PTR: *mut c_void = ptr::null_mut();
|
||||
static mut corpus_ptr: *const c_void = ptr::null_mut();
|
||||
static mut state_ptr: *const c_void = ptr::null_mut();
|
||||
static mut event_mgr_ptr: *mut c_void = ptr::null_mut();
|
||||
/// 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_input_ptr: *const c_void = ptr::null();
|
||||
static mut on_crash_fn_ptr: *mut c_void = ptr::null_mut();
|
||||
|
||||
pub unsafe extern "C" fn libaflrs_executor_inmem_handle_crash<EM, C, OT, FT, I, R>(
|
||||
_sig: c_int,
|
||||
@ -197,12 +229,13 @@ pub mod unix_signals {
|
||||
I: Input,
|
||||
R: Rand,
|
||||
{
|
||||
if CURRENT_INPUT_PTR == ptr::null() {
|
||||
if current_input_ptr == ptr::null() {
|
||||
println!(
|
||||
"We died accessing addr {}, but are not in client... Exiting.",
|
||||
info.si_addr() as usize
|
||||
);
|
||||
return;
|
||||
//exit(1);
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
@ -210,15 +243,13 @@ pub mod unix_signals {
|
||||
#[cfg(feature = "std")]
|
||||
let _ = stdout().flush();
|
||||
|
||||
let input = (CURRENT_INPUT_PTR as *const I).as_ref().unwrap();
|
||||
let corpus = (CORPUS_PTR as *const C).as_ref().unwrap();
|
||||
let state = (EVENT_MANAGER_PTR as *const State<I, R, FT>)
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
let manager = (EVENT_MANAGER_PTR as *mut EM).as_mut().unwrap();
|
||||
let input = (current_input_ptr as *const I).as_ref().unwrap();
|
||||
let corpus = (corpus_ptr as *const C).as_ref().unwrap();
|
||||
let state = (event_mgr_ptr as *const State<I, R, FT>).as_ref().unwrap();
|
||||
let manager = (event_mgr_ptr as *mut EM).as_mut().unwrap();
|
||||
|
||||
if !CURRENT_ON_CRASH_FN.is_null() {
|
||||
(*(CURRENT_ON_CRASH_FN as *mut Box<OnCrashFunction<I, C, EM, FT, R>>))(
|
||||
if !on_crash_fn_ptr.is_null() {
|
||||
(*(on_crash_fn_ptr as *mut Box<OnCrashFunction<I, C, EM, FT, R>>))(
|
||||
ExitKind::Crash,
|
||||
input,
|
||||
state,
|
||||
@ -243,20 +274,18 @@ pub mod unix_signals {
|
||||
R: Rand,
|
||||
{
|
||||
dbg!("TIMEOUT/SIGUSR2 received");
|
||||
if CURRENT_INPUT_PTR.is_null() {
|
||||
if current_input_ptr.is_null() {
|
||||
dbg!("TIMEOUT or SIGUSR2 happened, but currently not fuzzing. Exiting");
|
||||
return;
|
||||
}
|
||||
|
||||
let input = (CURRENT_INPUT_PTR as *const I).as_ref().unwrap();
|
||||
let corpus = (CORPUS_PTR as *const C).as_ref().unwrap();
|
||||
let state = (EVENT_MANAGER_PTR as *const State<I, R, FT>)
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
let manager = (EVENT_MANAGER_PTR as *mut EM).as_mut().unwrap();
|
||||
let input = (current_input_ptr as *const I).as_ref().unwrap();
|
||||
let corpus = (corpus_ptr as *const C).as_ref().unwrap();
|
||||
let state = (event_mgr_ptr as *const State<I, R, FT>).as_ref().unwrap();
|
||||
let manager = (event_mgr_ptr as *mut EM).as_mut().unwrap();
|
||||
|
||||
if !CURRENT_ON_CRASH_FN.is_null() {
|
||||
(*(CURRENT_ON_CRASH_FN as *mut Box<OnCrashFunction<I, C, EM, FT, R>>))(
|
||||
if !on_crash_fn_ptr.is_null() {
|
||||
(*(on_crash_fn_ptr as *mut Box<OnCrashFunction<I, C, EM, FT, R>>))(
|
||||
ExitKind::Timeout,
|
||||
input,
|
||||
state,
|
||||
@ -283,11 +312,13 @@ pub mod unix_signals {
|
||||
process::abort();
|
||||
}
|
||||
|
||||
// TODO clearly state that manager should be static (maybe put the 'static lifetime?)
|
||||
pub unsafe fn setup_crash_handlers<EM, C, OT, FT, I, R>(
|
||||
#[inline]
|
||||
pub unsafe fn set_oncrash_ptrs<EM, C, OT, FT, I, R>(
|
||||
state: &State<I, R, FT>,
|
||||
corpus: &C,
|
||||
manager: &mut EM,
|
||||
event_mgr: &mut EM,
|
||||
input: I,
|
||||
on_crash_handler: &mut Box<OnCrashFunction<I, C, EM, FT, R>>,
|
||||
) where
|
||||
EM: EventManager<I>,
|
||||
C: Corpus<I, R>,
|
||||
@ -296,10 +327,32 @@ pub mod unix_signals {
|
||||
I: Input,
|
||||
R: Rand,
|
||||
{
|
||||
CORPUS_PTR = corpus as *const _ as *const c_void;
|
||||
STATE_PTR = state as *const _ as *const c_void;
|
||||
EVENT_MANAGER_PTR = manager as *mut _ as *mut c_void;
|
||||
current_input_ptr = input as *const _ as *const c_void;
|
||||
corpus_ptr = corpus as *const _ as *const c_void;
|
||||
state_ptr = state as *const _ as *const c_void;
|
||||
event_mgr_ptr = event_mgr as *mut _ as *mut c_void;
|
||||
on_crash_fn_ptr = on_crash_handler as *mut _ as *mut c_void;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn reset_oncrash_ptrs<EM, C, OT, FT, I, R>() {
|
||||
current_input_ptr = ptr::null();
|
||||
corpus_ptr = ptr::null();
|
||||
state_ptr = ptr::null();
|
||||
event_mgr_ptr = ptr::null_mut();
|
||||
on_crash_fn_ptr = ptr::null_mut();
|
||||
}
|
||||
|
||||
// TODO clearly state that manager should be static (maybe put the 'static lifetime?)
|
||||
pub unsafe fn setup_crash_handlers<EM, C, OT, FT, I, R>()
|
||||
where
|
||||
EM: EventManager<I>,
|
||||
C: Corpus<I, R>,
|
||||
OT: ObserversTuple,
|
||||
FT: FeedbacksTuple<I>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
{
|
||||
let mut sa: sigaction = mem::zeroed();
|
||||
libc::sigemptyset(&mut sa.sa_mask as *mut libc::sigset_t);
|
||||
sa.sa_flags = SA_NODEFER | SA_SIGINFO;
|
||||
|
@ -6,6 +6,7 @@ pub mod runtime;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use crate::{
|
||||
engines::State,
|
||||
inputs::{HasTargetBytes, Input},
|
||||
observers::ObserversTuple,
|
||||
tuples::{MatchNameAndType, MatchType, Named, TupleList},
|
||||
@ -74,7 +75,13 @@ where
|
||||
I: Input,
|
||||
{
|
||||
/// Instruct the target about the input and run
|
||||
fn run_target(&mut self, input: &I) -> Result<ExitKind, AflError>;
|
||||
fn run_target<R, FT, C, EM>(
|
||||
&mut self,
|
||||
input: &I,
|
||||
state: &State<I, R, FT>,
|
||||
corpus: &C,
|
||||
event_mgr: &EM,
|
||||
) -> Result<ExitKind, AflError>;
|
||||
}
|
||||
|
||||
pub trait ExecutorsTuple<I>: MatchType + MatchNameAndType
|
||||
|
@ -208,7 +208,6 @@ where
|
||||
9 => mutation_byteinteresting,
|
||||
10 => mutation_wordinteresting,
|
||||
11 => mutation_dwordinteresting,*/
|
||||
|
||||
_ => mutation_splice,
|
||||
};
|
||||
mutation(self, rand, corpus, input)?;
|
||||
|
@ -35,14 +35,25 @@ where
|
||||
SH: ShMem,
|
||||
ST: Stats,
|
||||
{
|
||||
let mgr_bytes = postcard::to_allocvec(&mgr.describe()?)?;
|
||||
let state_bytes = postcard::to_allocvec(&state)?;
|
||||
let corpus_bytes = postcard::to_allocvec(&corpus)?;
|
||||
Ok(postcard::to_allocvec(&(
|
||||
println!("state ptr: {:x}", state as *const _ as u64);
|
||||
println!("state execs: {}", state.executions());
|
||||
println!("More fun");
|
||||
let ret_slice = postcard::to_allocvec(&(&state, &corpus, &mgr.describe()?))?;
|
||||
println!("done: {:?}", ret_slice);
|
||||
//let corpus_bytes = serde_json::to_string(&corpus).unwrap();
|
||||
|
||||
//println!("fun");
|
||||
//let state_bytes = serde_json::to_string(&state).unwrap();
|
||||
//println!("fun & games");
|
||||
/*match serde_json::to_string(&(
|
||||
state_bytes,
|
||||
corpus_bytes,
|
||||
mgr_bytes,
|
||||
))?)
|
||||
)) {
|
||||
Ok(val) => Ok(val.as_bytes().to_vec()),
|
||||
Err(e) => panic!("couldn't do things"),
|
||||
}*/
|
||||
Ok(ret_slice)
|
||||
}
|
||||
|
||||
/// Deserialize the state and corpus tuple, previously serialized with `serialize_state_corpus(...)`
|
||||
|
@ -149,12 +149,17 @@ fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
|
||||
sender.to_env(ENV_FUZZER_SENDER)?;
|
||||
receiver.to_env(ENV_FUZZER_RECEIVER)?;
|
||||
|
||||
let mut ctr = 0;
|
||||
loop {
|
||||
dbg!("Spawning next client");
|
||||
Command::new(env::current_exe()?)
|
||||
.current_dir(env::current_dir()?)
|
||||
.args(env::args())
|
||||
.status()?;
|
||||
ctr += 1;
|
||||
if ctr == 10 {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -219,7 +224,9 @@ fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
|
||||
.expect(&format!("Error sending crash event for input {:?}", input)),
|
||||
_ => (),
|
||||
}
|
||||
println!("foo");
|
||||
let state_corpus_serialized = serialize_state_corpus_mgr(state, corpus, mgr).unwrap();
|
||||
println!("bar: {:?}", &state_corpus_serialized);
|
||||
sender.send_buf(0x1, &state_corpus_serialized).unwrap();
|
||||
}),
|
||||
&state,
|
||||
|
Loading…
x
Reference in New Issue
Block a user