use moving average success rate for interrupt mutation frequency

This commit is contained in:
Alwin Berger 2024-10-18 11:09:44 +02:00
parent 3a126cb0a8
commit bf827c077f

View File

@ -17,6 +17,8 @@ use crate::{time::clock::{IcHist, QEMU_ISNS_PER_USEC}, fuzzer::{DO_NUM_INTERRUPT
use libafl::state::HasCurrentTestcase; use libafl::state::HasCurrentTestcase;
use std::borrow::Cow; use std::borrow::Cow;
use simple_moving_average::SMA;
use super::stg::{STGEdge, STGNode}; use super::stg::{STGEdge, STGNode};
// pub static mut MINIMUM_INTER_ARRIVAL_TIME : u32 = 1000 /*us*/ * QEMU_ISNS_PER_USEC; // pub static mut MINIMUM_INTER_ARRIVAL_TIME : u32 = 1000 /*us*/ * QEMU_ISNS_PER_USEC;
@ -109,11 +111,12 @@ pub fn try_force_new_branches(interrupt_ticks : &[u32], fbs: &STGFeedbackState,
} }
/// The default mutational stage /// The default mutational stage
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug)]
pub struct InterruptShiftStage<E, EM, Z> { pub struct InterruptShiftStage<E, EM, Z> {
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
phantom: PhantomData<(E, EM, Z)>, phantom: PhantomData<(E, EM, Z)>,
interrup_config: Vec<(usize,u32)> interrup_config: Vec<(usize,u32)>,
success: simple_moving_average::SingleSumSMA<f32, f32, 100>
} }
impl<E, EM, Z> InterruptShiftStage<E, EM, Z> impl<E, EM, Z> InterruptShiftStage<E, EM, Z>
@ -124,7 +127,7 @@ where
Z::State: MaybeHasClientPerfMonitor + HasCorpus + HasRand, Z::State: MaybeHasClientPerfMonitor + HasCorpus + HasRand,
{ {
pub fn new(config : &Vec<(usize,u32)>) -> Self { pub fn new(config : &Vec<(usize,u32)>) -> Self {
Self { phantom: PhantomData, interrup_config: config.clone() } Self { phantom: PhantomData, interrup_config: config.clone(), success: simple_moving_average::SingleSumSMA::from_zero(1.0) }
} }
} }
@ -185,8 +188,9 @@ where
let mut rerun_count = 0; // count how many times we rerun the executor let mut rerun_count = 0; // count how many times we rerun the executor
let mut interesting_rerun_count = 0; // count how many reruns were interesting
// Try many times to find a mutation that is not already in the corpus // Try many times to find a mutation that is not already in the corpus
let loopbound = 5; let loopbound = max(1, (self.success.get_average()*100.0) as usize);
for _ in 0..loopbound { for _ in 0..loopbound {
// Choose which isr to mutate // Choose which isr to mutate
let interrup_config = match myrand.choose(&self.interrup_config) { let interrup_config = match myrand.choose(&self.interrup_config) {
@ -413,12 +417,14 @@ where
if do_rerun { if do_rerun {
rerun_count+=1; rerun_count+=1;
let (_, corpus_idx) = fuzzer.evaluate_input(state, executor, manager, new_input)?; let (_, corpus_idx) = fuzzer.evaluate_input(state, executor, manager, new_input)?;
if corpus_idx.is_some() { unsafe{sum_interesting_reruns+=1;}} else if corpus_idx.is_some() { unsafe{interesting_rerun_count+=1;}} else
if corpus_idx.is_none() && loopbound<=0 { break;} if corpus_idx.is_none() && loopbound<=0 { break;}
} else {if loopbound<=0 {break;}} } else {if loopbound<=0 {break;}}
} }
unsafe { unsafe {
sum_reruns+=rerun_count; sum_reruns+=rerun_count;
sum_interesting_reruns+=interesting_rerun_count;
if rerun_count>0 {self.success.add_sample(interesting_rerun_count as f32 / rerun_count as f32);}
} }
self.report_stats(state, manager); self.report_stats(state, manager);
Ok(()) Ok(())