add run_until_saturation

This commit is contained in:
Alwin Berger 2023-05-08 18:23:32 +02:00
parent eec998c426
commit 52cc00fedc
5 changed files with 134 additions and 15 deletions

View File

@ -23,6 +23,8 @@ gensize_1 = [ ]
gensize_10 = [ ]
gensize_100 = [ ]
observer_hitcounts = []
no_hash_state = []
run_until_saturation = []
[profile.release]
lto = true

View File

@ -34,6 +34,7 @@ use core::{fmt::Debug, time::Duration};
// use libafl::feedbacks::FeedbackState;
// use libafl::state::HasFeedbackStates;
use libafl::bolts::tuples::MatchName;
use std::time::{SystemTime, UNIX_EPOCH};
//========== Metadata
#[derive(Debug, SerdeAny, Serialize, Deserialize)]
@ -84,7 +85,7 @@ impl Default for MaxIcountMetadata {
/// A piece of metadata tracking all icounts
#[derive(Debug, SerdeAny, Serialize, Deserialize)]
pub struct IcHist (pub Vec<u64>, pub u64);
pub struct IcHist (pub Vec<(u64, u128)>, pub (u64,u128));
//========== Observer
@ -139,11 +140,14 @@ where
let hist = metadata.get_mut::<IcHist>();
match hist {
None => {
metadata.insert(IcHist(vec![self.end_tick - self.start_tick], self.end_tick-self.start_tick));
metadata.insert(IcHist(vec![(self.end_tick - self.start_tick, SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis())],
(self.end_tick - self.start_tick, SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis())));
}
Some(v) => {
v.0.push(self.end_tick - self.start_tick);
v.1 = max(v.1, self.end_tick - self.start_tick);
v.0.push((self.end_tick - self.start_tick, SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis()));
if (v.1.0 < self.end_tick-self.start_tick) {
v.1 = (self.end_tick - self.start_tick, SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis());
}
if v.0.len() >= 100 {
if let Ok(td) = env::var("TIME_DUMP") {
let mut file = OpenOptions::new()
@ -152,9 +156,9 @@ where
.create(true)
.append(true)
.open(td).expect("Could not open timedump");
let newv : Vec<u64> = Vec::with_capacity(100);
let newv : Vec<(u64, u128)> = Vec::with_capacity(100);
for i in std::mem::replace(&mut v.0, newv).into_iter() {
writeln!(file, "{}", i).expect("Write to dump failed");
writeln!(file, "{},{}", i.0, i.1).expect("Write to dump failed");
}
} else {
// If we don't write out values we don't need to remember them at all

View File

@ -42,6 +42,7 @@ use crate::{
// systemstate::mutation::scheduled::{havoc_mutations, StdScheduledMutator},
// mutational::StdMutationalStage
};
use std::time::{SystemTime, UNIX_EPOCH};
pub static mut RNG_SEED: u64 = 1;
@ -390,9 +391,9 @@ pub fn fuzz() {
.create(true)
.append(true)
.open(td).expect("Could not open timedump");
if let Some(ichist) = state.metadata().get::<IcHist>() {
for i in ichist.0.iter() {
writeln!(file, "{}", i).expect("Write to dump failed");
if let Some(ichist) = state.metadata_mut().get_mut::<IcHist>() {
for i in ichist.0.drain(..) {
writeln!(file, "{},{}", i.0, i.1).expect("Write to dump failed");
}
}
}
@ -452,6 +453,117 @@ pub fn fuzz() {
fuzzer
.fuzz_loop_until(&mut stages, &mut executor, &mut state, &mut mgr, starttime.checked_add(Duration::from_secs(num)).unwrap())
.unwrap();
#[cfg(feature = "run_until_saturation")]
{
{
let mut dumper = |marker : String| {
if let Ok(td) = env::var("TIME_DUMP") {
let mut file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.append(true)
.open(td).expect("Could not open timedump");
if let Some(ichist) = state.metadata_mut().get_mut::<IcHist>() {
for i in ichist.0.drain(..) {
writeln!(file, "{},{}", i.0, i.1).expect("Write to dump failed");
}
}
}
if let Ok(td) = env::var("CASE_DUMP") {
println!("Dumping worst case to {:?}", td);
let corpus = state.corpus();
let mut worst = Duration::new(0,0);
let mut worst_input = None;
for i in 0..corpus.count() {
let tc = corpus.get(i).expect("Could not get element from corpus").borrow();
if worst < tc.exec_time().expect("Testcase missing duration") {
worst_input = Some(tc.input().as_ref().unwrap().bytes().to_owned());
worst = tc.exec_time().expect("Testcase missing duration");
}
}
match worst_input {
Some(wi) => {
// let cd = format!("{}.case",&td);
let mut cd = td.clone();
cd.push_str(&marker);
fs::write(&cd,wi).expect("Failed to write worst corpus element");
},
None => (),
}
#[cfg(feature = "feed_systemgraph")]
{
let mut gd = String::from(&td);
gd.push_str(&format!(".graph{}", marker));
if let Some(md) = state.named_metadata_mut().get_mut::<SysGraphFeedbackState>("SysMap") {
fs::write(&gd,ron::to_string(&md).expect("Failed to serialize graph")).expect("Failed to write graph");
}
}
{
let mut gd = String::from(&td);
if let Some(md) = state.metadata_mut().get_mut::<TopRatedsMetadata>() {
let mut uniq: Vec<usize> = md.map.values().map(|x| x.clone()).collect();
uniq.sort();
uniq.dedup();
gd.push_str(&format!(".{}.toprated{}", uniq.len(), marker));
fs::write(&gd,ron::to_string(&md.map).expect("Failed to serialize metadata")).expect("Failed to write graph");
}
}
}
};
dumper(format!(".iter_{}",t));
}
println!("Start running until saturation");
let mut last = state.metadata().get::<IcHist>().unwrap().1;
while SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() < last.1 + Duration::from_secs(10800).as_millis() {
fuzzer
.fuzz_loop_until(&mut stages, &mut executor, &mut state, &mut mgr, starttime.checked_add(Duration::from_secs(5)).unwrap())
.unwrap();
let after = state.metadata().get::<IcHist>().unwrap().1;
if after.0 > last.0 {
last=after;
}
if let Ok(td) = env::var("CASE_DUMP") {
println!("Dumping worst case to {:?}", td);
let corpus = state.corpus();
let mut worst = Duration::new(0,0);
let mut worst_input = None;
for i in 0..corpus.count() {
let tc = corpus.get(i).expect("Could not get element from corpus").borrow();
if worst < tc.exec_time().expect("Testcase missing duration") {
worst_input = Some(tc.input().as_ref().unwrap().bytes().to_owned());
worst = tc.exec_time().expect("Testcase missing duration");
}
}
match worst_input {
Some(wi) => {
// let cd = format!("{}.case",&td);
let cd = td.clone();
fs::write(&cd,wi).expect("Failed to write worst corpus element");
},
None => (),
}
#[cfg(feature = "feed_systemgraph")]
{
let mut gd = String::from(&td);
gd.push_str(".graph" );
if let Some(md) = state.named_metadata_mut().get_mut::<SysGraphFeedbackState>("SysMap") {
fs::write(&gd,ron::to_string(&md).expect("Failed to serialize graph")).expect("Failed to write graph");
}
}
{
let mut gd = String::from(&td);
if let Some(md) = state.metadata_mut().get_mut::<TopRatedsMetadata>() {
let mut uniq: Vec<usize> = md.map.values().map(|x| x.clone()).collect();
uniq.sort();
uniq.dedup();
gd.push_str(&format!(".{}.toprated", uniq.len()));
fs::write(&gd,ron::to_string(&md.map).expect("Failed to serialize metadata")).expect("Failed to write graph");
}
}
}
}
}
}
if let Ok(td) = env::var("TIME_DUMP") {
let mut file = OpenOptions::new()
@ -460,9 +572,9 @@ pub fn fuzz() {
.create(true)
.append(true)
.open(td).expect("Could not open timedump");
if let Some(ichist) = state.metadata().get::<IcHist>() {
for i in ichist.0.iter() {
writeln!(file, "{}", i).expect("Write to dump failed");
if let Some(ichist) = state.metadata_mut().get_mut::<IcHist>() {
for i in ichist.0.drain(..) {
writeln!(file, "{},{}", i.0, i.1).expect("Write to dump failed");
}
}
}

View File

@ -2,7 +2,7 @@
//! For the current input, it will perform a range of random mutations, and then run them in the executor.
use core::marker::PhantomData;
use std::cmp::max;
use std::cmp::{max, min};
use libafl::{
bolts::rands::Rand,
@ -355,11 +355,11 @@ where
{
let metadata = state.metadata();
let hist = metadata.get::<IcHist>().unwrap();
let maxtick : u64 = hist.1;
let maxtick : u64 = hist.1.0;
// let maxtick : u64 = (_input.exec_time().expect("No duration found").as_nanos() >> 4).try_into().unwrap();
let mut numbers : Vec<u32> = vec![];
for i in 0..num_interrupts {
prefix.push(u32::to_le_bytes(myrand.between(0, maxtick).try_into().unwrap()));
prefix.push(u32::to_le_bytes(myrand.between(0, min(maxtick, u32::MAX as u64)).try_into().expect("ticks > u32")));
}
}

View File

@ -57,6 +57,7 @@ impl Hash for RefinedTCB {
self.task_name.hash(state);
self.priority.hash(state);
self.mutexes_held.hash(state);
#[cfg(not(feature = "no_hash_state"))]
self.notify_state.hash(state);
// self.notify_value.hash(state);
}