scheduler half finished
This commit is contained in:
parent
0f40ac05d4
commit
3aa9439e80
@ -7,7 +7,7 @@ use libafl::{
|
||||
bolts::{shmem::UnixShMem, tuples::tuple_list},
|
||||
corpus::{
|
||||
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
||||
RandCorpusScheduler,
|
||||
RandCorpusScheduler,QueueCorpusScheduler
|
||||
},
|
||||
events::setup_restarting_mgr,
|
||||
executors::{inprocess::InProcessExecutor, Executor, ExitKind},
|
||||
@ -119,8 +119,8 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
|
||||
let stage = StdMutationalStage::new(mutator);
|
||||
|
||||
// A fuzzer with just one stage and a minimization+queue policy to get testcasess from the corpus
|
||||
let scheduler = IndexesLenTimeMinimizerCorpusScheduler::new(RandCorpusScheduler::new());
|
||||
//let scheduler = RandCorpusScheduler::new();
|
||||
//let scheduler = IndexesLenTimeMinimizerCorpusScheduler::new(RandCorpusScheduler::new());
|
||||
let scheduler = QueueCorpusScheduler::new();
|
||||
let fuzzer = StdFuzzer::new(scheduler, tuple_list!(stage));
|
||||
|
||||
// Create the executor for an in-process function with just one observer for edge coverage
|
||||
@ -139,6 +139,8 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
|
||||
println!("Warning: LLVMFuzzerInitialize failed with -1")
|
||||
}
|
||||
}
|
||||
|
||||
std::thread::sleep_ms(2000);
|
||||
|
||||
// In case the corpus is empty (on first run), reset
|
||||
if state.corpus().count() < 1 {
|
||||
@ -150,7 +152,7 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
|
||||
));
|
||||
println!("We imported {} inputs from disk.", state.corpus().count());
|
||||
}
|
||||
|
||||
|
||||
fuzzer.fuzz_loop(&mut state, &mut executor, &mut restarting_mgr)?;
|
||||
|
||||
// Never reached
|
||||
|
@ -179,6 +179,9 @@ where
|
||||
}
|
||||
|
||||
pub fn cull(&self, state: &mut S) -> Result<(), Error> {
|
||||
if state.metadatas().get::<TopRatedsMetadata>().is_none() {
|
||||
return Ok(());
|
||||
}
|
||||
let mut acc = HashSet::new();
|
||||
let top_rated = state.metadatas().get::<TopRatedsMetadata>().unwrap();
|
||||
|
||||
|
@ -281,7 +281,7 @@ 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)?.is_none() {
|
||||
if !state.add_if_interesting(&input, fitness, scheduler)?.is_none() {
|
||||
#[cfg(feature = "std")]
|
||||
println!("Added received Testcase");
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ where
|
||||
.clone();
|
||||
self.mutator().mutate(state, &mut input_mut, i as i32)?;
|
||||
|
||||
let fitness = state.evaluate_input(input_mut, executor, manager)?;
|
||||
let fitness = state.evaluate_input(input_mut, executor, manager, scheduler)?;
|
||||
|
||||
self.mutator().post_exec(state, fitness, i as i32)?;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ use std::{
|
||||
|
||||
use crate::{
|
||||
bolts::serdeany::{SerdeAny, SerdeAnyMap},
|
||||
corpus::{Corpus, Testcase},
|
||||
corpus::{Corpus, Testcase, CorpusScheduler},
|
||||
events::{Event, EventManager, LogSeverity},
|
||||
executors::{Executor, ExitKind, HasObservers},
|
||||
feedbacks::FeedbacksTuple,
|
||||
@ -175,7 +175,10 @@ where
|
||||
OT: ObserversTuple;
|
||||
|
||||
/// Adds this input to the corpus, if it's intersting, and return the index
|
||||
fn add_if_interesting(&mut self, input: &I, fitness: u32) -> 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;
|
||||
}
|
||||
|
||||
/// Evaluate an input modyfing the state of the fuzzer and returning a fitness
|
||||
@ -184,16 +187,18 @@ where
|
||||
I: Input,
|
||||
{
|
||||
/// Runs the input and triggers observers and feedback
|
||||
fn evaluate_input<E, EM, OT>(
|
||||
fn evaluate_input<CS, E, EM, OT>(
|
||||
&mut self,
|
||||
input: I,
|
||||
executor: &mut E,
|
||||
event_mgr: &mut EM,
|
||||
manager: &mut EM,
|
||||
scheduler: &CS,
|
||||
) -> Result<u32, Error>
|
||||
where
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
OT: ObserversTuple,
|
||||
EM: EventManager<I, Self>;
|
||||
EM: EventManager<I, Self>,
|
||||
CS: CorpusScheduler<I, Self>;
|
||||
}
|
||||
|
||||
/// The state a fuzz run.
|
||||
@ -450,10 +455,15 @@ where
|
||||
|
||||
/// Adds this input to the corpus, if it's intersting, and return the index
|
||||
#[inline]
|
||||
fn add_if_interesting(&mut self, input: &I, fitness: u32) -> 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>
|
||||
{
|
||||
if fitness > 0 {
|
||||
let testcase = self.testcase_with_feedbacks_metadata(input.clone(), fitness)?;
|
||||
Ok(Some(self.corpus.add(testcase)?)) // TODO scheduler hook
|
||||
let idx = self.corpus.add(testcase)?;
|
||||
scheduler.on_add(self, idx)?;
|
||||
Ok(Some(idx))
|
||||
} else {
|
||||
self.discard_feedbacks_metadata(input)?;
|
||||
Ok(None)
|
||||
@ -472,18 +482,20 @@ where
|
||||
{
|
||||
/// Process one input, adding to the respective corpuses if needed and firing the right events
|
||||
#[inline]
|
||||
fn evaluate_input<E, EM, OT>(
|
||||
fn evaluate_input<CS, E, EM, OT>(
|
||||
&mut self,
|
||||
// TODO probably we can take a ref to input and pass a cloned one to add_if_interesting
|
||||
input: I,
|
||||
executor: &mut E,
|
||||
manager: &mut EM,
|
||||
scheduler: &CS,
|
||||
) -> Result<u32, Error>
|
||||
where
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
OT: ObserversTuple,
|
||||
C: Corpus<I>,
|
||||
EM: EventManager<I, Self>,
|
||||
CS: CorpusScheduler<I, Self>
|
||||
{
|
||||
let (fitness, is_solution) = self.execute_input(&input, executor, manager)?;
|
||||
let observers = executor.observers();
|
||||
@ -493,7 +505,7 @@ where
|
||||
self.solutions_mut().add(Testcase::new(input.clone()))?;
|
||||
}
|
||||
|
||||
if !self.add_if_interesting(&input, fitness)?.is_none() {
|
||||
if !self.add_if_interesting(&input, fitness, scheduler)?.is_none() {
|
||||
let observers_buf = manager.serialize_observers(observers)?;
|
||||
manager.fire(
|
||||
self,
|
||||
@ -521,17 +533,18 @@ where
|
||||
SC: Corpus<BytesInput>,
|
||||
OFT: FeedbacksTuple<BytesInput>,
|
||||
{
|
||||
pub fn load_from_directory<E, OT, EM>(
|
||||
pub fn load_from_directory<CS, E, OT, EM>(
|
||||
&mut self,
|
||||
executor: &mut E,
|
||||
manager: &mut EM,
|
||||
scheduler: &CS,
|
||||
in_dir: &Path,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
C: Corpus<BytesInput>,
|
||||
E: Executor<BytesInput> + HasObservers<OT>,
|
||||
OT: ObserversTuple,
|
||||
EM: EventManager<BytesInput, Self>,
|
||||
CS: CorpusScheduler<BytesInput, Self>
|
||||
{
|
||||
for entry in fs::read_dir(in_dir)? {
|
||||
let entry = entry?;
|
||||
@ -549,34 +562,35 @@ 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)?.is_none() {
|
||||
if self.add_if_interesting(&input, fitness, scheduler)?.is_none() {
|
||||
println!("File {:?} was not interesting, skipped.", &path);
|
||||
}
|
||||
if is_solution {
|
||||
println!("File {:?} is a solution, however will be not considered as it is an initial testcase.", &path);
|
||||
}
|
||||
} else if attr.is_dir() {
|
||||
self.load_from_directory(executor, manager, &path)?;
|
||||
self.load_from_directory(executor, manager, scheduler, &path)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn load_initial_inputs<E, OT, EM>(
|
||||
pub fn load_initial_inputs<CS, E, OT, EM>(
|
||||
&mut self,
|
||||
executor: &mut E,
|
||||
manager: &mut EM,
|
||||
scheduler: &CS,
|
||||
in_dirs: &[PathBuf],
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
C: Corpus<BytesInput>,
|
||||
E: Executor<BytesInput> + HasObservers<OT>,
|
||||
OT: ObserversTuple,
|
||||
EM: EventManager<BytesInput, Self>,
|
||||
CS: CorpusScheduler<BytesInput, Self>,
|
||||
{
|
||||
for in_dir in in_dirs {
|
||||
self.load_from_directory(executor, manager, in_dir)?;
|
||||
self.load_from_directory(executor, manager, scheduler, in_dir)?;
|
||||
}
|
||||
manager.fire(
|
||||
self,
|
||||
@ -634,11 +648,12 @@ where
|
||||
Ok((fitness, is_solution))
|
||||
}
|
||||
|
||||
pub fn generate_initial_inputs<G, E, OT, EM>(
|
||||
pub fn generate_initial_inputs<CS, G, E, OT, EM>(
|
||||
&mut self,
|
||||
executor: &mut E,
|
||||
generator: &mut G,
|
||||
manager: &mut EM,
|
||||
scheduler: &CS,
|
||||
num: usize,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
@ -647,11 +662,12 @@ where
|
||||
E: Executor<I> + HasObservers<OT>,
|
||||
OT: ObserversTuple,
|
||||
EM: EventManager<I, Self>,
|
||||
CS: CorpusScheduler<I, Self>
|
||||
{
|
||||
let mut added = 0;
|
||||
for _ in 0..num {
|
||||
let input = generator.generate(self.rand_mut())?;
|
||||
let fitness = self.evaluate_input(input, executor, manager)?;
|
||||
let fitness = self.evaluate_input(input, executor, manager, scheduler)?;
|
||||
if fitness > 0 {
|
||||
added += 1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user