port to libafl 0.10.1

This commit is contained in:
Alwin Berger 2023-06-12 10:47:35 +02:00
parent 900ce0bc92
commit 53ef9ae96e
10 changed files with 124 additions and 119 deletions

View File

@ -138,7 +138,7 @@ where
unsafe { self.end_tick = emu::icount_get_raw() }; unsafe { self.end_tick = emu::icount_get_raw() };
// println!("clock post {}", self.end_tick); // println!("clock post {}", self.end_tick);
// println!("Number of Ticks: {} <- {} {}",self.end_tick - self.start_tick, self.end_tick, self.start_tick); // println!("Number of Ticks: {} <- {} {}",self.end_tick - self.start_tick, self.end_tick, self.start_tick);
let metadata =_state.metadata_mut(); let metadata =_state.metadata_map_mut();
let hist = metadata.get_mut::<IcHist>(); let hist = metadata.get_mut::<IcHist>();
let timestamp = SystemTime::now().duration_since(unsafe {FUZZ_START_TIMESTAMP}).unwrap().as_millis(); let timestamp = SystemTime::now().duration_since(unsafe {FUZZ_START_TIMESTAMP}).unwrap().as_millis();
match hist { match hist {
@ -226,9 +226,10 @@ where
/// Append to the testcase the generated metadata in case of a new corpus item /// Append to the testcase the generated metadata in case of a new corpus item
#[inline] #[inline]
fn append_metadata( fn append_metadata<OT>(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
observers: &OT,
testcase: &mut Testcase<S::Input>, testcase: &mut Testcase<S::Input>,
) -> Result<(), Error> { ) -> Result<(), Error> {
*testcase.exec_time_mut() = self.exec_time; *testcase.exec_time_mut() = self.exec_time;
@ -296,7 +297,7 @@ where
let observer = _observers.match_name::<QemuClockObserver>("clock") let observer = _observers.match_name::<QemuClockObserver>("clock")
.expect("QemuClockObserver not found"); .expect("QemuClockObserver not found");
let clock_state = state let clock_state = state
.named_metadata_mut() .named_metadata_map_mut()
.get_mut::<MaxIcountMetadata>(&self.name) .get_mut::<MaxIcountMetadata>(&self.name)
.unwrap(); .unwrap();
if observer.last_runtime() > clock_state.max_icount_seen { if observer.last_runtime() > clock_state.max_icount_seen {
@ -309,7 +310,7 @@ where
/// Append to the testcase the generated metadata in case of a new corpus item /// Append to the testcase the generated metadata in case of a new corpus item
#[inline] #[inline]
fn append_metadata(&mut self, _state: &mut S, testcase: &mut Testcase<S::Input>) -> Result<(), Error> { fn append_metadata<OT>(&mut self, _state: &mut S, observers: &OT, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
// testcase.metadata_mut().insert(QemuIcountMetadata{runtime: self.last_runtime}); // testcase.metadata_mut().insert(QemuIcountMetadata{runtime: self.last_runtime});
Ok(()) Ok(())
} }

View File

@ -1,7 +1,7 @@
//! A fuzzer using qemu in systemmode for binary-only coverage of kernels //! A fuzzer using qemu in systemmode for binary-only coverage of kernels
//! //!
use core::time::Duration; use core::time::Duration;
use std::{env, path::PathBuf, process::{self, abort}, io::{Read, Write}, fs::{self, OpenOptions}, cmp::{min, max}, mem::transmute_copy, collections::btree_map::Range}; use std::{env, path::PathBuf, process::{self, abort}, io::{Read, Write}, fs::{self, OpenOptions}, cmp::{min, max}, mem::transmute_copy, collections::btree_map::Range, ptr::addr_of_mut};
use libafl::{ use libafl::{
bolts::{ bolts::{
@ -26,10 +26,10 @@ use libafl::{
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
state::{HasCorpus, StdState, HasMetadata, HasNamedMetadata}, state::{HasCorpus, StdState, HasMetadata, HasNamedMetadata},
Error, Error,
prelude::{SimpleMonitor, SimpleEventManager, AsMutSlice, RandBytesGenerator, Generator, SimpleRestartingEventManager, HasBytesVec, minimizer::TopRatedsMetadata, havoc_mutations, StdScheduledMutator, HitcountsMapObserver}, Evaluator, stages::StdMutationalStage, prelude::{SimpleMonitor, SimpleEventManager, AsMutSlice, RandBytesGenerator, Generator, SimpleRestartingEventManager, HasBytesVec, minimizer::TopRatedsMetadata, havoc_mutations, StdScheduledMutator, HitcountsMapObserver, CorpusId}, Evaluator, stages::StdMutationalStage,
}; };
use libafl_qemu::{ use libafl_qemu::{
edges, edges::QemuEdgeCoverageHelper, elf::EasyElf, emu::Emulator, GuestPhysAddr, QemuExecutor, edges::{self, edges_map_mut_slice, MAX_EDGES_NUM}, edges::QemuEdgeCoverageHelper, elf::EasyElf, emu::Emulator, GuestPhysAddr, QemuExecutor,
QemuHooks, Regs, QemuInstrumentationFilter, GuestAddr, QemuHooks, Regs, QemuInstrumentationFilter, GuestAddr,
emu::libafl_qemu_set_native_breakpoint, emu::libafl_qemu_remove_native_breakpoint, emu::libafl_qemu_set_native_breakpoint, emu::libafl_qemu_remove_native_breakpoint,
}; };
@ -174,7 +174,7 @@ pub fn fuzz() {
// Initialize QEMU // Initialize QEMU
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
let env: Vec<(String, String)> = env::vars().collect(); let env: Vec<(String, String)> = env::vars().collect();
let emu = Emulator::new(&args, &env); let emu = Emulator::new(&args, &env).expect("Emulator creation failed");
if let Some(main_addr) = main_addr { if let Some(main_addr) = main_addr {
unsafe { unsafe {
@ -242,9 +242,11 @@ pub fn fuzz() {
}; };
// Create an observation channel using the coverage map // Create an observation channel using the coverage map
let edges = unsafe { &mut edges::EDGES_MAP }; let edges_observer = unsafe { VariableMapObserver::from_mut_slice(
let edges_counter = unsafe { &mut edges::MAX_EDGES_NUM }; "edges",
let edges_observer = VariableMapObserver::new("edges", edges, edges_counter); edges_map_mut_slice(),
addr_of_mut!(MAX_EDGES_NUM)
)};
#[cfg(feature = "observer_hitcounts")] #[cfg(feature = "observer_hitcounts")]
let edges_observer = HitcountsMapObserver::new(edges_observer); let edges_observer = HitcountsMapObserver::new(edges_observer);
@ -393,7 +395,7 @@ pub fn fuzz() {
.create(true) .create(true)
.append(true) .append(true)
.open(td).expect("Could not open timedump"); .open(td).expect("Could not open timedump");
if let Some(ichist) = state.metadata_mut().get_mut::<IcHist>() { if let Ok(ichist) = state.metadata_mut::<IcHist>() {
for i in ichist.0.drain(..) { for i in ichist.0.drain(..) {
writeln!(file, "{},{}", i.0, i.1).expect("Write to dump failed"); writeln!(file, "{},{}", i.0, i.1).expect("Write to dump failed");
} }
@ -473,7 +475,7 @@ pub fn fuzz() {
.create(true) .create(true)
.append(true) .append(true)
.open(td).expect("Could not open timedump"); .open(td).expect("Could not open timedump");
if let Some(ichist) = state.metadata_mut().get_mut::<IcHist>() { if let Some(ichist) = state.metadata_map_mut().get_mut::<IcHist>() {
for i in ichist.0.drain(..) { for i in ichist.0.drain(..) {
writeln!(file, "{},{}", i.0, i.1).expect("Write to dump failed"); writeln!(file, "{},{}", i.0, i.1).expect("Write to dump failed");
} }
@ -485,7 +487,7 @@ pub fn fuzz() {
let mut worst = Duration::new(0,0); let mut worst = Duration::new(0,0);
let mut worst_input = None; let mut worst_input = None;
for i in 0..corpus.count() { for i in 0..corpus.count() {
let tc = corpus.get(i).expect("Could not get element from corpus").borrow(); let tc = corpus.get(i.into()).expect("Could not get element from corpus").borrow();
if worst < tc.exec_time().expect("Testcase missing duration") { if worst < tc.exec_time().expect("Testcase missing duration") {
worst_input = Some(tc.input().as_ref().unwrap().bytes().to_owned()); worst_input = Some(tc.input().as_ref().unwrap().bytes().to_owned());
worst = tc.exec_time().expect("Testcase missing duration"); worst = tc.exec_time().expect("Testcase missing duration");
@ -510,8 +512,8 @@ pub fn fuzz() {
} }
{ {
let mut gd = String::from(&td); let mut gd = String::from(&td);
if let Some(md) = state.metadata_mut().get_mut::<TopRatedsMetadata>() { if let Some(md) = state.metadata_map_mut().get_mut::<TopRatedsMetadata>() {
let mut uniq: Vec<usize> = md.map.values().map(|x| x.clone()).collect(); let mut uniq: Vec<CorpusId> = md.map.values().map(|x| x.clone()).collect();
uniq.sort(); uniq.sort();
uniq.dedup(); uniq.dedup();
gd.push_str(&format!(".{}.toprated{}", uniq.len(), marker)); gd.push_str(&format!(".{}.toprated{}", uniq.len(), marker));
@ -523,13 +525,13 @@ pub fn fuzz() {
dumper(format!(".iter_{}",t)); dumper(format!(".iter_{}",t));
} }
println!("Start running until saturation"); println!("Start running until saturation");
let mut last = state.metadata().get::<IcHist>().unwrap().1; let mut last = state.metadata_map().get::<IcHist>().unwrap().1;
while SystemTime::now().duration_since(unsafe {FUZZ_START_TIMESTAMP}).unwrap().as_millis() < last.1 + Duration::from_secs(10800).as_millis() { while SystemTime::now().duration_since(unsafe {FUZZ_START_TIMESTAMP}).unwrap().as_millis() < last.1 + Duration::from_secs(10800).as_millis() {
starttime=starttime.checked_add(Duration::from_secs(30)).unwrap(); starttime=starttime.checked_add(Duration::from_secs(30)).unwrap();
fuzzer fuzzer
.fuzz_loop_until(&mut stages, &mut executor, &mut state, &mut mgr, starttime) .fuzz_loop_until(&mut stages, &mut executor, &mut state, &mut mgr, starttime)
.unwrap(); .unwrap();
let after = state.metadata().get::<IcHist>().unwrap().1; let after = state.metadata_map().get::<IcHist>().unwrap().1;
if after.0 > last.0 { if after.0 > last.0 {
last=after; last=after;
} }
@ -539,7 +541,7 @@ pub fn fuzz() {
let mut worst = Duration::new(0,0); let mut worst = Duration::new(0,0);
let mut worst_input = None; let mut worst_input = None;
for i in 0..corpus.count() { for i in 0..corpus.count() {
let tc = corpus.get(i).expect("Could not get element from corpus").borrow(); let tc = corpus.get(i.into()).expect("Could not get element from corpus").borrow();
if worst < tc.exec_time().expect("Testcase missing duration") { if worst < tc.exec_time().expect("Testcase missing duration") {
worst_input = Some(tc.input().as_ref().unwrap().bytes().to_owned()); worst_input = Some(tc.input().as_ref().unwrap().bytes().to_owned());
worst = tc.exec_time().expect("Testcase missing duration"); worst = tc.exec_time().expect("Testcase missing duration");
@ -563,8 +565,8 @@ pub fn fuzz() {
} }
{ {
let mut gd = String::from(&td); let mut gd = String::from(&td);
if let Some(md) = state.metadata_mut().get_mut::<TopRatedsMetadata>() { if let Some(md) = state.metadata_map_mut().get_mut::<TopRatedsMetadata>() {
let mut uniq: Vec<usize> = md.map.values().map(|x| x.clone()).collect(); let mut uniq: Vec<CorpusId> = md.map.values().map(|x| x.clone()).collect();
uniq.sort(); uniq.sort();
uniq.dedup(); uniq.dedup();
gd.push_str(&format!(".{}.toprated", uniq.len())); gd.push_str(&format!(".{}.toprated", uniq.len()));
@ -582,7 +584,7 @@ pub fn fuzz() {
.create(true) .create(true)
.append(true) .append(true)
.open(td).expect("Could not open timedump"); .open(td).expect("Could not open timedump");
if let Some(ichist) = state.metadata_mut().get_mut::<IcHist>() { if let Ok(ichist) = state.metadata_mut::<IcHist>() {
for i in ichist.0.drain(..) { for i in ichist.0.drain(..) {
writeln!(file, "{},{}", i.0, i.1).expect("Write to dump failed"); writeln!(file, "{},{}", i.0, i.1).expect("Write to dump failed");
} }
@ -594,7 +596,7 @@ pub fn fuzz() {
let mut worst = Duration::new(0,0); let mut worst = Duration::new(0,0);
let mut worst_input = None; let mut worst_input = None;
for i in 0..corpus.count() { for i in 0..corpus.count() {
let tc = corpus.get(i).expect("Could not get element from corpus").borrow(); let tc = corpus.get(i.into()).expect("Could not get element from corpus").borrow();
if worst < tc.exec_time().expect("Testcase missing duration") { if worst < tc.exec_time().expect("Testcase missing duration") {
worst_input = Some(tc.input().as_ref().unwrap().bytes().to_owned()); worst_input = Some(tc.input().as_ref().unwrap().bytes().to_owned());
worst = tc.exec_time().expect("Testcase missing duration"); worst = tc.exec_time().expect("Testcase missing duration");
@ -618,8 +620,8 @@ pub fn fuzz() {
} }
{ {
let mut gd = String::from(&td); let mut gd = String::from(&td);
if let Some(md) = state.metadata_mut().get_mut::<TopRatedsMetadata>() { if let Ok(md) = state.metadata_mut::<TopRatedsMetadata>() {
let mut uniq: Vec<usize> = md.map.values().map(|x| x.clone()).collect(); let mut uniq: Vec<CorpusId> = md.map.values().map(|x| x.clone()).collect();
uniq.sort(); uniq.sort();
uniq.dedup(); uniq.dedup();
gd.push_str(&format!(".{}.toprated", uniq.len())); gd.push_str(&format!(".{}.toprated", uniq.len()));
@ -639,7 +641,7 @@ pub fn fuzz() {
// Initialize QEMU // Initialize QEMU
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
let env: Vec<(String, String)> = env::vars().collect(); let env: Vec<(String, String)> = env::vars().collect();
let emu = Emulator::new(&args, &env); let emu = Emulator::new(&args, &env).expect("Emu creation failed");
if let Some(main_addr) = main_addr { if let Some(main_addr) = main_addr {
unsafe { libafl_qemu_set_native_breakpoint(main_addr); }// BREAKPOINT unsafe { libafl_qemu_set_native_breakpoint(main_addr); }// BREAKPOINT

View File

@ -12,7 +12,7 @@ use libafl::{
stages::{Stage}, stages::{Stage},
start_timer, start_timer,
state::{HasClientPerfMonitor, HasCorpus, HasRand, UsesState, HasMetadata}, state::{HasClientPerfMonitor, HasCorpus, HasRand, UsesState, HasMetadata},
Error, prelude::{HasBytesVec, UsesInput, new_hash_feedback, StdRand, RandomSeed, MutationResult, Mutator}, Error, prelude::{HasBytesVec, UsesInput, new_hash_feedback, StdRand, RandomSeed, MutationResult, Mutator, CorpusId},
}; };
use crate::{systemstate::{FreeRTOSSystemStateMetadata, RefinedFreeRTOSSystemState}, fuzzer::DO_NUM_INTERRUPT, clock::IcHist}; use crate::{systemstate::{FreeRTOSSystemStateMetadata, RefinedFreeRTOSSystemState}, fuzzer::DO_NUM_INTERRUPT, clock::IcHist};
@ -53,7 +53,7 @@ where
executor: &mut E, executor: &mut E,
state: &mut Self::State, state: &mut Self::State,
manager: &mut EM, manager: &mut EM,
corpus_idx: usize, corpus_idx: CorpusId,
) -> Result<(), Error> { ) -> Result<(), Error> {
let mut _input = state let mut _input = state
.corpus() .corpus()
@ -103,7 +103,7 @@ where
// let mut suffix : Vec<u8> = vec![]; // let mut suffix : Vec<u8> = vec![];
#[cfg(feature = "feed_systemtrace")] #[cfg(feature = "feed_systemtrace")]
{ {
let tmp = _input.metadata().get::<FreeRTOSSystemStateMetadata>(); let tmp = _input.metadata_map().get::<FreeRTOSSystemStateMetadata>();
if tmp.is_some() { if tmp.is_some() {
let trace = tmp.expect("FreeRTOSSystemStateMetadata not found"); let trace = tmp.expect("FreeRTOSSystemStateMetadata not found");

View File

@ -56,7 +56,7 @@ where
{ {
} }
fn post_exec(&mut self, emulator: &Emulator, _input: &S::Input) { fn post_exec<OT>(&mut self, emulator: &Emulator, _input: &S::Input, _observers: &mut OT, _exit_kind: &mut ExitKind) {
// unsafe { println!("snapshot post {}",emu::icount_get_raw()) }; // unsafe { println!("snapshot post {}",emu::icount_get_raw()) };
} }

View File

@ -81,13 +81,13 @@ where
let clock_observer = observers.match_name::<QemuClockObserver>("clocktime") //TODO not fixed let clock_observer = observers.match_name::<QemuClockObserver>("clocktime") //TODO not fixed
.expect("QemuClockObserver not found"); .expect("QemuClockObserver not found");
let feedbackstate = match state let feedbackstate = match state
.named_metadata_mut() .named_metadata_map_mut()
.get_mut::<SystemStateFeedbackState>("systemstate") { .get_mut::<SystemStateFeedbackState>("systemstate") {
Some(s) => s, Some(s) => s,
None => { None => {
let n=SystemStateFeedbackState::default(); let n=SystemStateFeedbackState::default();
state.named_metadata_mut().insert(n, "systemstate"); state.named_metadata_map_mut().insert(n, "systemstate");
state.named_metadata_mut().get_mut::<SystemStateFeedbackState>("systemstate").unwrap() state.named_metadata_map_mut().get_mut::<SystemStateFeedbackState>("systemstate").unwrap()
} }
}; };
// let feedbackstate = state // let feedbackstate = state
@ -123,10 +123,10 @@ where
/// Append to the testcase the generated metadata in case of a new corpus item /// Append to the testcase the generated metadata in case of a new corpus item
#[inline] #[inline]
fn append_metadata(&mut self, _state: &mut S, testcase: &mut Testcase<S::Input>) -> Result<(), Error> { fn append_metadata<OT>(&mut self, _state: &mut S, observers: &OT, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
let a = self.last_trace.take(); let a = self.last_trace.take();
match a { match a {
Some(s) => testcase.metadata_mut().insert(FreeRTOSSystemStateMetadata::new(s)), Some(s) => testcase.metadata_map_mut().insert(FreeRTOSSystemStateMetadata::new(s)),
None => (), None => (),
} }
Ok(()) Ok(())
@ -257,11 +257,11 @@ where
} }
/// Append to the testcase the generated metadata in case of a new corpus item /// Append to the testcase the generated metadata in case of a new corpus item
#[inline] #[inline]
fn append_metadata(&mut self, _state: &mut S, testcase: &mut Testcase<S::Input>) -> Result<(), Error> { fn append_metadata<OT>(&mut self, _state: &mut S, observers: &OT, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
if !self.dump_metadata {return Ok(());} if !self.dump_metadata {return Ok(());}
let a = self.last_trace.take(); let a = self.last_trace.take();
match a { match a {
Some(s) => testcase.metadata_mut().insert(FreeRTOSSystemStateMetadata::new(s)), Some(s) => testcase.metadata_map_mut().insert(FreeRTOSSystemStateMetadata::new(s)),
None => (), None => (),
} }
Ok(()) Ok(())

View File

@ -281,13 +281,13 @@ where
let observer = observers.match_name::<QemuSystemStateObserver>("systemstate") let observer = observers.match_name::<QemuSystemStateObserver>("systemstate")
.expect("QemuSystemStateObserver not found"); .expect("QemuSystemStateObserver not found");
let feedbackstate = match state let feedbackstate = match state
.named_metadata_mut() .named_metadata_map_mut()
.get_mut::<SysGraphFeedbackState>("SysMap") { .get_mut::<SysGraphFeedbackState>("SysMap") {
Some(s) => s, Some(s) => s,
None => { None => {
let n=SysGraphFeedbackState::default(); let n=SysGraphFeedbackState::default();
state.named_metadata_mut().insert(n, "SysMap"); state.named_metadata_map_mut().insert(n, "SysMap");
state.named_metadata_mut().get_mut::<SysGraphFeedbackState>("SysMap").unwrap() state.named_metadata_map_mut().get_mut::<SysGraphFeedbackState>("SysMap").unwrap()
} }
}; };
let ret = feedbackstate.update(&observer.last_run, &observer.last_input); let ret = feedbackstate.update(&observer.last_run, &observer.last_input);
@ -297,10 +297,10 @@ where
/// Append to the testcase the generated metadata in case of a new corpus item /// Append to the testcase the generated metadata in case of a new corpus item
#[inline] #[inline]
fn append_metadata(&mut self, _state: &mut S, testcase: &mut Testcase<S::Input>) -> Result<(), Error> { fn append_metadata<OT>(&mut self, _state: &mut S, observers: &OT, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
let a = self.last_trace.take(); let a = self.last_trace.take();
match a { match a {
Some(s) => testcase.metadata_mut().insert(SysGraphMetadata::new(s)), Some(s) => testcase.metadata_map_mut().insert(SysGraphMetadata::new(s)),
None => (), None => (),
} }
Ok(()) Ok(())

View File

@ -1,6 +1,7 @@
use std::cell::UnsafeCell; use std::cell::UnsafeCell;
use std::io::Write; use std::io::Write;
use std::ops::Range; use std::ops::Range;
use libafl::prelude::ExitKind;
use libafl::prelude::UsesInput; use libafl::prelude::UsesInput;
use libafl_qemu::Emulator; use libafl_qemu::Emulator;
use libafl_qemu::GuestAddr; use libafl_qemu::GuestAddr;
@ -82,7 +83,7 @@ where
} }
} }
fn post_exec(&mut self, emulator: &Emulator, _input: &S::Input) { fn post_exec<OT>(&mut self, emulator: &Emulator, _input: &S::Input, _observers: &mut OT, _exit_kind: &mut ExitKind) {
trigger_collection(emulator, self) trigger_collection(emulator, self)
} }
} }

View File

@ -12,7 +12,7 @@ use libafl::{
inputs::UsesInput, inputs::UsesInput,
schedulers::{Scheduler, TestcaseScore, minimizer::DEFAULT_SKIP_NON_FAVORED_PROB }, schedulers::{Scheduler, TestcaseScore, minimizer::DEFAULT_SKIP_NON_FAVORED_PROB },
state::{HasCorpus, HasMetadata, HasRand, UsesState, State}, state::{HasCorpus, HasMetadata, HasRand, UsesState, State},
Error, SerdeAny, prelude::HasLen, Error, SerdeAny, prelude::{HasLen, CorpusId},
}; };
@ -55,51 +55,51 @@ where
CS::State: HasCorpus + HasMetadata + HasRand, CS::State: HasCorpus + HasMetadata + HasRand,
{ {
/// 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 CS::State, idx: usize) -> Result<(), Error> { fn on_add(&mut self, state: &mut CS::State, idx: CorpusId) -> Result<(), Error> {
let l = state.corpus() let l = state.corpus()
.get(idx)? .get(idx)?
.borrow() .borrow()
.metadata() .metadata_map()
.get::<FreeRTOSSystemStateMetadata>().map_or(0, |x| x.trace_length); .get::<FreeRTOSSystemStateMetadata>().map_or(0, |x| x.trace_length);
self.get_update_trace_length(state,l); self.get_update_trace_length(state,l);
self.base.on_add(state, idx) self.base.on_add(state, idx)
} }
/// Replaces the testcase at the given idx /// Replaces the testcase at the given idx
fn on_replace( // fn on_replace(
&self, // &mut self,
state: &mut CS::State, // state: &mut CS::State,
idx: usize, // idx: CorpusId,
testcase: &Testcase<<CS::State as UsesInput>::Input>, // testcase: &Testcase<<CS::State as UsesInput>::Input>,
) -> Result<(), Error> { // ) -> Result<(), Error> {
let l = state.corpus() // let l = state.corpus()
.get(idx)? // .get(idx)?
.borrow() // .borrow()
.metadata() // .metadata()
.get::<FreeRTOSSystemStateMetadata>().map_or(0, |x| x.trace_length); // .get::<FreeRTOSSystemStateMetadata>().map_or(0, |x| x.trace_length);
self.get_update_trace_length(state, l); // self.get_update_trace_length(state, l);
self.base.on_replace(state, idx, testcase) // self.base.on_replace(state, idx, testcase)
} // }
/// Removes an entry from the corpus, returning M if M was present. /// Removes an entry from the corpus, returning M if M was present.
fn on_remove( // fn on_remove(
&self, // &self,
state: &mut CS::State, // state: &mut CS::State,
idx: usize, // idx: usize,
testcase: &Option<Testcase<<CS::State as UsesInput>::Input>>, // testcase: &Option<Testcase<<CS::State as UsesInput>::Input>>,
) -> Result<(), Error> { // ) -> Result<(), Error> {
self.base.on_remove(state, idx, testcase)?; // self.base.on_remove(state, idx, testcase)?;
Ok(()) // Ok(())
} // }
/// Gets the next entry /// Gets the next entry
fn next(&self, state: &mut CS::State) -> Result<usize, Error> { fn next(&mut self, state: &mut CS::State) -> Result<CorpusId, Error> {
let mut idx = self.base.next(state)?; let mut idx = self.base.next(state)?;
while { while {
let l = state.corpus() let l = state.corpus()
.get(idx)? .get(idx)?
.borrow() .borrow()
.metadata() .metadata_map()
.get::<FreeRTOSSystemStateMetadata>().map_or(0, |x| x.trace_length); .get::<FreeRTOSSystemStateMetadata>().map_or(0, |x| x.trace_length);
let m = self.get_update_trace_length(state,l); let m = self.get_update_trace_length(state,l);
state.rand_mut().below(m) > l as u64 state.rand_mut().below(m) > l as u64
@ -118,7 +118,7 @@ where
{ {
pub fn get_update_trace_length(&self, state: &mut CS::State, par: usize) -> u64 { pub fn get_update_trace_length(&self, state: &mut CS::State, par: usize) -> u64 {
// Create a new top rated meta if not existing // Create a new top rated meta if not existing
if let Some(td) = state.metadata_mut().get_mut::<LongestTracesMetadata>() { if let Some(td) = state.metadata_map_mut().get_mut::<LongestTracesMetadata>() {
let m = max(td.max_trace_length, par); let m = max(td.max_trace_length, par);
td.max_trace_length = m; td.max_trace_length = m;
m as u64 m as u64
@ -172,18 +172,18 @@ where
{ {
/// get first element in current gen, /// get first element in current gen,
/// if current_gen is empty, swap lists, sort by FavFactor, take top k and return first /// if current_gen is empty, swap lists, sort by FavFactor, take top k and return first
fn next(&self, state: &mut Self::State) -> Result<usize, Error> { fn next(&mut self, state: &mut Self::State) -> Result<CorpusId, Error> {
let mut to_remove : Vec<(usize, f64)> = vec![]; let mut to_remove : Vec<(usize, f64)> = vec![];
let mut to_return : usize = 0; let mut to_return : usize = 0;
let c = state.corpus().count(); let c = state.corpus().count();
let gm = state.metadata_mut().get_mut::<GeneticMetadata>().expect("Corpus Scheduler empty"); let gm = state.metadata_map_mut().get_mut::<GeneticMetadata>().expect("Corpus Scheduler empty");
// println!("index: {} curr: {:?} next: {:?} gen: {} corp: {}", gm.current_cursor, gm.current_gen.len(), gm.next_gen.len(), gm.gen, // println!("index: {} curr: {:?} next: {:?} gen: {} corp: {}", gm.current_cursor, gm.current_gen.len(), gm.next_gen.len(), gm.gen,
// c); // c);
match gm.current_gen.get(gm.current_cursor) { match gm.current_gen.get(gm.current_cursor) {
Some(c) => { Some(c) => {
gm.current_cursor+=1; gm.current_cursor+=1;
// println!("normal next: {}", (*c).0); // println!("normal next: {}", (*c).0);
return Ok((*c).0) return Ok((*c).0.into())
}, },
None => { None => {
swap(&mut to_remove, &mut gm.current_gen); swap(&mut to_remove, &mut gm.current_gen);
@ -207,53 +207,53 @@ where
to_remove.sort_by(|x,y| x.0.cmp(&(*y).0)); to_remove.sort_by(|x,y| x.0.cmp(&(*y).0));
to_remove.reverse(); to_remove.reverse();
for i in to_remove { for i in to_remove {
state.corpus_mut().remove(i.0).unwrap(); state.corpus_mut().remove(i.0.into()).unwrap();
} }
// println!("switch next: {to_return}"); // println!("switch next: {to_return}");
return Ok(to_return); return Ok(to_return.into());
} }
/// Add the new input to the next generation /// Add the new input to the next generation
fn on_add( fn on_add(
&self, &mut self,
state: &mut Self::State, state: &mut Self::State,
idx: usize idx: CorpusId
) -> Result<(), Error> { ) -> Result<(), Error> {
// println!("On Add {idx}"); // println!("On Add {idx}");
let mut tc = state.corpus_mut().get(idx).unwrap().borrow_mut().clone(); let mut tc = state.corpus_mut().get(idx).unwrap().borrow_mut().clone();
let ff = MaxTimeFavFactor::compute(&mut tc, state).unwrap(); let ff = MaxTimeFavFactor::compute(state, &mut tc).unwrap();
if let Some(gm) = state.metadata_mut().get_mut::<GeneticMetadata>() { if let Some(gm) = state.metadata_map_mut().get_mut::<GeneticMetadata>() {
gm.next_gen.push((idx,ff)); gm.next_gen.push((idx.into(),ff));
} else { } else {
state.add_metadata(GeneticMetadata::new(vec![], vec![(idx,ff)])); state.add_metadata(GeneticMetadata::new(vec![], vec![(idx.into(),ff)]));
} }
Ok(()) Ok(())
} }
fn on_replace( // fn on_replace(
&self, // &self,
_state: &mut Self::State, // _state: &mut Self::State,
_idx: usize, // _idx: usize,
_prev: &Testcase<<Self::State as UsesInput>::Input> // _prev: &Testcase<<Self::State as UsesInput>::Input>
) -> Result<(), Error> { // ) -> Result<(), Error> {
// println!("On Replace {_idx}"); // // println!("On Replace {_idx}");
Ok(()) // Ok(())
} // }
fn on_remove( // fn on_remove(
&self, // &self,
state: &mut Self::State, // state: &mut Self::State,
idx: usize, // idx: usize,
_testcase: &Option<Testcase<<Self::State as UsesInput>::Input>> // _testcase: &Option<Testcase<<Self::State as UsesInput>::Input>>
) -> Result<(), Error> { // ) -> Result<(), Error> {
// println!("On Remove {idx}"); // // println!("On Remove {idx}");
if let Some(gm) = state.metadata_mut().get_mut::<GeneticMetadata>() { // if let Some(gm) = state.metadata_mut().get_mut::<GeneticMetadata>() {
gm.next_gen = gm.next_gen.drain(..).into_iter().filter(|x| (*x).0 != idx).collect::<Vec<(usize, f64)>>(); // gm.next_gen = gm.next_gen.drain(..).into_iter().filter(|x| (*x).0 != idx).collect::<Vec<(usize, f64)>>();
gm.current_gen = gm.current_gen.drain(..).into_iter().filter(|x| (*x).0 != idx).collect::<Vec<(usize, f64)>>(); // gm.current_gen = gm.current_gen.drain(..).into_iter().filter(|x| (*x).0 != idx).collect::<Vec<(usize, f64)>>();
} else { // } else {
state.add_metadata(GeneticMetadata::new(vec![], vec![])); // state.add_metadata(GeneticMetadata::new(vec![], vec![]));
} // }
Ok(()) // Ok(())
} // }
} }
impl<S> GenerationScheduler<S> impl<S> GenerationScheduler<S>

View File

@ -54,7 +54,7 @@ where
S: HasCorpus + HasMetadata, S: HasCorpus + HasMetadata,
S::Input: HasLen, S::Input: HasLen,
{ {
fn compute(entry: &mut Testcase<<S as UsesInput>::Input>, state: &S) -> Result<f64, Error> { fn compute(state: &S, entry: &mut Testcase<<S as UsesInput>::Input>) -> Result<f64, Error> {
// TODO maybe enforce entry.exec_time().is_some() // TODO maybe enforce entry.exec_time().is_some()
let et = entry.exec_time().expect("testcase.exec_time is needed for scheduler"); let et = entry.exec_time().expect("testcase.exec_time is needed for scheduler");
let tns : i64 = et.as_nanos().try_into().expect("failed to convert time"); let tns : i64 = et.as_nanos().try_into().expect("failed to convert time");
@ -84,9 +84,9 @@ where
S: HasCorpus + HasMetadata, S: HasCorpus + HasMetadata,
S::Input: HasLen, S::Input: HasLen,
{ {
fn compute(entry: &mut Testcase<S::Input>, state: &S) -> Result<f64, Error> { fn compute( state: &S, entry: &mut Testcase<S::Input>) -> Result<f64, Error> {
let execs_per_hour = (3600.0/entry.exec_time().expect("testcase.exec_time is needed for scheduler").as_secs_f64()); let execs_per_hour = (3600.0/entry.exec_time().expect("testcase.exec_time is needed for scheduler").as_secs_f64());
let execs_times_length_per_hour = execs_per_hour*entry.cached_len()? as f64; let execs_times_length_per_hour = execs_per_hour*entry.cached_len().unwrap() as f64;
Ok(execs_times_length_per_hour) Ok(execs_times_length_per_hour)
} }
} }
@ -301,9 +301,10 @@ where
Ok(false) Ok(false)
} }
} }
fn append_metadata( fn append_metadata<OT>(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
observers: &OT,
testcase: &mut Testcase<<S as UsesInput>::Input>, testcase: &mut Testcase<<S as UsesInput>::Input>,
) -> Result<(), Error> { ) -> Result<(), Error> {
#[cfg(feature = "feed_afl")] #[cfg(feature = "feed_afl")]

View File

@ -246,21 +246,21 @@ where
state: &mut EM::State, state: &mut EM::State,
manager: &mut EM, manager: &mut EM,
time: Duration time: Duration
) -> Result<usize, Error> { ) -> Result<CorpusId, Error> {
if time==Duration::ZERO { if time==Duration::ZERO {
return Err(Error::illegal_argument( return Err(Error::illegal_argument(
"Cannot fuzz for 0 duration!".to_string(), "Cannot fuzz for 0 duration!".to_string(),
)); ));
} }
let mut ret = 0; let mut ret = None;
let mut last = current_time(); let mut last = current_time();
let monitor_timeout = STATS_TIMEOUT_DEFAULT; let monitor_timeout = STATS_TIMEOUT_DEFAULT;
let starttime = std::time::Instant::now(); let starttime = std::time::Instant::now();
while std::time::Instant::now().duration_since(starttime) < time { while std::time::Instant::now().duration_since(starttime) < time {
ret = self.fuzz_one(stages, executor, state, manager)?; ret = Some(self.fuzz_one(stages, executor, state, manager)?);
last = manager.maybe_report_progress(state, last, monitor_timeout)?; last = manager.maybe_report_progress(state, last, monitor_timeout)?;
} }
@ -269,7 +269,7 @@ where
// But as the state may grow to a few megabytes, // But as the state may grow to a few megabytes,
// for now we won' and the user has to do it (unless we find a way to do this on `Drop`). // for now we won' and the user has to do it (unless we find a way to do this on `Drop`).
Ok(ret) Ok(ret.unwrap())
} }
/// Fuzz for n iterations. /// Fuzz for n iterations.
@ -288,13 +288,13 @@ where
state: &mut EM::State, state: &mut EM::State,
manager: &mut EM, manager: &mut EM,
time: std::time::Instant time: std::time::Instant
) -> Result<usize, Error> { ) -> Result<CorpusId, Error> {
let mut ret = 0; let mut ret = None;
let mut last = current_time(); let mut last = current_time();
let monitor_timeout = STATS_TIMEOUT_DEFAULT; let monitor_timeout = STATS_TIMEOUT_DEFAULT;
while std::time::Instant::now() < time { while std::time::Instant::now() < time {
ret = self.fuzz_one(stages, executor, state, manager)?; ret = Some(self.fuzz_one(stages, executor, state, manager)?);
last = manager.maybe_report_progress(state, last, monitor_timeout)?; last = manager.maybe_report_progress(state, last, monitor_timeout)?;
} }
@ -303,7 +303,7 @@ where
// But as the state may grow to a few megabytes, // But as the state may grow to a few megabytes,
// for now we won' and the user has to do it (unless we find a way to do this on `Drop`). // for now we won' and the user has to do it (unless we find a way to do this on `Drop`).
Ok(ret) Ok(ret.unwrap())
} }
} }