add a new scheduler for systemtraces
This commit is contained in:
parent
5db99e4e68
commit
6a8e9c80c1
@ -39,7 +39,7 @@ use rand::{SeedableRng, StdRng, Rng};
|
||||
use crate::{
|
||||
clock::{QemuClockObserver, ClockTimeFeedback, QemuClockIncreaseFeedback, IcHist},
|
||||
qemustate::QemuStateRestoreHelper,
|
||||
systemstate::{helpers::QemuSystemStateHelper, observers::QemuSystemStateObserver, feedbacks::{DumpSystraceFeedback, NovelSystemStateFeedback}, graph::{SysMapFeedback, SysGraphFeedbackState, GraphMaximizerCorpusScheduler}}, worst::{TimeMaximizerCorpusScheduler, ExecTimeIncFeedback, TimeStateMaximizerCorpusScheduler},
|
||||
systemstate::{helpers::QemuSystemStateHelper, observers::QemuSystemStateObserver, feedbacks::{DumpSystraceFeedback, NovelSystemStateFeedback}, graph::{SysMapFeedback, SysGraphFeedbackState, GraphMaximizerCorpusScheduler}, schedulers::LongestTraceScheduler}, worst::{TimeMaximizerCorpusScheduler, ExecTimeIncFeedback, TimeStateMaximizerCorpusScheduler},
|
||||
};
|
||||
pub static mut RNG_SEED: u64 = 1;
|
||||
|
||||
@ -302,7 +302,7 @@ pub fn fuzz() {
|
||||
#[cfg(all(feature = "feed_afl",not(any(feature = "feed_systemgraph",feature = "feed_systemtrace"))))]
|
||||
let scheduler = TimeMaximizerCorpusScheduler::new(QueueScheduler::new());
|
||||
#[cfg(feature = "feed_systemtrace")]
|
||||
let scheduler = TimeStateMaximizerCorpusScheduler::new(QueueScheduler::new());
|
||||
let scheduler = LongestTraceScheduler::new(TimeStateMaximizerCorpusScheduler::new(QueueScheduler::new()));
|
||||
#[cfg(feature = "feed_systemgraph")]
|
||||
let scheduler = GraphMaximizerCorpusScheduler::new(QueueScheduler::new());
|
||||
|
||||
|
@ -14,6 +14,7 @@ pub mod helpers;
|
||||
pub mod observers;
|
||||
pub mod feedbacks;
|
||||
pub mod graph;
|
||||
pub mod schedulers;
|
||||
// pub mod mutators;
|
||||
|
||||
#[cfg(feature = "fuzz_interrupt")]
|
||||
@ -125,13 +126,14 @@ impl RefinedFreeRTOSSystemState {
|
||||
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
||||
pub struct FreeRTOSSystemStateMetadata {
|
||||
inner: Vec<RefinedFreeRTOSSystemState>,
|
||||
trace_length: usize,
|
||||
indices: Vec<usize>, // Hashed enumeration of States
|
||||
tcref: isize,
|
||||
}
|
||||
impl FreeRTOSSystemStateMetadata {
|
||||
pub fn new(inner: Vec<RefinedFreeRTOSSystemState>) -> Self{
|
||||
let tmp = inner.iter().enumerate().map(|x| compute_hash(x) as usize).collect();
|
||||
Self {inner: inner, indices: tmp, tcref: 0}
|
||||
Self {trace_length: inner.len(), inner: inner, indices: tmp, tcref: 0}
|
||||
}
|
||||
}
|
||||
pub fn compute_hash<T>(obj: T) -> u64
|
||||
|
134
fuzzers/FRET/src/systemstate/schedulers.rs
Normal file
134
fuzzers/FRET/src/systemstate/schedulers.rs
Normal file
@ -0,0 +1,134 @@
|
||||
//! The Minimizer schedulers are a family of corpus schedulers that feed the fuzzer
|
||||
//! with testcases only from a subset of the total corpus.
|
||||
|
||||
use core::{marker::PhantomData};
|
||||
use std::cmp::max;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use libafl::{
|
||||
bolts::{rands::Rand, serdeany::SerdeAny, AsSlice, HasRefCnt},
|
||||
corpus::{Corpus, Testcase},
|
||||
inputs::UsesInput,
|
||||
schedulers::{Scheduler, TestcaseScore, minimizer::DEFAULT_SKIP_NON_FAVORED_PROB },
|
||||
state::{HasCorpus, HasMetadata, HasRand, UsesState},
|
||||
Error, SerdeAny,
|
||||
|
||||
};
|
||||
|
||||
use super::FreeRTOSSystemStateMetadata;
|
||||
|
||||
/// A state metadata holding a map of favoreds testcases for each map entry
|
||||
#[derive(Debug, Serialize, Deserialize, SerdeAny, Default)]
|
||||
pub struct LongestTracesMetadata {
|
||||
/// map index -> corpus index
|
||||
pub max_trace_length: usize,
|
||||
}
|
||||
|
||||
impl LongestTracesMetadata {
|
||||
fn new(l : usize) -> Self {
|
||||
Self {max_trace_length: l}
|
||||
}
|
||||
}
|
||||
|
||||
/// The [`MinimizerScheduler`] employs a genetic algorithm to compute a subset of the
|
||||
/// corpus that exercise all the requested features (e.g. all the coverage seen so far)
|
||||
/// prioritizing [`Testcase`]`s` using [`TestcaseScore`]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LongestTraceScheduler<CS> {
|
||||
base: CS,
|
||||
skip_non_favored_prob: u64,
|
||||
}
|
||||
|
||||
impl<CS> UsesState for LongestTraceScheduler<CS>
|
||||
where
|
||||
CS: UsesState,
|
||||
{
|
||||
type State = CS::State;
|
||||
}
|
||||
|
||||
impl<CS> Scheduler for LongestTraceScheduler<CS>
|
||||
where
|
||||
CS: Scheduler,
|
||||
CS::State: HasCorpus + HasMetadata + HasRand,
|
||||
{
|
||||
/// Add an entry to the corpus and return its index
|
||||
fn on_add(&self, state: &mut CS::State, idx: usize) -> Result<(), Error> {
|
||||
let l = state.corpus()
|
||||
.get(idx)?
|
||||
.borrow()
|
||||
.metadata()
|
||||
.get::<FreeRTOSSystemStateMetadata>().map_or(0, |x| x.trace_length);
|
||||
self.get_update_trace_length(state,l);
|
||||
self.base.on_add(state, idx)
|
||||
}
|
||||
|
||||
/// Replaces the testcase at the given idx
|
||||
fn on_replace(
|
||||
&self,
|
||||
state: &mut CS::State,
|
||||
idx: usize,
|
||||
testcase: &Testcase<<CS::State as UsesInput>::Input>,
|
||||
) -> Result<(), Error> {
|
||||
let l = state.corpus()
|
||||
.get(idx)?
|
||||
.borrow()
|
||||
.metadata()
|
||||
.get::<FreeRTOSSystemStateMetadata>().map_or(0, |x| x.trace_length);
|
||||
self.get_update_trace_length(state, l);
|
||||
self.base.on_replace(state, idx, testcase)
|
||||
}
|
||||
|
||||
/// Removes an entry from the corpus, returning M if M was present.
|
||||
fn on_remove(
|
||||
&self,
|
||||
state: &mut CS::State,
|
||||
idx: usize,
|
||||
testcase: &Option<Testcase<<CS::State as UsesInput>::Input>>,
|
||||
) -> Result<(), Error> {
|
||||
self.base.on_remove(state, idx, testcase)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Gets the next entry
|
||||
fn next(&self, state: &mut CS::State) -> Result<usize, Error> {
|
||||
let mut idx = self.base.next(state)?;
|
||||
while {
|
||||
let l = state.corpus()
|
||||
.get(idx)?
|
||||
.borrow()
|
||||
.metadata()
|
||||
.get::<FreeRTOSSystemStateMetadata>().map_or(0, |x| x.trace_length);
|
||||
let m = self.get_update_trace_length(state,l);
|
||||
state.rand_mut().below(m) > l as u64
|
||||
} && state.rand_mut().below(100) < self.skip_non_favored_prob
|
||||
{
|
||||
idx = self.base.next(state)?;
|
||||
}
|
||||
Ok(idx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<CS> LongestTraceScheduler<CS>
|
||||
where
|
||||
CS: Scheduler,
|
||||
CS::State: HasCorpus + HasMetadata + HasRand,
|
||||
{
|
||||
pub fn get_update_trace_length(&self, state: &mut CS::State, par: usize) -> u64 {
|
||||
// Create a new top rated meta if not existing
|
||||
if let Some(td) = state.metadata_mut().get_mut::<LongestTracesMetadata>() {
|
||||
let m = max(td.max_trace_length, par);
|
||||
td.max_trace_length = m;
|
||||
m as u64
|
||||
} else {
|
||||
state.add_metadata(LongestTracesMetadata::new(par));
|
||||
par as u64
|
||||
}
|
||||
}
|
||||
pub fn new(base: CS) -> Self {
|
||||
Self {
|
||||
base,
|
||||
skip_non_favored_prob: DEFAULT_SKIP_NON_FAVORED_PROB,
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user