objective corpus and feedbacks
This commit is contained in:
parent
e3773e080f
commit
7a75155e6b
@ -251,9 +251,9 @@ where
|
||||
}
|
||||
|
||||
// Handle arriving events in the client
|
||||
fn handle_in_client<C, FT, R>(
|
||||
fn handle_in_client<C, FT, OC, OFT, R>(
|
||||
&mut self,
|
||||
state: &mut State<C, FT, I, R>,
|
||||
state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
_sender_id: u32,
|
||||
event: Event<I>,
|
||||
) -> Result<(), AflError>
|
||||
@ -261,6 +261,8 @@ where
|
||||
C: Corpus<I, R>,
|
||||
FT: FeedbacksTuple<I>,
|
||||
R: Rand,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
{
|
||||
match event {
|
||||
Event::NewTestcase {
|
||||
@ -306,11 +308,16 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn process<C, FT, R>(&mut self, state: &mut State<C, FT, I, R>) -> Result<usize, AflError>
|
||||
fn process<C, FT, OC, OFT, R>(
|
||||
&mut self,
|
||||
state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
) -> Result<usize, AflError>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
FT: FeedbacksTuple<I>,
|
||||
R: Rand,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
{
|
||||
// TODO: Get around local event copy by moving handle_in_client
|
||||
let mut events = vec![];
|
||||
@ -339,9 +346,9 @@ where
|
||||
Ok(count)
|
||||
}
|
||||
|
||||
fn fire<C, FT, R>(
|
||||
fn fire<C, FT, OC, OFT, R>(
|
||||
&mut self,
|
||||
_state: &mut State<C, FT, I, R>,
|
||||
_state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
event: Event<I>,
|
||||
) -> Result<(), AflError>
|
||||
where
|
||||
@ -349,6 +356,8 @@ where
|
||||
FT: FeedbacksTuple<I>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
{
|
||||
let serialized = postcard::to_allocvec(&event)?;
|
||||
self.llmp.send_buf(LLMP_TAG_EVENT_TO_BOTH, &serialized)?;
|
||||
@ -359,8 +368,8 @@ where
|
||||
/// Serialize the current state and corpus during an executiont to bytes.
|
||||
/// On top, add the current llmp event manager instance to be restored
|
||||
/// This method is needed when the fuzzer run crashes and has to restart.
|
||||
pub fn serialize_state_mgr<C, FT, I, R, SH, ST>(
|
||||
state: &State<C, FT, I, R>,
|
||||
pub fn serialize_state_mgr<C, FT, I, OC, OFT, R, SH, ST>(
|
||||
state: &State<C, FT, I, OC, OFT, R>,
|
||||
mgr: &LlmpEventManager<I, SH, ST>,
|
||||
) -> Result<Vec<u8>, AflError>
|
||||
where
|
||||
@ -368,6 +377,8 @@ where
|
||||
FT: FeedbacksTuple<I>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
SH: ShMem,
|
||||
ST: Stats,
|
||||
{
|
||||
@ -375,18 +386,20 @@ where
|
||||
}
|
||||
|
||||
/// Deserialize the state and corpus tuple, previously serialized with `serialize_state_corpus(...)`
|
||||
pub fn deserialize_state_mgr<C, FT, I, R, SH, ST>(
|
||||
pub fn deserialize_state_mgr<C, FT, I, OC, OFT, R, SH, ST>(
|
||||
state_corpus_serialized: &[u8],
|
||||
) -> Result<(State<C, FT, I, R>, LlmpEventManager<I, SH, ST>), AflError>
|
||||
) -> Result<(State<C, FT, I, OC, OFT, R>, LlmpEventManager<I, SH, ST>), AflError>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
FT: FeedbacksTuple<I>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
SH: ShMem,
|
||||
ST: Stats,
|
||||
{
|
||||
let tuple: (State<C, FT, I, R>, _) = postcard::from_bytes(&state_corpus_serialized)?;
|
||||
let tuple: (State<C, FT, I, OC, OFT, R>, _) = postcard::from_bytes(&state_corpus_serialized)?;
|
||||
Ok((
|
||||
tuple.0,
|
||||
LlmpEventManager::existing_client_from_description(&tuple.1)?,
|
||||
@ -422,11 +435,16 @@ where
|
||||
}
|
||||
|
||||
/// Reset the single page (we reuse it over and over from pos 0), then send the current state to the next runner.
|
||||
fn on_restart<C, FT, R>(&mut self, state: &mut State<C, FT, I, R>) -> Result<(), AflError>
|
||||
fn on_restart<C, FT, OC, OFT, R>(
|
||||
&mut self,
|
||||
state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
) -> Result<(), AflError>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
FT: FeedbacksTuple<I>,
|
||||
R: Rand,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
{
|
||||
// First, reset the page to 0 so the next iteration can read read from the beginning of this page
|
||||
unsafe { self.sender.reset() };
|
||||
@ -435,24 +453,31 @@ where
|
||||
.send_buf(_LLMP_TAG_RESTART, &state_corpus_serialized)
|
||||
}
|
||||
|
||||
fn process<C, FT, R>(&mut self, state: &mut State<C, FT, I, R>) -> Result<usize, AflError>
|
||||
fn process<C, FT, OC, OFT, R>(
|
||||
&mut self,
|
||||
state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
) -> Result<usize, AflError>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
FT: FeedbacksTuple<I>,
|
||||
R: Rand,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
{
|
||||
self.llmp_mgr.process(state)
|
||||
}
|
||||
|
||||
fn fire<C, FT, R>(
|
||||
fn fire<C, FT, OC, OFT, R>(
|
||||
&mut self,
|
||||
state: &mut State<C, FT, I, R>,
|
||||
state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
event: Event<I>,
|
||||
) -> Result<(), AflError>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
FT: FeedbacksTuple<I>,
|
||||
R: Rand,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
{
|
||||
// Check if we are going to crash in the event, in which case we store our current state for the next runner
|
||||
self.llmp_mgr.fire(state, event)
|
||||
@ -490,13 +515,13 @@ where
|
||||
/// A restarting state is a combination of restarter and runner, that can be used on systems without `fork`.
|
||||
/// The restarter will start a new process each time the child crashes or timeouts.
|
||||
#[cfg(feature = "std")]
|
||||
pub fn setup_restarting_mgr<I, C, FT, R, SH, ST>(
|
||||
pub fn setup_restarting_mgr<I, C, FT, OC, OFT, R, SH, ST>(
|
||||
//mgr: &mut LlmpEventManager<I, SH, ST>,
|
||||
stats: ST,
|
||||
broker_port: u16,
|
||||
) -> Result<
|
||||
(
|
||||
Option<State<C, FT, I, R>>,
|
||||
Option<State<C, FT, I, OC, OFT, R>>,
|
||||
LlmpRestartingEventManager<I, SH, ST>,
|
||||
),
|
||||
AflError,
|
||||
@ -506,6 +531,8 @@ where
|
||||
C: Corpus<I, R>,
|
||||
FT: FeedbacksTuple<I>,
|
||||
R: Rand,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
SH: ShMem,
|
||||
ST: Stats,
|
||||
{
|
||||
@ -565,7 +592,7 @@ where
|
||||
// Restoring from a previous run, deserialize state and corpus.
|
||||
Some((_sender, _tag, msg)) => {
|
||||
println!("Subsequent run. Let's load all data from shmem (received {} bytes from previous instance)", msg.len());
|
||||
let (state, mgr): (State<C, FT, I, R>, LlmpEventManager<I, SH, ST>) =
|
||||
let (state, mgr): (State<C, FT, I, OC, OFT, R>, LlmpEventManager<I, SH, ST>) =
|
||||
deserialize_state_mgr(&msg)?;
|
||||
|
||||
(Some(state), LlmpRestartingEventManager::new(mgr, sender))
|
||||
|
@ -31,11 +31,16 @@ where
|
||||
I: Input,
|
||||
ST: Stats, //CE: CustomEvent<I, OT>,
|
||||
{
|
||||
fn process<C, FT, R>(&mut self, state: &mut State<C, FT, I, R>) -> Result<usize, AflError>
|
||||
fn process<C, FT, OC, OFT, R>(
|
||||
&mut self,
|
||||
state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
) -> Result<usize, AflError>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
FT: FeedbacksTuple<I>,
|
||||
R: Rand,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
{
|
||||
let count = self.events.len();
|
||||
while self.events.len() > 0 {
|
||||
@ -45,15 +50,17 @@ where
|
||||
Ok(count)
|
||||
}
|
||||
|
||||
fn fire<C, FT, R>(
|
||||
fn fire<C, FT, OC, OFT, R>(
|
||||
&mut self,
|
||||
_state: &mut State<C, FT, I, R>,
|
||||
_state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
event: Event<I>,
|
||||
) -> Result<(), AflError>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
FT: FeedbacksTuple<I>,
|
||||
R: Rand,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
{
|
||||
match Self::handle_in_broker(&mut self.stats, 0, &event)? {
|
||||
BrokerEventResult::Forward => self.events.push(event),
|
||||
@ -125,9 +132,9 @@ where
|
||||
}
|
||||
|
||||
// Handle arriving events in the client
|
||||
fn handle_in_client<C, FT, R>(
|
||||
fn handle_in_client<C, FT, OC, OFT, R>(
|
||||
&mut self,
|
||||
_state: &mut State<C, FT, I, R>,
|
||||
_state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
_sender_id: u32,
|
||||
event: Event<I>,
|
||||
) -> Result<(), AflError>
|
||||
@ -135,6 +142,8 @@ where
|
||||
C: Corpus<I, R>,
|
||||
FT: FeedbacksTuple<I>,
|
||||
R: Rand,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
{
|
||||
match event {
|
||||
_ => Err(AflError::Unknown(format!(
|
||||
|
@ -162,11 +162,16 @@ where
|
||||
|
||||
/// Lookup for incoming events and process them.
|
||||
/// Return the number of processes events or an error
|
||||
fn process<C, FT, R>(&mut self, state: &mut State<C, FT, I, R>) -> Result<usize, AflError>
|
||||
fn process<C, FT, OC, OFT, R>(
|
||||
&mut self,
|
||||
state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
) -> Result<usize, AflError>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
FT: FeedbacksTuple<I>,
|
||||
R: Rand;
|
||||
R: Rand,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>;
|
||||
|
||||
/// Serialize all observers for this type and manager
|
||||
fn serialize_observers<OT>(&mut self, observers: &OT) -> Result<Vec<u8>, AflError>
|
||||
@ -186,11 +191,16 @@ where
|
||||
|
||||
/// For restarting event managers, implement a way to forward state to their next peers.
|
||||
#[inline]
|
||||
fn on_restart<C, FT, R>(&mut self, _state: &mut State<C, FT, I, R>) -> Result<(), AflError>
|
||||
fn on_restart<C, FT, OC, OFT, R>(
|
||||
&mut self,
|
||||
_state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
) -> Result<(), AflError>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
FT: FeedbacksTuple<I>,
|
||||
R: Rand,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
@ -200,15 +210,17 @@ where
|
||||
fn await_restart_safe(&mut self) {}
|
||||
|
||||
/// Send off an event to the broker
|
||||
fn fire<C, FT, R>(
|
||||
fn fire<C, FT, OC, OFT, R>(
|
||||
&mut self,
|
||||
_state: &mut State<C, FT, I, R>,
|
||||
_state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
event: Event<I>,
|
||||
) -> Result<(), AflError>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
FT: FeedbacksTuple<I>,
|
||||
R: Rand;
|
||||
R: Rand,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>;
|
||||
}
|
||||
|
||||
/// An eventmgr for tests, and as placeholder if you really don't need an event manager.
|
||||
@ -220,24 +232,31 @@ impl<I> EventManager<I> for NopEventManager<I>
|
||||
where
|
||||
I: Input,
|
||||
{
|
||||
fn process<C, FT, R>(&mut self, _state: &mut State<C, FT, I, R>) -> Result<usize, AflError>
|
||||
fn process<C, FT, OC, OFT, R>(
|
||||
&mut self,
|
||||
_state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
) -> Result<usize, AflError>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
FT: FeedbacksTuple<I>,
|
||||
R: Rand,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
{
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn fire<C, FT, R>(
|
||||
fn fire<C, FT, OC, OFT, R>(
|
||||
&mut self,
|
||||
_state: &mut State<C, FT, I, R>,
|
||||
_state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
_event: Event<I>,
|
||||
) -> Result<(), AflError>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
FT: FeedbacksTuple<I>,
|
||||
R: Rand,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
|
@ -54,30 +54,32 @@ where
|
||||
OT: ObserversTuple,
|
||||
{
|
||||
#[inline]
|
||||
fn pre_exec<C, EM, FT, R>(
|
||||
fn pre_exec<C, EM, FT, OC, OFT, R>(
|
||||
&mut self,
|
||||
_state: &mut State<C, FT, I, R>,
|
||||
_state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
_event_mgr: &mut EM,
|
||||
_input: &I,
|
||||
) -> Result<(), AflError>
|
||||
where
|
||||
R: Rand,
|
||||
FT: FeedbacksTuple<I>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
C: Corpus<I, R>,
|
||||
EM: EventManager<I>,
|
||||
{
|
||||
#[cfg(unix)]
|
||||
#[cfg(feature = "std")]
|
||||
unsafe {
|
||||
set_oncrash_ptrs::<C, EM, FT, I, OT, R>(_state, _event_mgr, _input);
|
||||
set_oncrash_ptrs::<C, EM, FT, I, OC, OFT, OT, R>(_state, _event_mgr, _input);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn post_exec<C, EM, FT, R>(
|
||||
fn post_exec<C, EM, FT, OC, OFT, R>(
|
||||
&mut self,
|
||||
_state: &State<C, FT, I, R>,
|
||||
_state: &State<C, FT, I, OC, OFT, R>,
|
||||
_event_mgr: &mut EM,
|
||||
_input: &I,
|
||||
) -> Result<(), AflError>
|
||||
@ -86,6 +88,8 @@ where
|
||||
FT: FeedbacksTuple<I>,
|
||||
C: Corpus<I, R>,
|
||||
EM: EventManager<I>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
{
|
||||
#[cfg(unix)]
|
||||
#[cfg(feature = "std")]
|
||||
@ -142,23 +146,25 @@ where
|
||||
/// * `on_crash_fn` - When an in-mem harness crashes, it may safe some state to continue fuzzing later.
|
||||
/// Do that that in this function. The program will crash afterwards.
|
||||
/// * `observers` - the observers observing the target during execution
|
||||
pub fn new<C, EM, FT, R>(
|
||||
pub fn new<C, EM, FT, OC, OFT, R>(
|
||||
name: &'static str,
|
||||
harness_fn: HarnessFunction<Self>,
|
||||
observers: OT,
|
||||
_state: &mut State<C, FT, I, R>,
|
||||
_state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
_event_mgr: &mut EM,
|
||||
) -> Self
|
||||
where
|
||||
R: Rand,
|
||||
FT: FeedbacksTuple<I>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
C: Corpus<I, R>,
|
||||
EM: EventManager<I>,
|
||||
{
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg(unix)]
|
||||
unsafe {
|
||||
setup_crash_handlers::<C, EM, FT, I, OT, R>();
|
||||
setup_crash_handlers::<C, EM, FT, I, OC, OFT, OT, R>();
|
||||
}
|
||||
|
||||
Self {
|
||||
@ -229,7 +235,7 @@ pub mod unix_signals {
|
||||
/// 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();
|
||||
|
||||
pub unsafe extern "C" fn libaflrs_executor_inmem_handle_crash<C, EM, FT, I, OT, R>(
|
||||
pub unsafe extern "C" fn libaflrs_executor_inmem_handle_crash<C, EM, FT, I, OC, OFT, OT, R>(
|
||||
_sig: c_int,
|
||||
info: siginfo_t,
|
||||
_void: c_void,
|
||||
@ -237,6 +243,8 @@ pub mod unix_signals {
|
||||
EM: EventManager<I>,
|
||||
C: Corpus<I, R>,
|
||||
OT: ObserversTuple,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
FT: FeedbacksTuple<I>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
@ -263,7 +271,9 @@ pub mod unix_signals {
|
||||
let input = (CURRENT_INPUT_PTR as *const I).as_ref().unwrap();
|
||||
// Make sure we don't crash in the crash handler forever.
|
||||
CURRENT_INPUT_PTR = ptr::null();
|
||||
let state = (STATE_PTR as *mut State<C, FT, I, R>).as_mut().unwrap();
|
||||
let state = (STATE_PTR as *mut State<C, FT, I, OC, OFT, R>)
|
||||
.as_mut()
|
||||
.unwrap();
|
||||
let mgr = (EVENT_MGR_PTR as *mut EM).as_mut().unwrap();
|
||||
mgr.fire(
|
||||
state,
|
||||
@ -282,13 +292,15 @@ pub mod unix_signals {
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
pub unsafe extern "C" fn libaflrs_executor_inmem_handle_timeout<C, EM, FT, I, OT, R>(
|
||||
pub unsafe extern "C" fn libaflrs_executor_inmem_handle_timeout<C, EM, FT, I, OC, OFT, OT, R>(
|
||||
_sig: c_int,
|
||||
_info: siginfo_t,
|
||||
_void: c_void,
|
||||
) where
|
||||
EM: EventManager<I>,
|
||||
C: Corpus<I, R>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
OT: ObserversTuple,
|
||||
FT: FeedbacksTuple<I>,
|
||||
I: Input,
|
||||
@ -306,7 +318,9 @@ pub mod unix_signals {
|
||||
let input = (CURRENT_INPUT_PTR as *const I).as_ref().unwrap();
|
||||
// Make sure we don't crash in the crash handler forever.
|
||||
CURRENT_INPUT_PTR = ptr::null();
|
||||
let state = (STATE_PTR as *mut State<C, FT, I, R>).as_mut().unwrap();
|
||||
let state = (STATE_PTR as *mut State<C, FT, I, OC, OFT, R>)
|
||||
.as_mut()
|
||||
.unwrap();
|
||||
let mgr = (EVENT_MGR_PTR as *mut EM).as_mut().unwrap();
|
||||
|
||||
mgr.fire(
|
||||
@ -325,13 +339,15 @@ pub mod unix_signals {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn set_oncrash_ptrs<C, EM, FT, I, OT, R>(
|
||||
state: &mut State<C, FT, I, R>,
|
||||
pub unsafe fn set_oncrash_ptrs<C, EM, FT, I, OC, OFT, OT, R>(
|
||||
state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
event_mgr: &mut EM,
|
||||
input: &I,
|
||||
) where
|
||||
EM: EventManager<I>,
|
||||
C: Corpus<I, R>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
OT: ObserversTuple,
|
||||
FT: FeedbacksTuple<I>,
|
||||
I: Input,
|
||||
@ -350,10 +366,12 @@ pub mod unix_signals {
|
||||
}
|
||||
|
||||
// TODO clearly state that manager should be static (maybe put the 'static lifetime?)
|
||||
pub unsafe fn setup_crash_handlers<C, EM, FT, I, OT, R>()
|
||||
pub unsafe fn setup_crash_handlers<C, EM, FT, I, OC, OFT, OT, R>()
|
||||
where
|
||||
EM: EventManager<I>,
|
||||
C: Corpus<I, R>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
OT: ObserversTuple,
|
||||
FT: FeedbacksTuple<I>,
|
||||
I: Input,
|
||||
@ -374,7 +392,8 @@ pub mod unix_signals {
|
||||
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_ONSTACK;
|
||||
sa.sa_sigaction = libaflrs_executor_inmem_handle_crash::<C, EM, FT, I, OT, R> as usize;
|
||||
sa.sa_sigaction =
|
||||
libaflrs_executor_inmem_handle_crash::<C, EM, FT, I, OC, OFT, OT, R> as usize;
|
||||
for (sig, msg) in &[
|
||||
(SIGSEGV, "segfault"),
|
||||
(SIGBUS, "sigbus"),
|
||||
@ -388,7 +407,8 @@ pub mod unix_signals {
|
||||
}
|
||||
}
|
||||
|
||||
sa.sa_sigaction = libaflrs_executor_inmem_handle_timeout::<C, EM, FT, I, OT, R> as usize;
|
||||
sa.sa_sigaction =
|
||||
libaflrs_executor_inmem_handle_timeout::<C, EM, FT, I, OC, OFT, OT, R> as usize;
|
||||
if sigaction(SIGUSR2, &mut sa as *mut sigaction, ptr::null_mut()) < 0 {
|
||||
panic!("Could not set up sigusr2 handler for timeouts");
|
||||
}
|
||||
|
@ -82,9 +82,9 @@ where
|
||||
{
|
||||
#[inline]
|
||||
/// Called right before exexution starts
|
||||
fn pre_exec<C, EM, FT, R>(
|
||||
fn pre_exec<C, EM, FT, OC, OFT, R>(
|
||||
&mut self,
|
||||
_state: &mut State<C, FT, I, R>,
|
||||
_state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
_event_mgr: &mut EM,
|
||||
_input: &I,
|
||||
) -> Result<(), AflError>
|
||||
@ -92,6 +92,8 @@ where
|
||||
R: Rand,
|
||||
FT: FeedbacksTuple<I>,
|
||||
C: Corpus<I, R>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
EM: EventManager<I>,
|
||||
{
|
||||
Ok(())
|
||||
@ -99,9 +101,9 @@ where
|
||||
|
||||
#[inline]
|
||||
/// Called right after execution finished.
|
||||
fn post_exec<C, EM, FT, R>(
|
||||
fn post_exec<C, EM, FT, OC, OFT, R>(
|
||||
&mut self,
|
||||
_state: &State<C, FT, I, R>,
|
||||
_state: &State<C, FT, I, OC, OFT, R>,
|
||||
_event_mgr: &mut EM,
|
||||
_input: &I,
|
||||
) -> Result<(), AflError>
|
||||
@ -109,6 +111,8 @@ where
|
||||
R: Rand,
|
||||
FT: FeedbacksTuple<I>,
|
||||
C: Corpus<I, R>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
EM: EventManager<I>,
|
||||
{
|
||||
Ok(())
|
||||
|
@ -39,11 +39,13 @@ use utils::{current_milliseconds, current_time, Rand};
|
||||
use std::{env::VarError, io, num::ParseIntError, string::FromUtf8Error};
|
||||
|
||||
/// The main fuzzer trait.
|
||||
pub trait Fuzzer<C, E, EM, FT, ST, I, OT, R>
|
||||
pub trait Fuzzer<C, E, EM, FT, ST, I, OC, OFT, OT, R>
|
||||
where
|
||||
ST: StagesTuple<C, E, EM, FT, I, OT, R>,
|
||||
ST: StagesTuple<C, E, EM, FT, I, OC, OFT, OT, R>,
|
||||
EM: EventManager<I>,
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
OT: ObserversTuple,
|
||||
FT: FeedbacksTuple<I>,
|
||||
C: Corpus<I, R>,
|
||||
@ -58,7 +60,7 @@ where
|
||||
&mut self,
|
||||
rand: &mut R,
|
||||
executor: &mut E,
|
||||
state: &mut State<C, FT, I, R>,
|
||||
state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
manager: &mut EM,
|
||||
) -> Result<usize, AflError> {
|
||||
let (_, idx) = state.corpus_mut().next(rand)?;
|
||||
@ -74,7 +76,7 @@ where
|
||||
&mut self,
|
||||
rand: &mut R,
|
||||
executor: &mut E,
|
||||
state: &mut State<C, FT, I, R>,
|
||||
state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
manager: &mut EM,
|
||||
) -> Result<(), AflError> {
|
||||
let mut last = current_milliseconds();
|
||||
@ -98,11 +100,13 @@ where
|
||||
|
||||
/// Your default fuzzer instance, for everyday use.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct StdFuzzer<C, E, EM, FT, ST, I, OT, R>
|
||||
pub struct StdFuzzer<C, E, EM, FT, ST, I, OC, OFT, OT, R>
|
||||
where
|
||||
ST: StagesTuple<C, E, EM, FT, I, OT, R>,
|
||||
ST: StagesTuple<C, E, EM, FT, I, OC, OFT, OT, R>,
|
||||
EM: EventManager<I>,
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
OT: ObserversTuple,
|
||||
FT: FeedbacksTuple<I>,
|
||||
C: Corpus<I, R>,
|
||||
@ -110,15 +114,17 @@ where
|
||||
R: Rand,
|
||||
{
|
||||
stages: ST,
|
||||
phantom: PhantomData<(EM, E, OT, FT, C, I, R)>,
|
||||
phantom: PhantomData<(EM, E, OC, OFT, OT, FT, C, I, R)>,
|
||||
}
|
||||
|
||||
impl<C, E, EM, FT, ST, I, OT, R> Fuzzer<C, E, EM, FT, ST, I, OT, R>
|
||||
for StdFuzzer<C, E, EM, FT, ST, I, OT, R>
|
||||
impl<C, E, EM, FT, ST, I, OC, OFT, OT, R> Fuzzer<C, E, EM, FT, ST, I, OC, OFT, OT, R>
|
||||
for StdFuzzer<C, E, EM, FT, ST, I, OC, OFT, OT, R>
|
||||
where
|
||||
ST: StagesTuple<C, E, EM, FT, I, OT, R>,
|
||||
ST: StagesTuple<C, E, EM, FT, I, OC, OFT, OT, R>,
|
||||
EM: EventManager<I>,
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
OT: ObserversTuple,
|
||||
FT: FeedbacksTuple<I>,
|
||||
C: Corpus<I, R>,
|
||||
@ -134,11 +140,13 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, E, EM, FT, ST, I, OT, R> StdFuzzer<C, E, EM, FT, ST, I, OT, R>
|
||||
impl<C, E, EM, FT, ST, I, OC, OFT, OT, R> StdFuzzer<C, E, EM, FT, ST, I, OC, OFT, OT, R>
|
||||
where
|
||||
ST: StagesTuple<C, E, EM, FT, I, OT, R>,
|
||||
ST: StagesTuple<C, E, EM, FT, I, OC, OFT, OT, R>,
|
||||
EM: EventManager<I>,
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
OT: ObserversTuple,
|
||||
FT: FeedbacksTuple<I>,
|
||||
C: Corpus<I, R>,
|
||||
@ -248,12 +256,13 @@ mod tests {
|
||||
mutators::{mutation_bitflip, ComposedByMutations, StdScheduledMutator},
|
||||
stages::StdMutationalStage,
|
||||
state::{HasCorpus, State},
|
||||
stats::SimpleStats,
|
||||
utils::StdRand,
|
||||
Fuzzer, StdFuzzer,
|
||||
};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use crate::events::{LoggerEventManager, SimpleStats};
|
||||
use crate::events::LoggerEventManager;
|
||||
|
||||
fn harness<E: Executor<I>, I: Input>(_executor: &E, _buf: &[u8]) -> ExitKind {
|
||||
ExitKind::Ok
|
||||
@ -267,7 +276,12 @@ mod tests {
|
||||
let testcase = Testcase::new(vec![0; 4]).into();
|
||||
corpus.add(testcase);
|
||||
|
||||
let mut state = State::new(corpus, tuple_list!());
|
||||
let mut state = State::new(
|
||||
corpus,
|
||||
tuple_list!(),
|
||||
InMemoryCorpus::<BytesInput, StdRand>::new(),
|
||||
tuple_list!(),
|
||||
);
|
||||
|
||||
let stats = SimpleStats::new(|s| {
|
||||
println!("{}", s);
|
||||
@ -295,8 +309,14 @@ mod tests {
|
||||
}
|
||||
|
||||
let state_serialized = postcard::to_allocvec(&state).unwrap();
|
||||
let state_deserialized: State<InMemoryCorpus<BytesInput, _>, (), BytesInput, StdRand> =
|
||||
postcard::from_bytes(state_serialized.as_slice()).unwrap();
|
||||
let state_deserialized: State<
|
||||
InMemoryCorpus<BytesInput, _>,
|
||||
(),
|
||||
BytesInput,
|
||||
InMemoryCorpus<BytesInput, _>,
|
||||
(),
|
||||
StdRand,
|
||||
> = postcard::from_bytes(state_serialized.as_slice()).unwrap();
|
||||
assert_eq!(state.executions(), state_deserialized.executions());
|
||||
|
||||
let corpus_serialized = postcard::to_allocvec(state.corpus()).unwrap();
|
||||
|
@ -999,7 +999,7 @@ token2="B"
|
||||
|
||||
corpus.add(BytesInput::new(vec![0x42; 0x1337]).into());
|
||||
|
||||
let mut state = State::new(corpus, ());
|
||||
let mut state = State::new(corpus, (), InMemoryCorpus::new(), ());
|
||||
|
||||
let mut mutations: Vec<MutationFunction<BytesInput, WithMaxSize, StdRand, _>> = vec![];
|
||||
|
||||
|
@ -343,7 +343,7 @@ mod tests {
|
||||
.expect("Corpus did not contain entries");
|
||||
let mut input = testcase.borrow_mut().load_input().unwrap().clone();
|
||||
|
||||
let mut state = State::new(corpus, ());
|
||||
let mut state = State::new(corpus, (), InMemoryCorpus::new(), ());
|
||||
|
||||
rand.set_seed(5);
|
||||
|
||||
@ -351,7 +351,7 @@ mod tests {
|
||||
InMemoryCorpus<BytesInput, XKCDRand>,
|
||||
_,
|
||||
_,
|
||||
State<_, (), _, _>,
|
||||
State<_, (), _, InMemoryCorpus<BytesInput, XKCDRand>, (), _>,
|
||||
>::new();
|
||||
|
||||
mutation_splice(&mut mutator, &mut rand, &mut state, &mut input).unwrap();
|
||||
@ -378,7 +378,7 @@ mod tests {
|
||||
let mut input = testcase.borrow_mut().load_input().unwrap().clone();
|
||||
let input_prior = input.clone();
|
||||
|
||||
let mut state = State::new(corpus, ());
|
||||
let mut state = State::new(corpus, (), InMemoryCorpus::new(), ());
|
||||
|
||||
let mut havoc = HavocBytesMutator::new(StdScheduledMutator::new());
|
||||
|
||||
|
@ -16,10 +16,12 @@ use crate::{
|
||||
|
||||
/// A stage is one step in the fuzzing process.
|
||||
/// Multiple stages will be scheduled one by one for each input.
|
||||
pub trait Stage<C, E, EM, FT, I, OT, R>
|
||||
pub trait Stage<C, E, EM, FT, I, OC, OFT, OT, R>
|
||||
where
|
||||
EM: EventManager<I>,
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
OT: ObserversTuple,
|
||||
FT: FeedbacksTuple<I>,
|
||||
C: Corpus<I, R>,
|
||||
@ -31,16 +33,18 @@ where
|
||||
&mut self,
|
||||
rand: &mut R,
|
||||
executor: &mut E,
|
||||
state: &mut State<C, FT, I, R>,
|
||||
state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
manager: &mut EM,
|
||||
corpus_idx: usize,
|
||||
) -> Result<(), AflError>;
|
||||
}
|
||||
|
||||
pub trait StagesTuple<C, E, EM, FT, I, OT, R>
|
||||
pub trait StagesTuple<C, E, EM, FT, I, OC, OFT, OT, R>
|
||||
where
|
||||
EM: EventManager<I>,
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
OT: ObserversTuple,
|
||||
FT: FeedbacksTuple<I>,
|
||||
C: Corpus<I, R>,
|
||||
@ -51,18 +55,20 @@ where
|
||||
&mut self,
|
||||
rand: &mut R,
|
||||
executor: &mut E,
|
||||
state: &mut State<C, FT, I, R>,
|
||||
state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
manager: &mut EM,
|
||||
corpus_idx: usize,
|
||||
) -> Result<(), AflError>;
|
||||
fn for_each(&self, f: fn(&dyn Stage<C, E, EM, FT, I, OT, R>));
|
||||
fn for_each_mut(&mut self, f: fn(&mut dyn Stage<C, E, EM, FT, I, OT, R>));
|
||||
fn for_each(&self, f: fn(&dyn Stage<C, E, EM, FT, I, OC, OFT, OT, R>));
|
||||
fn for_each_mut(&mut self, f: fn(&mut dyn Stage<C, E, EM, FT, I, OC, OFT, OT, R>));
|
||||
}
|
||||
|
||||
impl<C, E, EM, FT, I, OT, R> StagesTuple<C, E, EM, FT, I, OT, R> for ()
|
||||
impl<C, E, EM, FT, I, OC, OFT, OT, R> StagesTuple<C, E, EM, FT, I, OC, OFT, OT, R> for ()
|
||||
where
|
||||
EM: EventManager<I>,
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
OT: ObserversTuple,
|
||||
FT: FeedbacksTuple<I>,
|
||||
C: Corpus<I, R>,
|
||||
@ -73,22 +79,25 @@ where
|
||||
&mut self,
|
||||
_rand: &mut R,
|
||||
_executor: &mut E,
|
||||
_state: &mut State<C, FT, I, R>,
|
||||
_state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
_manager: &mut EM,
|
||||
_corpus_idx: usize,
|
||||
) -> Result<(), AflError> {
|
||||
Ok(())
|
||||
}
|
||||
fn for_each(&self, _f: fn(&dyn Stage<C, E, EM, FT, I, OT, R>)) {}
|
||||
fn for_each_mut(&mut self, _f: fn(&mut dyn Stage<C, E, EM, FT, I, OT, R>)) {}
|
||||
fn for_each(&self, _f: fn(&dyn Stage<C, E, EM, FT, I, OC, OFT, OT, R>)) {}
|
||||
fn for_each_mut(&mut self, _f: fn(&mut dyn Stage<C, E, EM, FT, I, OC, OFT, OT, R>)) {}
|
||||
}
|
||||
|
||||
impl<Head, Tail, EM, E, OT, FT, C, I, R> StagesTuple<C, E, EM, FT, I, OT, R> for (Head, Tail)
|
||||
impl<Head, Tail, EM, E, OC, OFT, OT, FT, C, I, R> StagesTuple<C, E, EM, FT, I, OC, OFT, OT, R>
|
||||
for (Head, Tail)
|
||||
where
|
||||
Head: Stage<C, E, EM, FT, I, OT, R>,
|
||||
Tail: StagesTuple<C, E, EM, FT, I, OT, R> + TupleList,
|
||||
Head: Stage<C, E, EM, FT, I, OC, OFT, OT, R>,
|
||||
Tail: StagesTuple<C, E, EM, FT, I, OC, OFT, OT, R> + TupleList,
|
||||
EM: EventManager<I>,
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
OT: ObserversTuple,
|
||||
FT: FeedbacksTuple<I>,
|
||||
C: Corpus<I, R>,
|
||||
@ -99,7 +108,7 @@ where
|
||||
&mut self,
|
||||
rand: &mut R,
|
||||
executor: &mut E,
|
||||
state: &mut State<C, FT, I, R>,
|
||||
state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
manager: &mut EM,
|
||||
corpus_idx: usize,
|
||||
) -> Result<(), AflError> {
|
||||
@ -108,12 +117,12 @@ where
|
||||
.perform_all(rand, executor, state, manager, corpus_idx)
|
||||
}
|
||||
|
||||
fn for_each(&self, f: fn(&dyn Stage<C, E, EM, FT, I, OT, R>)) {
|
||||
fn for_each(&self, f: fn(&dyn Stage<C, E, EM, FT, I, OC, OFT, OT, R>)) {
|
||||
f(&self.0);
|
||||
self.1.for_each(f)
|
||||
}
|
||||
|
||||
fn for_each_mut(&mut self, f: fn(&mut dyn Stage<C, E, EM, FT, I, OT, R>)) {
|
||||
fn for_each_mut(&mut self, f: fn(&mut dyn Stage<C, E, EM, FT, I, OC, OFT, OT, R>)) {
|
||||
f(&mut self.0);
|
||||
self.1.for_each_mut(f)
|
||||
}
|
||||
|
@ -19,11 +19,14 @@ use crate::{
|
||||
/// A Mutational stage is the stage in a fuzzing run that mutates inputs.
|
||||
/// Mutational stages will usually have a range of mutations that are
|
||||
/// being applied to the input one by one, between executions.
|
||||
pub trait MutationalStage<C, E, EM, FT, I, M, OT, R>: Stage<C, E, EM, FT, I, OT, R>
|
||||
pub trait MutationalStage<C, E, EM, FT, I, M, OC, OFT, OT, R>:
|
||||
Stage<C, E, EM, FT, I, OC, OFT, OT, R>
|
||||
where
|
||||
M: Mutator<C, I, R, State<C, FT, I, R>>,
|
||||
M: Mutator<C, I, R, State<C, FT, I, OC, OFT, R>>,
|
||||
EM: EventManager<I>,
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
OT: ObserversTuple,
|
||||
FT: FeedbacksTuple<I>,
|
||||
C: Corpus<I, R>,
|
||||
@ -48,7 +51,7 @@ where
|
||||
&mut self,
|
||||
rand: &mut R,
|
||||
executor: &mut E,
|
||||
state: &mut State<C, FT, I, R>,
|
||||
state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
manager: &mut EM,
|
||||
corpus_idx: usize,
|
||||
) -> Result<(), AflError> {
|
||||
@ -102,30 +105,34 @@ where
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// The default mutational stage
|
||||
pub struct StdMutationalStage<C, E, EM, FT, I, M, OT, R>
|
||||
pub struct StdMutationalStage<C, E, EM, FT, I, M, OC, OFT, OT, R>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
EM: EventManager<I>,
|
||||
FT: FeedbacksTuple<I>,
|
||||
I: Input,
|
||||
M: Mutator<C, I, R, State<C, FT, I, R>>,
|
||||
M: Mutator<C, I, R, State<C, FT, I, OC, OFT, R>>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
OT: ObserversTuple,
|
||||
R: Rand,
|
||||
{
|
||||
mutator: M,
|
||||
phantom: PhantomData<(EM, E, OT, FT, C, I, R)>,
|
||||
phantom: PhantomData<(EM, E, OC, OFT, OT, FT, C, I, R)>,
|
||||
}
|
||||
|
||||
impl<C, E, EM, FT, I, M, OT, R> MutationalStage<C, E, EM, FT, I, M, OT, R>
|
||||
for StdMutationalStage<C, E, EM, FT, I, M, OT, R>
|
||||
impl<C, E, EM, FT, I, M, OC, OFT, OT, R> MutationalStage<C, E, EM, FT, I, M, OC, OFT, OT, R>
|
||||
for StdMutationalStage<C, E, EM, FT, I, M, OC, OFT, OT, R>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
EM: EventManager<I>,
|
||||
FT: FeedbacksTuple<I>,
|
||||
I: Input,
|
||||
M: Mutator<C, I, R, State<C, FT, I, R>>,
|
||||
M: Mutator<C, I, R, State<C, FT, I, OC, OFT, R>>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
OT: ObserversTuple,
|
||||
R: Rand,
|
||||
{
|
||||
@ -142,12 +149,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, E, EM, FT, I, M, OT, R> Stage<C, E, EM, FT, I, OT, R>
|
||||
for StdMutationalStage<C, E, EM, FT, I, M, OT, R>
|
||||
impl<C, E, EM, FT, I, M, OC, OFT, OT, R> Stage<C, E, EM, FT, I, OC, OFT, OT, R>
|
||||
for StdMutationalStage<C, E, EM, FT, I, M, OC, OFT, OT, R>
|
||||
where
|
||||
M: Mutator<C, I, R, State<C, FT, I, R>>,
|
||||
M: Mutator<C, I, R, State<C, FT, I, OC, OFT, R>>,
|
||||
EM: EventManager<I>,
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
OT: ObserversTuple,
|
||||
FT: FeedbacksTuple<I>,
|
||||
C: Corpus<I, R>,
|
||||
@ -159,7 +168,7 @@ where
|
||||
&mut self,
|
||||
rand: &mut R,
|
||||
executor: &mut E,
|
||||
state: &mut State<C, FT, I, R>,
|
||||
state: &mut State<C, FT, I, OC, OFT, R>,
|
||||
manager: &mut EM,
|
||||
corpus_idx: usize,
|
||||
) -> Result<(), AflError> {
|
||||
@ -167,11 +176,13 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, E, EM, FT, I, M, OT, R> StdMutationalStage<C, E, EM, FT, I, M, OT, R>
|
||||
impl<C, E, EM, FT, I, M, OC, OFT, OT, R> StdMutationalStage<C, E, EM, FT, I, M, OC, OFT, OT, R>
|
||||
where
|
||||
M: Mutator<C, I, R, State<C, FT, I, R>>,
|
||||
M: Mutator<C, I, R, State<C, FT, I, OC, OFT, R>>,
|
||||
EM: EventManager<I>,
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
OT: ObserversTuple,
|
||||
FT: FeedbacksTuple<I>,
|
||||
C: Corpus<I, R>,
|
||||
|
@ -57,12 +57,14 @@ pub trait HasMetadata {
|
||||
/// The state a fuzz run.
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(bound = "FT: serde::de::DeserializeOwned")]
|
||||
pub struct State<C, FT, I, R>
|
||||
pub struct State<C, FT, I, OC, OFT, R>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
FT: FeedbacksTuple<I>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
{
|
||||
/// How many times the executor ran the harness/target
|
||||
executions: usize,
|
||||
@ -73,18 +75,24 @@ where
|
||||
start_time: u64,
|
||||
/// Metadata stored for this state by one of the components
|
||||
metadata: SerdeAnyMap,
|
||||
// additional_corpuses, maybe another TupleList?
|
||||
// Feedbacks used to evaluate an input
|
||||
/// Feedbacks used to evaluate an input
|
||||
feedbacks: FT,
|
||||
// Objective corpus
|
||||
objective_corpus: OC,
|
||||
/// Objective Feedbacks
|
||||
objective_feedbacks: OFT,
|
||||
|
||||
phantom: PhantomData<(R, I)>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<C, FT, R> State<C, FT, BytesInput, R>
|
||||
impl<C, FT, OC, OFT, R> State<C, FT, BytesInput, OC, OFT, R>
|
||||
where
|
||||
C: Corpus<BytesInput, R>,
|
||||
R: Rand,
|
||||
FT: FeedbacksTuple<BytesInput>,
|
||||
OC: Corpus<BytesInput, R>,
|
||||
OFT: FeedbacksTuple<BytesInput>,
|
||||
{
|
||||
pub fn load_from_directory<E, OT, EM>(
|
||||
&mut self,
|
||||
@ -153,12 +161,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, FT, I, R> HasCorpus<C, I, R> for State<C, FT, I, R>
|
||||
impl<C, FT, I, OC, OFT, R> HasCorpus<C, I, R> for State<C, FT, I, OC, OFT, R>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
FT: FeedbacksTuple<I>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
{
|
||||
/// Returns the corpus
|
||||
fn corpus(&self) -> &C {
|
||||
@ -172,12 +182,14 @@ where
|
||||
}
|
||||
|
||||
/// Trait for elements offering metadata
|
||||
impl<C, FT, I, R> HasMetadata for State<C, FT, I, R>
|
||||
impl<C, FT, I, OC, OFT, R> HasMetadata for State<C, FT, I, OC, OFT, R>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
FT: FeedbacksTuple<I>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
{
|
||||
/// Get all the metadata into an HashMap
|
||||
#[inline]
|
||||
@ -192,12 +204,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, FT, I, R> State<C, FT, I, R>
|
||||
impl<C, FT, I, OC, OFT, R> State<C, FT, I, OC, OFT, R>
|
||||
where
|
||||
C: Corpus<I, R>,
|
||||
I: Input,
|
||||
R: Rand,
|
||||
FT: FeedbacksTuple<I>,
|
||||
OC: Corpus<I, R>,
|
||||
OFT: FeedbacksTuple<I>,
|
||||
{
|
||||
/// Get executions
|
||||
#[inline]
|
||||
@ -349,13 +363,15 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn new(corpus: C, feedbacks: FT) -> Self {
|
||||
pub fn new(corpus: C, feedbacks: FT, objective_corpus: OC, objective_feedbacks: OFT) -> Self {
|
||||
Self {
|
||||
corpus,
|
||||
executions: 0,
|
||||
start_time: current_milliseconds(),
|
||||
metadata: SerdeAnyMap::default(),
|
||||
feedbacks: feedbacks,
|
||||
objective_corpus: objective_corpus,
|
||||
objective_feedbacks: objective_feedbacks,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use std::{env, path::PathBuf};
|
||||
|
||||
use afl::{
|
||||
bolts::{serdeany::RegistryBuilder, shmem::AflShmem, tuples::tuple_list},
|
||||
corpus::{Corpus, InMemoryCorpus},
|
||||
corpus::{Corpus, InMemoryCorpus, OnDiskCorpus},
|
||||
events::setup_restarting_mgr,
|
||||
executors::{inprocess::InProcessExecutor, Executor, ExitKind},
|
||||
feedbacks::MaxMapFeedback,
|
||||
@ -59,18 +59,27 @@ pub fn main() {
|
||||
"Workdir: {:?}",
|
||||
env::current_dir().unwrap().to_string_lossy().to_string()
|
||||
);
|
||||
fuzz(vec![PathBuf::from("./corpus")], 1337).expect("An error occurred while fuzzing");
|
||||
fuzz(
|
||||
vec![PathBuf::from("./corpus")],
|
||||
PathBuf::from("./crashes"),
|
||||
1337,
|
||||
)
|
||||
.expect("An error occurred while fuzzing");
|
||||
}
|
||||
|
||||
/// The actual fuzzer
|
||||
fn fuzz(corpus_dirs: Vec<PathBuf>, broker_port: u16) -> Result<(), AflError> {
|
||||
fn fuzz(
|
||||
corpus_dirs: Vec<PathBuf>,
|
||||
objective_dir: PathBuf,
|
||||
broker_port: u16,
|
||||
) -> Result<(), AflError> {
|
||||
let mut rand = StdRand::new(0);
|
||||
// 'While the stats are state, they are usually used in the broker - which is likely never restarted
|
||||
let stats = SimpleStats::new(|s| println!("{}", s));
|
||||
|
||||
// The restarting state will spawn the same process again as child, then restarted it each time it crashes.
|
||||
let (state, mut restarting_mgr) =
|
||||
setup_restarting_mgr::<_, _, _, _, AflShmem, _>(stats, broker_port)
|
||||
setup_restarting_mgr::<_, _, _, _, _, _, AflShmem, _>(stats, broker_port)
|
||||
.expect("Failed to setup the restarter".into());
|
||||
|
||||
// Create an observation channel using the coverage map
|
||||
@ -86,6 +95,8 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, broker_port: u16) -> Result<(), AflError> {
|
||||
&NAME_COV_MAP,
|
||||
&edges_observer
|
||||
)),
|
||||
OnDiskCorpus::new(objective_dir),
|
||||
tuple_list!(),
|
||||
));
|
||||
|
||||
println!("We're a client, let's fuzz :)");
|
||||
|
Loading…
x
Reference in New Issue
Block a user