tidying up

This commit is contained in:
Dominik Maier 2021-01-06 03:27:57 +01:00
parent b4e9890b78
commit 95fff9d740
6 changed files with 113 additions and 106 deletions

View File

@ -509,7 +509,7 @@ mod tests {
use crate::inputs::bytes::BytesInput; use crate::inputs::bytes::BytesInput;
use crate::mutators::{mutation_bitflip, ComposedByMutations, StdScheduledMutator}; use crate::mutators::{mutation_bitflip, ComposedByMutations, StdScheduledMutator};
use crate::stages::mutational::StdMutationalStage; use crate::stages::mutational::StdMutationalStage;
use crate::tuples::{tuple_list, tuple_list_type}; use crate::tuples::tuple_list;
use crate::utils::StdRand; use crate::utils::StdRand;
fn harness<I>(_executor: &dyn Executor<I>, _buf: &[u8]) -> ExitKind { fn harness<I>(_executor: &dyn Executor<I>, _buf: &[u8]) -> ExitKind {
@ -534,7 +534,7 @@ mod tests {
"main", "main",
harness, harness,
tuple_list!(), tuple_list!(),
Box::new(|_, _| ()), Box::new(|_, _, _, _, _| ()),
&state, &state,
&corpus, &corpus,
&mut event_manager, &mut event_manager,
@ -559,7 +559,7 @@ mod tests {
} }
let state_serialized = postcard::to_allocvec(&state).unwrap(); let state_serialized = postcard::to_allocvec(&state).unwrap();
let state_deserialized: State<BytesInput, StdRand, tuple_list_type!(), tuple_list_type!()> = let state_deserialized: State<BytesInput, StdRand, ()> =
postcard::from_bytes(state_serialized.as_slice()).unwrap(); postcard::from_bytes(state_serialized.as_slice()).unwrap();
assert_eq!(state.executions, state_deserialized.executions); assert_eq!(state.executions, state_deserialized.executions);

View File

@ -292,6 +292,30 @@ where
// TODO Custom event fire (dyn CustomEvent or similar) // TODO Custom event fire (dyn CustomEvent or similar)
} }
/// An eventmgr for tests, and as placeholder if you really don't need an event manager.
#[derive(Copy, Clone, Debug)]
pub struct NopEventManager<I> {
phantom: PhantomData<I>,
}
impl<I> EventManager<I> for NopEventManager<I>
where
I: Input,
{
fn process<C, FT, R>(
&mut self,
_state: &mut State<I, R, FT>,
_corpus: &mut C,
) -> Result<usize, AflError>
where
C: Corpus<I, R>,
FT: FeedbacksTuple<I>,
R: Rand,
{
Ok(0)
}
}
/// Events that may happen
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum LoggerEvent<I> pub enum LoggerEvent<I>
where where

View File

@ -1,4 +1,4 @@
use alloc::{boxed::Box, vec::Vec}; use alloc::boxed::Box;
use core::{ffi::c_void, ptr}; use core::{ffi::c_void, ptr};
use crate::{ use crate::{
@ -15,17 +15,17 @@ use crate::{
}; };
#[cfg(feature = "std")] #[cfg(feature = "std")]
use self::unix_signals::setup_crash_handlers; #[cfg(unix)]
use unix_signals as os_signals;
#[cfg(feature = "std")]
use self::os_signals::setup_crash_handlers;
/// The (unsafe) pointer to the current inmem input, 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_INPUT_PTR: *const c_void = ptr::null(); static mut CURRENT_INPUT_PTR: *const c_void = ptr::null();
static mut CURRENT_ON_CRASH_FN: *mut c_void = ptr::null_mut(); static mut CURRENT_ON_CRASH_FN: *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_MANAGER_PTR: *mut c_void = ptr::null_mut();
/// 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;
type OnCrashFunction<I, C, EM, FT, R> = dyn FnMut(ExitKind, &I, &State<I, R, FT>, &C, &mut EM); type OnCrashFunction<I, C, EM, FT, R> = dyn FnMut(ExitKind, &I, &State<I, R, FT>, &C, &mut EM);
@ -149,40 +149,6 @@ where
} }
} }
/// Serialize the current state and corpus during an executiont to bytes.
/// This method is needed when the fuzzer run crashes and has to restart.
pub fn serialize_state_corpus<C, FT, I, R>(
state: &State<I, R, FT>,
corpus: &C,
) -> Result<Vec<u8>, AflError>
where
C: Corpus<I, R>,
FT: FeedbacksTuple<I>,
I: Input,
R: Rand,
{
let state_bytes = postcard::to_allocvec(&state)?;
let corpus_bytes = postcard::to_allocvec(&corpus)?;
Ok(postcard::to_allocvec(&(state_bytes, corpus_bytes))?)
}
/// Deserialize the state and corpus tuple, previously serialized with `serialize_state_corpus(...)`
pub fn deserialize_state_corpus<C, FT, I, R>(
state_corpus_serialized: &[u8],
) -> Result<(State<I, R, FT>, C), AflError>
where
C: Corpus<I, R>,
FT: FeedbacksTuple<I>,
I: Input,
R: Rand,
{
let tuple: (Vec<u8>, Vec<u8>) = postcard::from_bytes(&state_corpus_serialized)?;
Ok((
postcard::from_bytes(&tuple.0)?,
postcard::from_bytes(&tuple.1)?,
))
}
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[cfg(unix)] #[cfg(unix)]
pub mod unix_signals { pub mod unix_signals {
@ -206,16 +172,19 @@ pub mod unix_signals {
corpus::Corpus, corpus::Corpus,
engines::State, engines::State,
events::EventManager, events::EventManager,
executors::inmemory::{ executors::inmemory::{ExitKind, OnCrashFunction, CURRENT_INPUT_PTR, CURRENT_ON_CRASH_FN},
ExitKind, OnCrashFunction, CORPUS_PTR, CURRENT_INPUT_PTR, CURRENT_ON_CRASH_FN,
EVENT_MANAGER_PTR, STATE_PTR,
},
feedbacks::FeedbacksTuple, feedbacks::FeedbacksTuple,
inputs::Input, inputs::Input,
observers::ObserversTuple, observers::ObserversTuple,
utils::Rand, utils::Rand,
}; };
/// 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();
pub unsafe extern "C" fn libaflrs_executor_inmem_handle_crash<EM, C, OT, FT, I, R>( pub unsafe extern "C" fn libaflrs_executor_inmem_handle_crash<EM, C, OT, FT, I, R>(
_sig: c_int, _sig: c_int,
info: siginfo_t, info: siginfo_t,
@ -230,9 +199,10 @@ pub mod unix_signals {
{ {
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... Exiting.",
info.si_addr() as usize info.si_addr() as usize
); );
return;
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
@ -274,7 +244,7 @@ pub mod unix_signals {
{ {
dbg!("TIMEOUT/SIGUSR2 received"); 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."); dbg!("TIMEOUT or SIGUSR2 happened, but currently not fuzzing. Exiting");
return; return;
} }
@ -342,33 +312,16 @@ pub mod unix_signals {
} }
} }
//#[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)] #[cfg(test)]
mod tests { mod tests {
use alloc::boxed::Box; use alloc::boxed::Box;
use crate::executors::inmemory::InMemoryExecutor; use crate::{
use crate::executors::{Executor, ExitKind}; executors::{inmemory::InMemoryExecutor, Executor, ExitKind},
use crate::inputs::{HasTargetBytes, Input, TargetBytes}; inputs::NopInput,
use crate::tuples::tuple_list; tuples::tuple_list,
};
use serde::{Deserialize, Serialize};
#[derive(Clone, Serialize, Deserialize, Debug)]
struct NopInput {}
impl Input for NopInput {}
impl HasTargetBytes for NopInput {
fn target_bytes(&self) -> TargetBytes {
TargetBytes::Owned(vec![0])
}
}
#[cfg(feature = "std")] #[cfg(feature = "std")]
fn test_harness_fn_nop(_executor: &dyn Executor<NopInput>, buf: &[u8]) -> ExitKind { fn test_harness_fn_nop(_executor: &dyn Executor<NopInput>, buf: &[u8]) -> ExitKind {
@ -383,12 +336,22 @@ mod tests {
#[test] #[test]
fn test_inmem_exec() { fn test_inmem_exec() {
let mut in_mem_executor = InMemoryExecutor { use crate::{
corpus::InMemoryCorpus, events::NopEventManager, inputs::NopInput, utils::StdRand,
};
let mut in_mem_executor = InMemoryExecutor::<
NopInput,
(),
InMemoryCorpus<_, _>,
NopEventManager<_>,
(),
StdRand,
> {
harness_fn: test_harness_fn_nop, harness_fn: test_harness_fn_nop,
on_crash_fn: Box::new(|_, _| ()), on_crash_fn: Box::new(|_, _, _, _, _| ()),
observers: tuple_list!(), observers: tuple_list!(),
name: "main", name: "main",
phantom: PhantomData,
}; };
let mut input = NopInput {}; let mut input = NopInput {};
assert!(in_mem_executor.run_target(&mut input).is_ok()); assert!(in_mem_executor.run_target(&mut input).is_ok());

View File

@ -3,7 +3,6 @@ pub use bytes::BytesInput;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::{clone::Clone, fmt::Debug}; use core::{clone::Clone, fmt::Debug};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::{ use std::{
fs::File, fs::File,
@ -11,6 +10,8 @@ use std::{
path::Path, path::Path,
}; };
use serde::{Deserialize, Serialize};
use crate::AflError; use crate::AflError;
/// An input for the target /// An input for the target
@ -54,6 +55,16 @@ where {
} }
} }
/// An input for tests, mainly. There is no real use much else.
#[derive(Copy, Clone, Serialize, Deserialize, Debug)]
pub struct NopInput {}
impl Input for NopInput {}
impl HasTargetBytes for NopInput {
fn target_bytes(&self) -> TargetBytes {
TargetBytes::Owned(vec![0])
}
}
pub enum TargetBytes<'a> { pub enum TargetBytes<'a> {
Ref(&'a [u8]), Ref(&'a [u8]),
Owned(Vec<u8>), Owned(Vec<u8>),

View File

@ -1,14 +1,51 @@
//! Utility functions for AFL //! Utility functions for AFL
use alloc::rc::Rc; use alloc::vec::Vec;
use core::{cell::RefCell, debug_assert, fmt::Debug, time}; use core::{cell::RefCell, debug_assert, fmt::Debug, time};
use postcard;
use xxhash_rust::xxh3::xxh3_64_with_seed; use xxhash_rust::xxh3::xxh3_64_with_seed;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
use crate::{corpus::Corpus, engines::State, feedbacks::FeedbacksTuple, inputs::Input, AflError};
pub type StdRand = RomuTrioRand; pub type StdRand = RomuTrioRand;
/// Serialize the current state and corpus during an executiont to bytes.
/// This method is needed when the fuzzer run crashes and has to restart.
pub fn serialize_state_corpus<C, FT, I, R>(
state: &State<I, R, FT>,
corpus: &C,
) -> Result<Vec<u8>, AflError>
where
C: Corpus<I, R>,
FT: FeedbacksTuple<I>,
I: Input,
R: Rand,
{
let state_bytes = postcard::to_allocvec(&state)?;
let corpus_bytes = postcard::to_allocvec(&corpus)?;
Ok(postcard::to_allocvec(&(state_bytes, corpus_bytes))?)
}
/// Deserialize the state and corpus tuple, previously serialized with `serialize_state_corpus(...)`
pub fn deserialize_state_corpus<C, FT, I, R>(
state_corpus_serialized: &[u8],
) -> Result<(State<I, R, FT>, C), AflError>
where
C: Corpus<I, R>,
FT: FeedbacksTuple<I>,
I: Input,
R: Rand,
{
let tuple: (Vec<u8>, Vec<u8>) = postcard::from_bytes(&state_corpus_serialized)?;
Ok((
postcard::from_bytes(&tuple.0)?,
postcard::from_bytes(&tuple.1)?,
))
}
/// Ways to get random around here /// Ways to get random around here
pub trait Rand: Debug { pub trait Rand: Debug {
// Sets the seed of this Rand // Sets the seed of this Rand
@ -137,12 +174,6 @@ impl Rand for Xoshiro256StarRand {
} }
} }
impl Into<Rc<RefCell<Self>>> for Xoshiro256StarRand {
fn into(self) -> Rc<RefCell<Self>> {
Rc::new(RefCell::new(self))
}
}
impl Xoshiro256StarRand { impl Xoshiro256StarRand {
/// Creates a new Xoshiro rand with the given seed /// Creates a new Xoshiro rand with the given seed
pub fn new(seed: u64) -> Self { pub fn new(seed: u64) -> Self {
@ -184,12 +215,6 @@ impl Rand for XorShift64Rand {
} }
} }
impl Into<Rc<RefCell<Self>>> for XorShift64Rand {
fn into(self) -> Rc<RefCell<Self>> {
Rc::new(RefCell::new(self))
}
}
impl XorShift64Rand { impl XorShift64Rand {
/// Creates a new Xoshiro rand with the given seed /// Creates a new Xoshiro rand with the given seed
pub fn new(seed: u64) -> Self { pub fn new(seed: u64) -> Self {
@ -227,12 +252,6 @@ impl Rand for Lehmer64Rand {
} }
} }
impl Into<Rc<RefCell<Self>>> for Lehmer64Rand {
fn into(self) -> Rc<RefCell<Self>> {
Rc::new(RefCell::new(self))
}
}
impl Lehmer64Rand { impl Lehmer64Rand {
/// Creates a new Lehmer rand with the given seed /// Creates a new Lehmer rand with the given seed
pub fn new(seed: u64) -> Self { pub fn new(seed: u64) -> Self {
@ -360,13 +379,6 @@ impl Rand for XKCDRand {
} }
} }
#[cfg(test)]
impl Into<Rc<RefCell<Self>>> for XKCDRand {
fn into(self) -> Rc<RefCell<Self>> {
Rc::new(RefCell::new(self))
}
}
#[cfg(test)] #[cfg(test)]
impl XKCDRand { impl XKCDRand {
pub fn new() -> Self { pub fn new() -> Self {

View File

@ -13,10 +13,7 @@ use afl::{
shmem::{AflShmem, ShMem}, shmem::{AflShmem, ShMem},
EventManager, LlmpEventManager, SimpleStats, EventManager, LlmpEventManager, SimpleStats,
}, },
executors::{ executors::{inmemory::InMemoryExecutor, Executor, ExitKind},
inmemory::{deserialize_state_corpus, serialize_state_corpus, InMemoryExecutor},
Executor, ExitKind,
},
feedbacks::MaxMapFeedback, feedbacks::MaxMapFeedback,
generators::RandPrintablesGenerator, generators::RandPrintablesGenerator,
inputs::BytesInput, inputs::BytesInput,
@ -24,7 +21,7 @@ use afl::{
observers::StdMapObserver, observers::StdMapObserver,
stages::mutational::StdMutationalStage, stages::mutational::StdMutationalStage,
tuples::tuple_list, tuples::tuple_list,
utils::StdRand, utils::{deserialize_state_corpus, serialize_state_corpus, StdRand},
AflError, AflError,
}; };