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