From 82908badfd5c62b67ea52acc2afb23853e339c7b Mon Sep 17 00:00:00 2001 From: Alwin Berger Date: Mon, 18 Sep 2023 13:43:31 +0200 Subject: [PATCH] add simple iteration counter --- fuzzers/FRET/Cargo.toml | 2 +- fuzzers/FRET/src/systemstate/feedbacks.rs | 8 +-- fuzzers/FRET/src/systemstate/graph.rs | 10 ++-- fuzzers/FRET/src/systemstate/mod.rs | 6 +-- fuzzers/FRET/src/systemstate/observers.rs | 65 +++++++++++++++-------- 5 files changed, 55 insertions(+), 36 deletions(-) diff --git a/fuzzers/FRET/Cargo.toml b/fuzzers/FRET/Cargo.toml index 3f984b1fc9..28f1bfc1f3 100644 --- a/fuzzers/FRET/Cargo.toml +++ b/fuzzers/FRET/Cargo.toml @@ -36,7 +36,7 @@ libafl = { path = "../../libafl/" } libafl_bolts = { path = "../../libafl_bolts/" } libafl_qemu = { path = "../../libafl_qemu/", features = ["arm", "systemmode"] } serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib -hashbrown = { version = "0.12", features = ["serde", "ahash-compile-time-rng"] } # A faster hashmap, nostd compatible +hashbrown = { version = "0.14.0", features = ["serde"] } # A faster hashmap, nostd compatible petgraph = { version="0.6.0", features = ["serde-1"] } ron = "0.7" # write serialized data - including hashmaps rand = "0.5" diff --git a/fuzzers/FRET/src/systemstate/feedbacks.rs b/fuzzers/FRET/src/systemstate/feedbacks.rs index 6f32ae7755..03214f1f7d 100644 --- a/fuzzers/FRET/src/systemstate/feedbacks.rs +++ b/fuzzers/FRET/src/systemstate/feedbacks.rs @@ -154,7 +154,7 @@ pub fn match_traces(target: &Vec, last: &Vec last.len() {return false;} for i in 0..target.len() { - ret &= target[i].current_task.task_name==last[i].current_task.task_name; + ret &= target[i].current_task.0.task_name==last[i].current_task.0.task_name; } ret } @@ -162,7 +162,7 @@ pub fn match_traces_name(target: &Vec, last: &Vec last.len() {return false;} for i in 0..target.len() { - ret &= target[i]==last[i].current_task.task_name; + ret &= target[i]==last[i].current_task.0.task_name; } ret } @@ -213,7 +213,7 @@ impl Named for HitSystemStateFeedback impl HitSystemStateFeedback { pub fn new(target: Option>) -> Self { - Self {target: target.map(|x| x.into_iter().map(|y| y.current_task.task_name).collect())} + Self {target: target.map(|x| x.into_iter().map(|y| y.current_task.0.task_name).collect())} } } //=========================== Debugging Feedback @@ -244,7 +244,7 @@ where { let observer = observers.match_name::("systemstate") .expect("QemuSystemStateObserver not found"); - let names : Vec = observer.last_run.iter().map(|x| x.current_task.task_name.clone()).collect(); + let names : Vec = observer.last_run.iter().map(|x| x.current_task.0.task_name.clone()).collect(); match &self.dumpfile { Some(s) => { std::fs::write(s,ron::to_string(&observer.last_run).expect("Error serializing hashmap")).expect("Can not dump to file"); diff --git a/fuzzers/FRET/src/systemstate/graph.rs b/fuzzers/FRET/src/systemstate/graph.rs index ca24d2ed48..5e72d7b2cd 100644 --- a/fuzzers/FRET/src/systemstate/graph.rs +++ b/fuzzers/FRET/src/systemstate/graph.rs @@ -105,7 +105,7 @@ impl SysGraphNode { return interesting; } pub fn get_taskname(&self) -> &str { - &self.base.current_task.task_name + &self.base.current_task.0.task_name } pub fn get_input_counts(&self) -> Vec { self.variants.iter().map(|x| x.input_counter).collect() @@ -169,9 +169,9 @@ impl SysGraphFeedbackState pub fn new() -> Self { let mut graph = DiGraph::::new(); let mut entry = SysGraphNode::default(); - entry.base.current_task.task_name="Start".to_string(); + entry.base.current_task.0.task_name="Start".to_string(); let mut exit = SysGraphNode::default(); - exit.base.current_task.task_name="End".to_string(); + exit.base.current_task.0.task_name="End".to_string(); let entry = graph.add_node(entry); let exit = graph.add_node(exit); Self {graph: graph, entrypoint: entry, exit: exit, name: String::from("SysMap")} @@ -238,9 +238,9 @@ impl SysGraphFeedbackState fn reset(&mut self) -> Result<(), Error> { self.graph.clear(); let mut entry = SysGraphNode::default(); - entry.base.current_task.task_name="Start".to_string(); + entry.base.current_task.0.task_name="Start".to_string(); let mut exit = SysGraphNode::default(); - exit.base.current_task.task_name="End".to_string(); + exit.base.current_task.0.task_name="End".to_string(); self.entrypoint = self.graph.add_node(entry); self.exit = self.graph.add_node(exit); Ok(()) diff --git a/fuzzers/FRET/src/systemstate/mod.rs b/fuzzers/FRET/src/systemstate/mod.rs index 7656334d85..d3f187a29c 100644 --- a/fuzzers/FRET/src/systemstate/mod.rs +++ b/fuzzers/FRET/src/systemstate/mod.rs @@ -100,9 +100,9 @@ pub struct RefinedFreeRTOSSystemState { pub end_tick: u64, last_pc: Option, input_counter: u32, - pub current_task: RefinedTCB, - ready_list_after: Vec, - delay_list_after: Vec, + pub current_task: (RefinedTCB, u32), + ready_list_after: Vec<(RefinedTCB, u32)>, + delay_list_after: Vec<(RefinedTCB, u32)>, } impl PartialEq for RefinedFreeRTOSSystemState { fn eq(&self, other: &Self) -> bool { diff --git a/fuzzers/FRET/src/systemstate/observers.rs b/fuzzers/FRET/src/systemstate/observers.rs index 12a4664616..97bc806164 100644 --- a/fuzzers/FRET/src/systemstate/observers.rs +++ b/fuzzers/FRET/src/systemstate/observers.rs @@ -6,8 +6,8 @@ use libafl_bolts::Named; use libafl_bolts::AsSlice; use libafl::Error; use libafl::observers::Observer; -use hashbrown::HashMap; use serde::{Deserialize, Serialize}; +use hashbrown::HashMap; use super::{ CURRENT_SYSTEMSTATE_VEC, @@ -112,27 +112,46 @@ fn tcb_list_to_vec_cached(list: List_t, dump: &mut HashMap) -> } /// Drains a List of raw SystemStates to produce a refined trace fn refine_system_states(input: &mut Vec) -> Vec { -let mut ret = Vec::::new(); -let mut start_tick : u64 = 0; -for mut i in input.drain(..) { - let mut collector = Vec::::new(); - for j in i.prio_ready_lists.into_iter().rev() { - let mut tmp = tcb_list_to_vec_cached(j,&mut i.dumping_ground).iter().map(|x| RefinedTCB::from_tcb(x)).collect(); - collector.append(&mut tmp); + let mut iteration_counts : HashMap= HashMap::new(); + let mut ret = Vec::::new(); + let mut start_tick : u64 = 0; + for mut i in input.drain(..) { + let cur = RefinedTCB::from_tcb_owned(i.current_tcb); + // collect ready list + let mut collector = Vec::::new(); + for j in i.prio_ready_lists.into_iter().rev() { + let mut tmp = tcb_list_to_vec_cached(j,&mut i.dumping_ground).iter().map(|x| RefinedTCB::from_tcb(x)).collect(); + collector.append(&mut tmp); + } + // collect delay list + let mut delay_list : Vec:: = tcb_list_to_vec_cached(i.delay_list, &mut i.dumping_ground).iter().map(|x| RefinedTCB::from_tcb(x)).collect(); + delay_list.sort_by(|a,b| a.task_name.cmp(&b.task_name)); + + // keep counts for all tasks + let _ = iteration_counts.try_insert(cur.task_name.clone(), 1); + for j in collector.iter() {let _ = iteration_counts.try_insert(j.task_name.clone(), 1);} + for j in delay_list.iter() {let _ = iteration_counts.try_insert(j.task_name.clone(), 0);} + + // increase when: + // current and delayed afterwards + if let Some(_) = delay_list.iter().find(|x| (*x).task_name==cur.task_name) { + *iteration_counts.get_mut(&cur.task_name).unwrap()+=1; + } + + let collector = collector.into_iter().map(|x| {let t = *iteration_counts.get(&x.task_name).unwrap_or(&1); (x, t)}).collect(); + let delay_list : Vec<(RefinedTCB, u32)> = delay_list.into_iter().map(|x| {let t = *iteration_counts.get(&x.task_name).unwrap_or(&0); (x, t)}).collect(); + let t = *iteration_counts.get(&cur.task_name).unwrap_or(&1); + // We don't care about the order + ret.push(RefinedFreeRTOSSystemState { + current_task: (cur, t), + start_tick: start_tick, + end_tick: i.qemu_tick, + ready_list_after: collector, + delay_list_after: delay_list, + input_counter: i.input_counter,//+IRQ_INPUT_BYTES_NUMBER, + last_pc: i.last_pc, + }); + start_tick=i.qemu_tick; } - let mut delay_list : Vec:: = tcb_list_to_vec_cached(i.delay_list, &mut i.dumping_ground).iter().map(|x| RefinedTCB::from_tcb(x)).collect(); - // We don't care about the order - delay_list.sort_by(|a,b| a.task_name.cmp(&b.task_name)); - ret.push(RefinedFreeRTOSSystemState { - current_task: RefinedTCB::from_tcb_owned(i.current_tcb), - start_tick: start_tick, - end_tick: i.qemu_tick, - ready_list_after: collector, - delay_list_after: delay_list, - input_counter: i.input_counter,//+IRQ_INPUT_BYTES_NUMBER, - last_pc: i.last_pc, - }); - start_tick=i.qemu_tick; -} -return ret; + return ret; } \ No newline at end of file