This commit is contained in:
Andrea Fioraldi 2021-03-01 10:04:59 +01:00
parent 9ba508f77a
commit dc39a5591a
8 changed files with 95 additions and 37 deletions

View File

@ -6,12 +6,13 @@ use std::{env, path::PathBuf};
use libafl::{
bolts::{shmem::UnixShMem, tuples::tuple_list},
corpus::{
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, QueueCorpusScheduler
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
QueueCorpusScheduler,
},
events::setup_restarting_mgr,
executors::{inprocess::InProcessExecutor, Executor, ExitKind},
feedbacks::{CrashFeedback, MaxMapFeedback},
fuzzer::{Fuzzer, StdFuzzer, HasCorpusScheduler},
fuzzer::{Fuzzer, HasCorpusScheduler, StdFuzzer},
inputs::Input,
mutators::scheduled::HavocBytesMutator,
mutators::token_mutations::TokensMetadata,
@ -91,7 +92,11 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
// Corpus that will be evolved, we keep it in memory for performance
InMemoryCorpus::new(),
// Feedbacks to rate the interestingness of an input
tuple_list!(MaxMapFeedback::new_with_observer_track(&edges_observer, true, false)),
tuple_list!(MaxMapFeedback::new_with_observer_track(
&edges_observer,
true,
false
)),
// Corpus in which we store solutions (crashes in this example),
// on disk so the user can get them after stopping the fuzzer
OnDiskCorpus::new(objective_dir),
@ -142,7 +147,12 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
// In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 {
state
.load_initial_inputs(&mut executor, &mut restarting_mgr, fuzzer.scheduler(), &corpus_dirs)
.load_initial_inputs(
&mut executor,
&mut restarting_mgr,
fuzzer.scheduler(),
&corpus_dirs,
)
.expect(&format!(
"Failed to load initial corpus at {:?}",
&corpus_dirs

View File

@ -17,12 +17,12 @@ use crate::{
llmp::{self, LlmpClient, LlmpClientDescription, Tag},
shmem::ShMem,
},
corpus::CorpusScheduler,
events::{BrokerEventResult, Event, EventManager},
executors::ExitKind,
executors::{Executor, HasObservers},
inputs::Input,
observers::ObserversTuple,
corpus::CorpusScheduler,
state::IfInteresting,
stats::Stats,
Error,
@ -284,7 +284,10 @@ where
// TODO include ExitKind in NewTestcase
let fitness = state.is_interesting(&input, &observers, ExitKind::Ok)?;
if fitness > 0 {
if !state.add_if_interesting(&input, fitness, scheduler)?.is_none() {
if !state
.add_if_interesting(&input, fitness, scheduler)?
.is_none()
{
#[cfg(feature = "std")]
println!("Added received Testcase");
}
@ -318,11 +321,16 @@ where
}
}
fn process<CS, E, OT>(&mut self, state: &mut S, executor: &mut E, scheduler: &CS) -> Result<usize, Error>
fn process<CS, E, OT>(
&mut self,
state: &mut S,
executor: &mut E,
scheduler: &CS,
) -> Result<usize, Error>
where
CS: CorpusScheduler<I, S>,
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple
OT: ObserversTuple,
{
// TODO: Get around local event copy by moving handle_in_client
let mut events = vec![];
@ -430,11 +438,16 @@ where
.send_buf(_LLMP_TAG_RESTART, &state_corpus_serialized)
}
fn process<CS, E, OT>(&mut self, state: &mut S, executor: &mut E, scheduler: &CS) -> Result<usize, Error>
fn process<CS, E, OT>(
&mut self,
state: &mut S,
executor: &mut E,
scheduler: &CS,
) -> Result<usize, Error>
where
CS: CorpusScheduler<I, S>,
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple
OT: ObserversTuple,
{
self.llmp_mgr.process(state, executor, scheduler)
}

View File

@ -10,9 +10,9 @@ use core::{fmt, marker::PhantomData, time::Duration};
use serde::{Deserialize, Serialize};
use crate::{
corpus::CorpusScheduler,
executors::{Executor, HasObservers},
inputs::Input,
corpus::{ CorpusScheduler},
observers::ObserversTuple,
Error,
};
@ -160,7 +160,12 @@ where
/// Lookup for incoming events and process them.
/// Return the number of processes events or an error
fn process<CS, E, OT>(&mut self, state: &mut S, executor: &mut E, scheduler: &CS) -> Result<usize, Error>
fn process<CS, E, OT>(
&mut self,
state: &mut S,
executor: &mut E,
scheduler: &CS,
) -> Result<usize, Error>
where
CS: CorpusScheduler<I, S>,
E: Executor<I> + HasObservers<OT>,
@ -205,7 +210,12 @@ impl<I, S> EventManager<I, S> for NopEventManager<I, S>
where
I: Input,
{
fn process<CS, E, OT>(&mut self, _state: &mut S, _executor: &mut E, _scheduler: &CS) -> Result<usize, Error>
fn process<CS, E, OT>(
&mut self,
_state: &mut S,
_executor: &mut E,
_scheduler: &CS,
) -> Result<usize, Error>
where
CS: CorpusScheduler<I, S>,
E: Executor<I> + HasObservers<OT>,

View File

@ -3,11 +3,11 @@ use alloc::{string::ToString, vec::Vec};
use core::marker::PhantomData;
use crate::{
corpus::CorpusScheduler,
events::{BrokerEventResult, Event, EventManager},
executors::{Executor, HasObservers},
inputs::Input,
observers::ObserversTuple,
corpus::CorpusScheduler,
stats::Stats,
Error,
};
@ -31,11 +31,16 @@ where
I: Input,
ST: Stats, //CE: CustomEvent<I, OT>,
{
fn process<CS, E, OT>(&mut self, state: &mut S, _executor: &mut E, _scheduler: &CS) -> Result<usize, Error>
fn process<CS, E, OT>(
&mut self,
state: &mut S,
_executor: &mut E,
_scheduler: &CS,
) -> Result<usize, Error>
where
CS: CorpusScheduler<I, S>,
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple
OT: ObserversTuple,
{
let count = self.events.len();
while self.events.len() > 0 {

View File

@ -105,7 +105,8 @@ where
fn fuzz_one(&self, state: &mut S, executor: &mut E, manager: &mut EM) -> Result<usize, Error> {
let idx = self.scheduler().next(state)?;
self.stages().perform_all(state, executor, manager, self.scheduler(), idx)?;
self.stages()
.perform_all(state, executor, manager, self.scheduler(), idx)?;
manager.process(state, executor, self.scheduler())?;
Ok(idx)

View File

@ -67,7 +67,9 @@ where
scheduler: &CS,
corpus_idx: usize,
) -> Result<(), Error> {
self.0.perform(state, executor, manager, scheduler, corpus_idx)?;
self.1.perform_all(state, executor, manager, scheduler, corpus_idx)
self.0
.perform(state, executor, manager, scheduler, corpus_idx)?;
self.1
.perform_all(state, executor, manager, scheduler, corpus_idx)
}
}

View File

@ -27,7 +27,7 @@ where
EM: EventManager<I, S>,
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple,
CS: CorpusScheduler<I, S>
CS: CorpusScheduler<I, S>,
{
/// The mutator registered for this stage
fn mutator(&self) -> &M;
@ -116,7 +116,8 @@ where
}
}
impl<C, CS, E, EM, I, M, OT, R, S> Stage<CS, E, EM, I, S> for StdMutationalStage<C, CS, E, EM, I, M, OT, R, S>
impl<C, CS, E, EM, I, M, OT, R, S> Stage<CS, E, EM, I, S>
for StdMutationalStage<C, CS, E, EM, I, M, OT, R, S>
where
M: Mutator<I, S>,
I: Input,

View File

@ -10,7 +10,7 @@ use std::{
use crate::{
bolts::serdeany::{SerdeAny, SerdeAnyMap},
corpus::{Corpus, Testcase, CorpusScheduler},
corpus::{Corpus, CorpusScheduler, Testcase},
events::{Event, EventManager, LogSeverity},
executors::{Executor, ExitKind, HasObservers},
feedbacks::FeedbacksTuple,
@ -175,7 +175,12 @@ where
OT: ObserversTuple;
/// Adds this input to the corpus, if it's intersting, and return the index
fn add_if_interesting<CS>(&mut self, input: &I, fitness: u32, scheduler: &CS) -> Result<Option<usize>, Error>
fn add_if_interesting<CS>(
&mut self,
input: &I,
fitness: u32,
scheduler: &CS,
) -> Result<Option<usize>, Error>
where
CS: CorpusScheduler<I, Self>,
Self: Sized;
@ -455,9 +460,14 @@ where
/// Adds this input to the corpus, if it's intersting, and return the index
#[inline]
fn add_if_interesting<CS>(&mut self, input: &I, fitness: u32, scheduler: &CS) -> Result<Option<usize>, Error>
fn add_if_interesting<CS>(
&mut self,
input: &I,
fitness: u32,
scheduler: &CS,
) -> Result<Option<usize>, Error>
where
CS: CorpusScheduler<I, Self>
CS: CorpusScheduler<I, Self>,
{
if fitness > 0 {
let testcase = self.testcase_with_feedbacks_metadata(input.clone(), fitness)?;
@ -495,7 +505,7 @@ where
OT: ObserversTuple,
C: Corpus<I>,
EM: EventManager<I, Self>,
CS: CorpusScheduler<I, Self>
CS: CorpusScheduler<I, Self>,
{
let (fitness, is_solution) = self.execute_input(&input, executor, manager)?;
let observers = executor.observers();
@ -505,7 +515,10 @@ where
self.solutions_mut().add(Testcase::new(input.clone()))?;
}
if !self.add_if_interesting(&input, fitness, scheduler)?.is_none() {
if !self
.add_if_interesting(&input, fitness, scheduler)?
.is_none()
{
let observers_buf = manager.serialize_observers(observers)?;
manager.fire(
self,
@ -544,7 +557,7 @@ where
E: Executor<BytesInput> + HasObservers<OT>,
OT: ObserversTuple,
EM: EventManager<BytesInput, Self>,
CS: CorpusScheduler<BytesInput, Self>
CS: CorpusScheduler<BytesInput, Self>,
{
for entry in fs::read_dir(in_dir)? {
let entry = entry?;
@ -562,7 +575,10 @@ where
let bytes = fs::read(&path)?;
let input = BytesInput::new(bytes);
let (fitness, is_solution) = self.execute_input(&input, executor, manager)?;
if self.add_if_interesting(&input, fitness, scheduler)?.is_none() {
if self
.add_if_interesting(&input, fitness, scheduler)?
.is_none()
{
println!("File {:?} was not interesting, skipped.", &path);
}
if is_solution {
@ -662,7 +678,7 @@ where
E: Executor<I> + HasObservers<OT>,
OT: ObserversTuple,
EM: EventManager<I, Self>,
CS: CorpusScheduler<I, Self>
CS: CorpusScheduler<I, Self>,
{
let mut added = 0;
for _ in 0..num {