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