Make weigthed scheduler independent of powersheduler stage (#599)
* rename & add metadata in scheduler, not stage * Update testcase_score * rename * fix * update handicap in scheduler * fmt * update fuzzers * doc * fmt * fix * fmt * more * fix * fix * fix * fmt
This commit is contained in:
parent
92196cc9be
commit
283ceaac9b
@ -313,11 +313,11 @@ fn fuzz(
|
|||||||
5,
|
5,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let power =
|
let power = StdPowerMutationalStage::new(mutator, &edges_observer);
|
||||||
StdPowerMutationalStage::new(&mut state, mutator, &edges_observer, PowerSchedule::FAST);
|
|
||||||
|
|
||||||
// A minimization+queue policy to get testcasess from the corpus
|
// A minimization+queue policy to get testcasess from the corpus
|
||||||
let scheduler = IndexesLenTimeMinimizerScheduler::new(PowerQueueScheduler::new());
|
let scheduler =
|
||||||
|
IndexesLenTimeMinimizerScheduler::new(PowerQueueScheduler::new(PowerSchedule::FAST));
|
||||||
|
|
||||||
// A fuzzer with feedbacks and a corpus scheduler
|
// A fuzzer with feedbacks and a corpus scheduler
|
||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
@ -284,11 +284,11 @@ fn fuzz(
|
|||||||
5,
|
5,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let power =
|
let power = StdPowerMutationalStage::new(mutator, &edges_observer);
|
||||||
StdPowerMutationalStage::new(&mut state, mutator, &edges_observer, PowerSchedule::FAST);
|
|
||||||
|
|
||||||
// A minimization+queue policy to get testcasess from the corpus
|
// A minimization+queue policy to get testcasess from the corpus
|
||||||
let scheduler = IndexesLenTimeMinimizerScheduler::new(PowerQueueScheduler::new());
|
let scheduler =
|
||||||
|
IndexesLenTimeMinimizerScheduler::new(PowerQueueScheduler::new(PowerSchedule::FAST));
|
||||||
|
|
||||||
// A fuzzer with feedbacks and a corpus scheduler
|
// A fuzzer with feedbacks and a corpus scheduler
|
||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
@ -297,11 +297,11 @@ fn fuzz(
|
|||||||
5,
|
5,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let power =
|
let power = StdPowerMutationalStage::new(mutator, &edges_observer);
|
||||||
StdPowerMutationalStage::new(&mut state, mutator, &edges_observer, PowerSchedule::FAST);
|
|
||||||
|
|
||||||
// A minimization+queue policy to get testcasess from the corpus
|
// A minimization+queue policy to get testcasess from the corpus
|
||||||
let scheduler = IndexesLenTimeMinimizerScheduler::new(PowerQueueScheduler::new());
|
let scheduler =
|
||||||
|
IndexesLenTimeMinimizerScheduler::new(PowerQueueScheduler::new(PowerSchedule::FAST));
|
||||||
|
|
||||||
// A fuzzer with feedbacks and a corpus scheduler
|
// A fuzzer with feedbacks and a corpus scheduler
|
||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
@ -374,11 +374,11 @@ fn fuzz_binary(
|
|||||||
5,
|
5,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let power =
|
let power = StdPowerMutationalStage::new(mutator, &edges_observer);
|
||||||
StdPowerMutationalStage::new(&mut state, mutator, &edges_observer, PowerSchedule::FAST);
|
|
||||||
|
|
||||||
// A minimization+queue policy to get testcasess from the corpus
|
// A minimization+queue policy to get testcasess from the corpus
|
||||||
let scheduler = IndexesLenTimeMinimizerScheduler::new(PowerQueueScheduler::new());
|
let scheduler =
|
||||||
|
IndexesLenTimeMinimizerScheduler::new(PowerQueueScheduler::new(PowerSchedule::FAST));
|
||||||
|
|
||||||
// A fuzzer with feedbacks and a corpus scheduler
|
// A fuzzer with feedbacks and a corpus scheduler
|
||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
@ -584,8 +584,7 @@ fn fuzz_text(
|
|||||||
5,
|
5,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let power =
|
let power = StdPowerMutationalStage::new(mutator, &edges_observer);
|
||||||
StdPowerMutationalStage::new(&mut state, mutator, &edges_observer, PowerSchedule::FAST);
|
|
||||||
|
|
||||||
let grimoire_mutator = StdScheduledMutator::with_max_stack_pow(
|
let grimoire_mutator = StdScheduledMutator::with_max_stack_pow(
|
||||||
tuple_list!(
|
tuple_list!(
|
||||||
@ -601,7 +600,8 @@ fn fuzz_text(
|
|||||||
let grimoire = StdMutationalStage::new(grimoire_mutator);
|
let grimoire = StdMutationalStage::new(grimoire_mutator);
|
||||||
|
|
||||||
// A minimization+queue policy to get testcasess from the corpus
|
// A minimization+queue policy to get testcasess from the corpus
|
||||||
let scheduler = IndexesLenTimeMinimizerScheduler::new(PowerQueueScheduler::new());
|
let scheduler =
|
||||||
|
IndexesLenTimeMinimizerScheduler::new(PowerQueueScheduler::new(PowerSchedule::FAST));
|
||||||
|
|
||||||
// A fuzzer with feedbacks and a corpus scheduler
|
// A fuzzer with feedbacks and a corpus scheduler
|
||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
@ -313,8 +313,7 @@ fn fuzz(
|
|||||||
5,
|
5,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let power =
|
let power = StdMutationalStage::new(mutator);
|
||||||
StdPowerMutationalStage::new(&mut state, mutator, &edges_observer, PowerSchedule::RAND);
|
|
||||||
|
|
||||||
// A minimization+queue policy to get testcasess from the corpus
|
// A minimization+queue policy to get testcasess from the corpus
|
||||||
let scheduler = IndexesLenTimeMinimizerScheduler::new(StdWeightedScheduler::new());
|
let scheduler = IndexesLenTimeMinimizerScheduler::new(StdWeightedScheduler::new());
|
||||||
|
@ -132,8 +132,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
|
|||||||
let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations()));
|
let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations()));
|
||||||
|
|
||||||
let calibration = CalibrationStage::new(&edges_observer);
|
let calibration = CalibrationStage::new(&edges_observer);
|
||||||
let power =
|
let power = StdPowerMutationalStage::new(mutator, &edges_observer);
|
||||||
StdPowerMutationalStage::new(&mut state, mutator, &edges_observer, PowerSchedule::COE);
|
|
||||||
|
|
||||||
let mut stages = tuple_list!(calibration, power);
|
let mut stages = tuple_list!(calibration, power);
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ use libafl::{
|
|||||||
},
|
},
|
||||||
StdMapObserver, TimeObserver,
|
StdMapObserver, TimeObserver,
|
||||||
},
|
},
|
||||||
schedulers::{IndexesLenTimeMinimizerScheduler, PowerQueueScheduler},
|
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
|
||||||
stages::{
|
stages::{
|
||||||
ConcolicTracingStage, ShadowTracingStage, SimpleConcolicMutationalStage,
|
ConcolicTracingStage, ShadowTracingStage, SimpleConcolicMutationalStage,
|
||||||
StdMutationalStage, TracingStage,
|
StdMutationalStage, TracingStage,
|
||||||
@ -150,7 +150,7 @@ fn fuzz(
|
|||||||
println!("We're a client, let's fuzz :)");
|
println!("We're a client, let's fuzz :)");
|
||||||
|
|
||||||
// A minimization+queue policy to get testcasess from the corpus
|
// A minimization+queue policy to get testcasess from the corpus
|
||||||
let scheduler = IndexesLenTimeMinimizerScheduler::new(PowerQueueScheduler::new());
|
let scheduler = IndexesLenTimeMinimizerScheduler::new(QueueScheduler::new());
|
||||||
|
|
||||||
// A fuzzer with feedbacks and a corpus scheduler
|
// A fuzzer with feedbacks and a corpus scheduler
|
||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
@ -126,13 +126,12 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
|
|||||||
let mutator = LainMutator::new();
|
let mutator = LainMutator::new();
|
||||||
|
|
||||||
let calibration = CalibrationStage::new(&edges_observer);
|
let calibration = CalibrationStage::new(&edges_observer);
|
||||||
let power =
|
let power = StdPowerMutationalStage::new(mutator, &edges_observer);
|
||||||
StdPowerMutationalStage::new(&mut state, mutator, &edges_observer, PowerSchedule::FAST);
|
|
||||||
|
|
||||||
let mut stages = tuple_list!(calibration, power);
|
let mut stages = tuple_list!(calibration, power);
|
||||||
|
|
||||||
// A minimization+queue policy to get testcasess from the corpus
|
// A minimization+queue policy to get testcasess from the corpus
|
||||||
let scheduler = PacketLenMinimizerScheduler::new(PowerQueueScheduler::new());
|
let scheduler = PacketLenMinimizerScheduler::new(PowerQueueScheduler::new(PowerSchedule::FAST));
|
||||||
|
|
||||||
// A fuzzer with feedbacks and a corpus scheduler
|
// A fuzzer with feedbacks and a corpus scheduler
|
||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Corpuses contain the testcases, either in memory, on disk, or somewhere else.
|
//! Corpuses contain the testcases, either in memory, on disk, or somewhere else.
|
||||||
|
|
||||||
pub mod testcase;
|
pub mod testcase;
|
||||||
pub use testcase::{PowerScheduleTestcaseMetaData, Testcase};
|
pub use testcase::{SchedulerTestcaseMetaData, Testcase};
|
||||||
|
|
||||||
pub mod inmemory;
|
pub mod inmemory;
|
||||||
pub use inmemory::InMemoryCorpus;
|
pub use inmemory::InMemoryCorpus;
|
||||||
|
@ -276,7 +276,7 @@ where
|
|||||||
|
|
||||||
/// The Metadata for each testcase used in power schedules.
|
/// The Metadata for each testcase used in power schedules.
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct PowerScheduleTestcaseMetaData {
|
pub struct SchedulerTestcaseMetaData {
|
||||||
/// Number of bits set in bitmap, updated in calibrate_case
|
/// Number of bits set in bitmap, updated in calibrate_case
|
||||||
bitmap_size: u64,
|
bitmap_size: u64,
|
||||||
/// Number of queue cycles behind
|
/// Number of queue cycles behind
|
||||||
@ -287,8 +287,8 @@ pub struct PowerScheduleTestcaseMetaData {
|
|||||||
n_fuzz_entry: usize,
|
n_fuzz_entry: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PowerScheduleTestcaseMetaData {
|
impl SchedulerTestcaseMetaData {
|
||||||
/// Create new [`struct@PowerScheduleTestcaseMetaData`]
|
/// Create new [`struct@SchedulerTestcaseMetaData`]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(depth: u64) -> Self {
|
pub fn new(depth: u64) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -344,4 +344,4 @@ impl PowerScheduleTestcaseMetaData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::impl_serdeany!(PowerScheduleTestcaseMetaData);
|
crate::impl_serdeany!(SchedulerTestcaseMetaData);
|
||||||
|
@ -6,7 +6,7 @@ use alloc::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
corpus::{Corpus, PowerScheduleTestcaseMetaData},
|
corpus::{Corpus, SchedulerTestcaseMetaData},
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
schedulers::Scheduler,
|
schedulers::Scheduler,
|
||||||
state::{HasCorpus, HasMetadata},
|
state::{HasCorpus, HasMetadata},
|
||||||
@ -17,13 +17,13 @@ use serde::{Deserialize, Serialize};
|
|||||||
/// The n fuzz size
|
/// The n fuzz size
|
||||||
pub const N_FUZZ_SIZE: usize = 1 << 21;
|
pub const N_FUZZ_SIZE: usize = 1 << 21;
|
||||||
|
|
||||||
crate::impl_serdeany!(PowerScheduleMetadata);
|
crate::impl_serdeany!(SchedulerMetadata);
|
||||||
|
|
||||||
/// The metadata used for power schedules
|
/// The metadata used for power schedules
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct PowerScheduleMetadata {
|
pub struct SchedulerMetadata {
|
||||||
/// Powerschedule strategy
|
/// Powerschedule strategy
|
||||||
strat: PowerSchedule,
|
strat: Option<PowerSchedule>,
|
||||||
/// Measured exec time during calibration
|
/// Measured exec time during calibration
|
||||||
exec_time: Duration,
|
exec_time: Duration,
|
||||||
/// Calibration cycles
|
/// Calibration cycles
|
||||||
@ -39,10 +39,10 @@ pub struct PowerScheduleMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The metadata for runs in the calibration stage.
|
/// The metadata for runs in the calibration stage.
|
||||||
impl PowerScheduleMetadata {
|
impl SchedulerMetadata {
|
||||||
/// Creates a new [`struct@PowerScheduleMetadata`]
|
/// Creates a new [`struct@SchedulerMetadata`]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(strat: PowerSchedule) -> Self {
|
pub fn new(strat: Option<PowerSchedule>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
strat,
|
strat,
|
||||||
exec_time: Duration::from_millis(0),
|
exec_time: Duration::from_millis(0),
|
||||||
@ -56,7 +56,7 @@ impl PowerScheduleMetadata {
|
|||||||
|
|
||||||
/// The powerschedule strategy
|
/// The powerschedule strategy
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn strat(&self) -> PowerSchedule {
|
pub fn strat(&self) -> Option<PowerSchedule> {
|
||||||
self.strat
|
self.strat
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +132,6 @@ impl PowerScheduleMetadata {
|
|||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq)]
|
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq)]
|
||||||
pub enum PowerSchedule {
|
pub enum PowerSchedule {
|
||||||
RAND,
|
|
||||||
EXPLORE,
|
EXPLORE,
|
||||||
EXPLOIT,
|
EXPLOIT,
|
||||||
FAST,
|
FAST,
|
||||||
@ -143,12 +142,8 @@ pub enum PowerSchedule {
|
|||||||
|
|
||||||
/// A corpus scheduler using power schedules
|
/// A corpus scheduler using power schedules
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct PowerQueueScheduler;
|
pub struct PowerQueueScheduler {
|
||||||
|
strat: PowerSchedule,
|
||||||
impl Default for PowerQueueScheduler {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, S> Scheduler<I, S> for PowerQueueScheduler
|
impl<I, S> Scheduler<I, S> for PowerQueueScheduler
|
||||||
@ -158,6 +153,10 @@ where
|
|||||||
{
|
{
|
||||||
/// Add an entry to the corpus and return its index
|
/// Add an entry to the corpus and return its index
|
||||||
fn on_add(&self, state: &mut S, idx: usize) -> Result<(), Error> {
|
fn on_add(&self, state: &mut S, idx: usize) -> Result<(), Error> {
|
||||||
|
if !state.has_metadata::<SchedulerMetadata>() {
|
||||||
|
state.add_metadata::<SchedulerMetadata>(SchedulerMetadata::new(Some(self.strat)));
|
||||||
|
}
|
||||||
|
|
||||||
let current_idx = *state.corpus().current();
|
let current_idx = *state.corpus().current();
|
||||||
|
|
||||||
let mut depth = match current_idx {
|
let mut depth = match current_idx {
|
||||||
@ -166,19 +165,21 @@ where
|
|||||||
.get(parent_idx)?
|
.get(parent_idx)?
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.metadata_mut()
|
.metadata_mut()
|
||||||
.get_mut::<PowerScheduleTestcaseMetaData>()
|
.get_mut::<SchedulerTestcaseMetaData>()
|
||||||
.ok_or_else(|| Error::key_not_found("PowerScheduleTestData not found".to_string()))?
|
.ok_or_else(|| {
|
||||||
|
Error::key_not_found("SchedulerTestcaseMetaData not found".to_string())
|
||||||
|
})?
|
||||||
.depth(),
|
.depth(),
|
||||||
None => 0,
|
None => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Attach a `PowerScheduleTestData` to the queue entry.
|
// Attach a `SchedulerTestcaseMetaData` to the queue entry.
|
||||||
depth += 1;
|
depth += 1;
|
||||||
state
|
state
|
||||||
.corpus()
|
.corpus()
|
||||||
.get(idx)?
|
.get(idx)?
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.add_metadata(PowerScheduleTestcaseMetaData::new(depth));
|
.add_metadata(SchedulerTestcaseMetaData::new(depth));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,9 +192,9 @@ where
|
|||||||
if *cur + 1 >= state.corpus().count() {
|
if *cur + 1 >= state.corpus().count() {
|
||||||
let psmeta = state
|
let psmeta = state
|
||||||
.metadata_mut()
|
.metadata_mut()
|
||||||
.get_mut::<PowerScheduleMetadata>()
|
.get_mut::<SchedulerMetadata>()
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
Error::key_not_found("PowerScheduleMetadata not found".to_string())
|
Error::key_not_found("SchedulerMetadata not found".to_string())
|
||||||
})?;
|
})?;
|
||||||
psmeta.set_queue_cycles(psmeta.queue_cycles() + 1);
|
psmeta.set_queue_cycles(psmeta.queue_cycles() + 1);
|
||||||
0
|
0
|
||||||
@ -204,6 +205,22 @@ where
|
|||||||
None => 0,
|
None => 0,
|
||||||
};
|
};
|
||||||
*state.corpus_mut().current_mut() = Some(id);
|
*state.corpus_mut().current_mut() = Some(id);
|
||||||
|
|
||||||
|
// Update the handicap
|
||||||
|
let mut testcase = state.corpus().get(id)?.borrow_mut();
|
||||||
|
let tcmeta = testcase
|
||||||
|
.metadata_mut()
|
||||||
|
.get_mut::<SchedulerTestcaseMetaData>()
|
||||||
|
.ok_or_else(|| {
|
||||||
|
Error::key_not_found("SchedulerTestcaseMetaData not found".to_string())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if tcmeta.handicap() >= 4 {
|
||||||
|
tcmeta.set_handicap(tcmeta.handicap() - 4);
|
||||||
|
} else if tcmeta.handicap() > 0 {
|
||||||
|
tcmeta.set_handicap(tcmeta.handicap() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,7 +229,7 @@ where
|
|||||||
impl PowerQueueScheduler {
|
impl PowerQueueScheduler {
|
||||||
/// Create a new [`PowerQueueScheduler`]
|
/// Create a new [`PowerQueueScheduler`]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new(strat: PowerSchedule) -> Self {
|
||||||
Self
|
PowerQueueScheduler { strat }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
//! The `TestcaseScore` is an evaluator providing scores of corpus items.
|
//! The `TestcaseScore` is an evaluator providing scores of corpus items.
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::{HasLen, HasRefCnt},
|
bolts::{HasLen, HasRefCnt},
|
||||||
corpus::{Corpus, PowerScheduleTestcaseMetaData, Testcase},
|
corpus::{Corpus, SchedulerTestcaseMetaData, Testcase},
|
||||||
feedbacks::MapIndexesMetadata,
|
feedbacks::MapIndexesMetadata,
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
schedulers::{
|
schedulers::{
|
||||||
minimizer::{IsFavoredMetadata, TopRatedsMetadata},
|
minimizer::{IsFavoredMetadata, TopRatedsMetadata},
|
||||||
powersched::{PowerSchedule, PowerScheduleMetadata},
|
powersched::{PowerSchedule, SchedulerMetadata},
|
||||||
},
|
},
|
||||||
state::{HasCorpus, HasMetadata},
|
state::{HasCorpus, HasMetadata},
|
||||||
Error,
|
Error,
|
||||||
@ -79,10 +79,11 @@ where
|
|||||||
fn compute(entry: &mut Testcase<I>, state: &S) -> Result<f64, Error> {
|
fn compute(entry: &mut Testcase<I>, state: &S) -> Result<f64, Error> {
|
||||||
let psmeta = state
|
let psmeta = state
|
||||||
.metadata()
|
.metadata()
|
||||||
.get::<PowerScheduleMetadata>()
|
.get::<SchedulerMetadata>()
|
||||||
.ok_or_else(|| Error::key_not_found("PowerScheduleMetadata not found".to_string()))?;
|
.ok_or_else(|| Error::key_not_found("SchedulerMetadata not found".to_string()))?;
|
||||||
|
|
||||||
let fuzz_mu = if psmeta.strat() == PowerSchedule::COE {
|
let fuzz_mu = if let Some(strat) = psmeta.strat() {
|
||||||
|
if strat == PowerSchedule::COE {
|
||||||
let corpus = state.corpus();
|
let corpus = state.corpus();
|
||||||
let mut n_paths = 0;
|
let mut n_paths = 0;
|
||||||
let mut v = 0.0;
|
let mut v = 0.0;
|
||||||
@ -91,9 +92,11 @@ where
|
|||||||
let n_fuzz_entry = if cur_index == idx {
|
let n_fuzz_entry = if cur_index == idx {
|
||||||
entry
|
entry
|
||||||
.metadata()
|
.metadata()
|
||||||
.get::<PowerScheduleTestcaseMetaData>()
|
.get::<SchedulerTestcaseMetaData>()
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
Error::key_not_found("PowerScheduleTestData not found".to_string())
|
Error::key_not_found(
|
||||||
|
"SchedulerTestcaseMetaData not found".to_string(),
|
||||||
|
)
|
||||||
})?
|
})?
|
||||||
.n_fuzz_entry()
|
.n_fuzz_entry()
|
||||||
} else {
|
} else {
|
||||||
@ -101,9 +104,11 @@ where
|
|||||||
.get(idx)?
|
.get(idx)?
|
||||||
.borrow()
|
.borrow()
|
||||||
.metadata()
|
.metadata()
|
||||||
.get::<PowerScheduleTestcaseMetaData>()
|
.get::<SchedulerTestcaseMetaData>()
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
Error::key_not_found("PowerScheduleTestData not found".to_string())
|
Error::key_not_found(
|
||||||
|
"SchedulerTestcaseMetaData not found".to_string(),
|
||||||
|
)
|
||||||
})?
|
})?
|
||||||
.n_fuzz_entry()
|
.n_fuzz_entry()
|
||||||
};
|
};
|
||||||
@ -119,6 +124,9 @@ where
|
|||||||
v
|
v
|
||||||
} else {
|
} else {
|
||||||
0.0
|
0.0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut perf_score = 100.0;
|
let mut perf_score = 100.0;
|
||||||
@ -133,9 +141,9 @@ where
|
|||||||
let favored = entry.has_metadata::<IsFavoredMetadata>();
|
let favored = entry.has_metadata::<IsFavoredMetadata>();
|
||||||
let tcmeta = entry
|
let tcmeta = entry
|
||||||
.metadata()
|
.metadata()
|
||||||
.get::<PowerScheduleTestcaseMetaData>()
|
.get::<SchedulerTestcaseMetaData>()
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
Error::key_not_found("PowerScheduleTestcaseMetaData not found".to_string())
|
Error::key_not_found("SchedulerTestcaseMetaData not found".to_string())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if q_exec_us * 0.1 > avg_exec_us {
|
if q_exec_us * 0.1 > avg_exec_us {
|
||||||
@ -191,8 +199,9 @@ where
|
|||||||
|
|
||||||
// COE and Fast schedule are fairly different from what are described in the original thesis,
|
// COE and Fast schedule are fairly different from what are described in the original thesis,
|
||||||
// This implementation follows the changes made in this pull request https://github.com/AFLplusplus/AFLplusplus/pull/568
|
// This implementation follows the changes made in this pull request https://github.com/AFLplusplus/AFLplusplus/pull/568
|
||||||
match psmeta.strat() {
|
if let Some(strat) = psmeta.strat() {
|
||||||
PowerSchedule::EXPLORE | PowerSchedule::RAND => {
|
match strat {
|
||||||
|
PowerSchedule::EXPLORE => {
|
||||||
// Nothing happens in EXPLORE
|
// Nothing happens in EXPLORE
|
||||||
}
|
}
|
||||||
PowerSchedule::EXPLOIT => {
|
PowerSchedule::EXPLOIT => {
|
||||||
@ -254,19 +263,24 @@ where
|
|||||||
/ f64::from(psmeta.n_fuzz()[tcmeta.n_fuzz_entry()] + 1);
|
/ f64::from(psmeta.n_fuzz()[tcmeta.n_fuzz_entry()] + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if psmeta.strat() != PowerSchedule::EXPLORE {
|
if let Some(strat) = psmeta.strat() {
|
||||||
|
if strat == PowerSchedule::EXPLORE {
|
||||||
if factor > MAX_FACTOR {
|
if factor > MAX_FACTOR {
|
||||||
factor = MAX_FACTOR;
|
factor = MAX_FACTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
perf_score *= factor / POWER_BETA;
|
perf_score *= factor / POWER_BETA;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Lower bound if the strat is not COE.
|
// Lower bound if the strat is not COE.
|
||||||
if psmeta.strat() == PowerSchedule::COE && perf_score < 1.0 {
|
if let Some(strat) = psmeta.strat() {
|
||||||
|
if strat == PowerSchedule::COE && perf_score < 1.0 {
|
||||||
perf_score = 1.0;
|
perf_score = 1.0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Upper bound
|
// Upper bound
|
||||||
if perf_score > HAVOC_MAX_MULT * 100.0 {
|
if perf_score > HAVOC_MAX_MULT * 100.0 {
|
||||||
@ -299,16 +313,19 @@ where
|
|||||||
let mut weight = 1.0;
|
let mut weight = 1.0;
|
||||||
let psmeta = state
|
let psmeta = state
|
||||||
.metadata()
|
.metadata()
|
||||||
.get::<PowerScheduleMetadata>()
|
.get::<SchedulerMetadata>()
|
||||||
.ok_or_else(|| Error::key_not_found("PowerScheduleMetadata not found".to_string()))?;
|
.ok_or_else(|| Error::key_not_found("SchedulerMetadata not found".to_string()))?;
|
||||||
|
|
||||||
let tcmeta = entry
|
let tcmeta = entry
|
||||||
.metadata()
|
.metadata()
|
||||||
.get::<PowerScheduleTestcaseMetaData>()
|
.get::<SchedulerTestcaseMetaData>()
|
||||||
.ok_or_else(|| Error::key_not_found("PowerScheduleTestData not found".to_string()))?;
|
.ok_or_else(|| {
|
||||||
|
Error::key_not_found("SchedulerTestcaseMetaData not found".to_string())
|
||||||
|
})?;
|
||||||
|
|
||||||
// This means that this testcase has never gone through the calibration stage before1,
|
// This means that this testcase has never gone through the calibration stage before1,
|
||||||
// In this case we'll just return the default weight
|
// In this case we'll just return the default weight
|
||||||
|
// This methoud is called in corpus's on_add() method. Fuzz_level is zero at that time.
|
||||||
if entry.fuzz_level() == 0 || psmeta.cycles() == 0 {
|
if entry.fuzz_level() == 0 || psmeta.cycles() == 0 {
|
||||||
return Ok(weight);
|
return Ok(weight);
|
||||||
}
|
}
|
||||||
@ -324,8 +341,12 @@ where
|
|||||||
|
|
||||||
let q_bitmap_size = tcmeta.bitmap_size() as f64;
|
let q_bitmap_size = tcmeta.bitmap_size() as f64;
|
||||||
|
|
||||||
match psmeta.strat() {
|
if let Some(strat) = psmeta.strat() {
|
||||||
PowerSchedule::FAST | PowerSchedule::COE | PowerSchedule::LIN | PowerSchedule::QUAD => {
|
match strat {
|
||||||
|
PowerSchedule::FAST
|
||||||
|
| PowerSchedule::COE
|
||||||
|
| PowerSchedule::LIN
|
||||||
|
| PowerSchedule::QUAD => {
|
||||||
let hits = psmeta.n_fuzz()[tcmeta.n_fuzz_entry()];
|
let hits = psmeta.n_fuzz()[tcmeta.n_fuzz_entry()];
|
||||||
if hits > 0 {
|
if hits > 0 {
|
||||||
weight *= libm::log10(f64::from(hits)) + 1.0;
|
weight *= libm::log10(f64::from(hits)) + 1.0;
|
||||||
@ -334,6 +355,7 @@ where
|
|||||||
// EXPLORE and EXPLOIT fall into this
|
// EXPLORE and EXPLOIT fall into this
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
weight *= avg_exec_us / q_exec_us;
|
weight *= avg_exec_us / q_exec_us;
|
||||||
weight *= libm::log2(q_bitmap_size) / (avg_bitmap_size as f64);
|
weight *= libm::log2(q_bitmap_size) / (avg_bitmap_size as f64);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//! The queue corpus scheduler with weighted queue item selection from aflpp (`https://github.com/AFLplusplus/AFLplusplus/blob/1d4f1e48797c064ee71441ba555b29fc3f467983/src/afl-fuzz-queue.c#L32`)
|
//! The queue corpus scheduler with weighted queue item selection from aflpp (`https://github.com/AFLplusplus/AFLplusplus/blob/1d4f1e48797c064ee71441ba555b29fc3f467983/src/afl-fuzz-queue.c#L32`)
|
||||||
//! This queue corpus scheduler needs calibration stage and the power schedule stage.
|
//! This queue corpus scheduler needs calibration stage.
|
||||||
|
|
||||||
use alloc::{
|
use alloc::{
|
||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
@ -8,10 +8,10 @@ use alloc::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::rands::Rand,
|
bolts::rands::Rand,
|
||||||
corpus::{Corpus, PowerScheduleTestcaseMetaData},
|
corpus::{Corpus, SchedulerTestcaseMetaData},
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
schedulers::{
|
schedulers::{
|
||||||
powersched::PowerScheduleMetadata,
|
powersched::SchedulerMetadata,
|
||||||
testcase_score::{CorpusWeightTestcaseScore, TestcaseScore},
|
testcase_score::{CorpusWeightTestcaseScore, TestcaseScore},
|
||||||
Scheduler,
|
Scheduler,
|
||||||
},
|
},
|
||||||
@ -215,6 +215,10 @@ where
|
|||||||
{
|
{
|
||||||
/// Add an entry to the corpus and return its index
|
/// Add an entry to the corpus and return its index
|
||||||
fn on_add(&self, state: &mut S, idx: usize) -> Result<(), Error> {
|
fn on_add(&self, state: &mut S, idx: usize) -> Result<(), Error> {
|
||||||
|
if !state.has_metadata::<SchedulerMetadata>() {
|
||||||
|
state.add_metadata(SchedulerMetadata::new(None));
|
||||||
|
}
|
||||||
|
|
||||||
if !state.has_metadata::<WeightedScheduleMetadata>() {
|
if !state.has_metadata::<WeightedScheduleMetadata>() {
|
||||||
state.add_metadata(WeightedScheduleMetadata::new());
|
state.add_metadata(WeightedScheduleMetadata::new());
|
||||||
}
|
}
|
||||||
@ -227,21 +231,23 @@ where
|
|||||||
.get(parent_idx)?
|
.get(parent_idx)?
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.metadata_mut()
|
.metadata_mut()
|
||||||
.get_mut::<PowerScheduleTestcaseMetaData>()
|
.get_mut::<SchedulerTestcaseMetaData>()
|
||||||
.ok_or_else(|| Error::key_not_found("PowerScheduleTestData not found".to_string()))?
|
.ok_or_else(|| {
|
||||||
|
Error::key_not_found("SchedulerTestcaseMetaData not found".to_string())
|
||||||
|
})?
|
||||||
.depth(),
|
.depth(),
|
||||||
None => 0,
|
None => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Attach a `PowerScheduleTestData` to the queue entry.
|
// Attach a `SchedulerTestcaseMetaData` to the queue entry.
|
||||||
depth += 1;
|
depth += 1;
|
||||||
state
|
state
|
||||||
.corpus()
|
.corpus()
|
||||||
.get(idx)?
|
.get(idx)?
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.add_metadata(PowerScheduleTestcaseMetaData::new(depth));
|
.add_metadata(SchedulerTestcaseMetaData::new(depth));
|
||||||
|
|
||||||
// Recrate the alias table
|
// Recreate the alias table
|
||||||
self.create_alias_table(state)?;
|
self.create_alias_table(state)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -281,9 +287,9 @@ where
|
|||||||
if current_cycles > corpus_counts {
|
if current_cycles > corpus_counts {
|
||||||
let psmeta = state
|
let psmeta = state
|
||||||
.metadata_mut()
|
.metadata_mut()
|
||||||
.get_mut::<PowerScheduleMetadata>()
|
.get_mut::<SchedulerMetadata>()
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
Error::key_not_found("PowerScheduleMetadata not found".to_string())
|
Error::key_not_found("SchedulerMetadata not found".to_string())
|
||||||
})?;
|
})?;
|
||||||
psmeta.set_queue_cycles(psmeta.queue_cycles() + 1);
|
psmeta.set_queue_cycles(psmeta.queue_cycles() + 1);
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,14 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
bolts::current_time,
|
bolts::current_time,
|
||||||
bolts::tuples::MatchName,
|
bolts::tuples::MatchName,
|
||||||
corpus::{Corpus, PowerScheduleTestcaseMetaData},
|
corpus::{Corpus, SchedulerTestcaseMetaData},
|
||||||
events::{EventFirer, LogSeverity},
|
events::{EventFirer, LogSeverity},
|
||||||
executors::{Executor, ExitKind, HasObservers},
|
executors::{Executor, ExitKind, HasObservers},
|
||||||
feedbacks::MapFeedbackState,
|
feedbacks::MapFeedbackState,
|
||||||
fuzzer::Evaluator,
|
fuzzer::Evaluator,
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
observers::{MapObserver, ObserversTuple},
|
observers::{MapObserver, ObserversTuple},
|
||||||
schedulers::powersched::PowerScheduleMetadata,
|
schedulers::powersched::SchedulerMetadata,
|
||||||
stages::Stage,
|
stages::Stage,
|
||||||
state::{HasClientPerfMonitor, HasCorpus, HasFeedbackStates, HasMetadata},
|
state::{HasClientPerfMonitor, HasCorpus, HasFeedbackStates, HasMetadata},
|
||||||
Error,
|
Error,
|
||||||
@ -160,13 +160,13 @@ where
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// If power schedule is used, update it
|
// If weighted scheduler or powerscheduler is used, update it
|
||||||
let use_powerschedule = state.has_metadata::<PowerScheduleMetadata>()
|
let use_powerschedule = state.has_metadata::<SchedulerMetadata>()
|
||||||
&& state
|
&& state
|
||||||
.corpus()
|
.corpus()
|
||||||
.get(corpus_idx)?
|
.get(corpus_idx)?
|
||||||
.borrow()
|
.borrow()
|
||||||
.has_metadata::<PowerScheduleTestcaseMetaData>();
|
.has_metadata::<SchedulerTestcaseMetaData>();
|
||||||
|
|
||||||
if use_powerschedule {
|
if use_powerschedule {
|
||||||
let map = executor
|
let map = executor
|
||||||
@ -176,10 +176,7 @@ where
|
|||||||
|
|
||||||
let bitmap_size = map.count_bytes();
|
let bitmap_size = map.count_bytes();
|
||||||
|
|
||||||
let psmeta = state
|
let psmeta = state.metadata_mut().get_mut::<SchedulerMetadata>().unwrap();
|
||||||
.metadata_mut()
|
|
||||||
.get_mut::<PowerScheduleMetadata>()
|
|
||||||
.unwrap();
|
|
||||||
let handicap = psmeta.queue_cycles();
|
let handicap = psmeta.queue_cycles();
|
||||||
|
|
||||||
psmeta.set_exec_time(psmeta.exec_time() + total_time);
|
psmeta.set_exec_time(psmeta.exec_time() + total_time);
|
||||||
@ -196,9 +193,9 @@ where
|
|||||||
|
|
||||||
let data = testcase
|
let data = testcase
|
||||||
.metadata_mut()
|
.metadata_mut()
|
||||||
.get_mut::<PowerScheduleTestcaseMetaData>()
|
.get_mut::<SchedulerTestcaseMetaData>()
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
Error::key_not_found("PowerScheduleTestData not found".to_string())
|
Error::key_not_found("SchedulerTestcaseMetaData not found".to_string())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
data.set_bitmap_size(bitmap_size);
|
data.set_bitmap_size(bitmap_size);
|
||||||
|
@ -4,17 +4,14 @@ use alloc::string::{String, ToString};
|
|||||||
use core::{fmt::Debug, marker::PhantomData};
|
use core::{fmt::Debug, marker::PhantomData};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::rands::Rand,
|
corpus::{Corpus, SchedulerTestcaseMetaData},
|
||||||
corpus::{Corpus, PowerScheduleTestcaseMetaData},
|
|
||||||
executors::{Executor, HasObservers},
|
executors::{Executor, HasObservers},
|
||||||
fuzzer::Evaluator,
|
fuzzer::Evaluator,
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
mutators::Mutator,
|
mutators::Mutator,
|
||||||
observers::{MapObserver, ObserversTuple},
|
observers::{MapObserver, ObserversTuple},
|
||||||
schedulers::{
|
schedulers::{
|
||||||
powersched::{PowerSchedule, PowerScheduleMetadata},
|
powersched::SchedulerMetadata, testcase_score::CorpusPowerTestcaseScore, TestcaseScore,
|
||||||
testcase_score::CorpusPowerTestcaseScore,
|
|
||||||
TestcaseScore,
|
|
||||||
},
|
},
|
||||||
stages::{MutationalStage, Stage},
|
stages::{MutationalStage, Stage},
|
||||||
state::{HasClientPerfMonitor, HasCorpus, HasMetadata, HasRand},
|
state::{HasClientPerfMonitor, HasCorpus, HasMetadata, HasRand},
|
||||||
@ -67,29 +64,8 @@ where
|
|||||||
#[allow(clippy::cast_sign_loss)]
|
#[allow(clippy::cast_sign_loss)]
|
||||||
fn iterations(&self, state: &mut S, corpus_idx: usize) -> Result<usize, Error> {
|
fn iterations(&self, state: &mut S, corpus_idx: usize) -> Result<usize, Error> {
|
||||||
// Update handicap
|
// Update handicap
|
||||||
let use_random = state
|
|
||||||
.metadata_mut()
|
|
||||||
.get_mut::<PowerScheduleMetadata>()
|
|
||||||
.ok_or_else(|| Error::key_not_found("PowerScheduleMetadata not found".to_string()))?
|
|
||||||
.strat()
|
|
||||||
== PowerSchedule::RAND;
|
|
||||||
if use_random {
|
|
||||||
return Ok(1 + state.rand_mut().below(128) as usize);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut testcase = state.corpus().get(corpus_idx)?.borrow_mut();
|
let mut testcase = state.corpus().get(corpus_idx)?.borrow_mut();
|
||||||
let score = F::compute(&mut *testcase, state)? as usize;
|
let score = F::compute(&mut *testcase, state)? as usize;
|
||||||
let tcmeta = testcase
|
|
||||||
.metadata_mut()
|
|
||||||
.get_mut::<PowerScheduleTestcaseMetaData>()
|
|
||||||
.ok_or_else(|| {
|
|
||||||
Error::key_not_found("PowerScheduleTestcaseMetaData not found".to_string())
|
|
||||||
})?;
|
|
||||||
if tcmeta.handicap() >= 4 {
|
|
||||||
tcmeta.set_handicap(tcmeta.handicap() - 4);
|
|
||||||
} else if tcmeta.handicap() > 0 {
|
|
||||||
tcmeta.set_handicap(tcmeta.handicap() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(score)
|
Ok(score)
|
||||||
}
|
}
|
||||||
@ -126,10 +102,8 @@ where
|
|||||||
|
|
||||||
let psmeta = state
|
let psmeta = state
|
||||||
.metadata_mut()
|
.metadata_mut()
|
||||||
.get_mut::<PowerScheduleMetadata>()
|
.get_mut::<SchedulerMetadata>()
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| Error::key_not_found("SchedulerMetadata not found".to_string()))?;
|
||||||
Error::key_not_found("PowerScheduleMetadata not found".to_string())
|
|
||||||
})?;
|
|
||||||
|
|
||||||
hash %= psmeta.n_fuzz().len();
|
hash %= psmeta.n_fuzz().len();
|
||||||
// Update the path frequency
|
// Update the path frequency
|
||||||
@ -141,9 +115,9 @@ where
|
|||||||
.get(idx)?
|
.get(idx)?
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.metadata_mut()
|
.metadata_mut()
|
||||||
.get_mut::<PowerScheduleTestcaseMetaData>()
|
.get_mut::<SchedulerTestcaseMetaData>()
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
Error::key_not_found("PowerScheduleTestData not found".to_string())
|
Error::key_not_found("SchedulerTestcaseMetaData not found".to_string())
|
||||||
})?
|
})?
|
||||||
.set_n_fuzz_entry(hash);
|
.set_n_fuzz_entry(hash);
|
||||||
}
|
}
|
||||||
@ -194,10 +168,7 @@ where
|
|||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
{
|
{
|
||||||
/// Creates a new [`PowerMutationalStage`]
|
/// Creates a new [`PowerMutationalStage`]
|
||||||
pub fn new(state: &mut S, mutator: M, map_observer_name: &O, strat: PowerSchedule) -> Self {
|
pub fn new(mutator: M, map_observer_name: &O) -> Self {
|
||||||
if !state.has_metadata::<PowerScheduleMetadata>() {
|
|
||||||
state.add_metadata::<PowerScheduleMetadata>(PowerScheduleMetadata::new(strat));
|
|
||||||
}
|
|
||||||
Self {
|
Self {
|
||||||
map_observer_name: map_observer_name.name().to_string(),
|
map_observer_name: map_observer_name.name().to_string(),
|
||||||
mutator,
|
mutator,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user