From 1d0c43081a1eddcfa8ee7ca9f12927b6f1c2486b Mon Sep 17 00:00:00 2001 From: Alwin Berger Date: Thu, 17 Mar 2022 22:37:14 +0100 Subject: [PATCH] add graph nodes --- .../wcet_qemu_sys/src/sysstate/feedbacks.rs | 64 +++++++++++++++---- .../wcet_qemu_sys/src/sysstate/observers.rs | 7 +- 2 files changed, 57 insertions(+), 14 deletions(-) diff --git a/fuzzers/wcet_qemu_sys/src/sysstate/feedbacks.rs b/fuzzers/wcet_qemu_sys/src/sysstate/feedbacks.rs index 2bf7c143e8..7561919628 100644 --- a/fuzzers/wcet_qemu_sys/src/sysstate/feedbacks.rs +++ b/fuzzers/wcet_qemu_sys/src/sysstate/feedbacks.rs @@ -1,3 +1,5 @@ +use libafl::bolts::ownedref::OwnedSlice; +use libafl::inputs::BytesInput; use std::path::PathBuf; use libafl_qemu::QemuClockObserver; use libafl::feedbacks::FeedbackState; @@ -25,48 +27,84 @@ use petgraph::Direction; use std::cmp::Ordering; //============================= Graph Feedback +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] +struct VariantTuple +{ + start_tick: u64, + end_tick: u64, + input_counter: u32, + input: Vec, // in the end any kind of input are bytes, regardless of type and lifetime +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +struct SysGraphNode +{ + base: MiniFreeRTOSSystemState, + variants: Vec, +} +impl SysGraphNode { + fn from(base: MiniFreeRTOSSystemState, input: Vec) -> Self { + SysGraphNode{variants: vec![VariantTuple{ + start_tick: base.start_tick, + end_tick: base.end_tick, + input_counter: base.input_counter, + input:input}], base:base } + } + /// unites the variants of this value with another, draining the other if the bases are equal + fn unite(mut self, other: &mut SysGraphNode) -> bool { + if &self!=other {return false;} + self.variants.append(&mut other.variants); + self.variants.dedup(); + return true; + } +} +impl PartialEq for SysGraphNode { + fn eq(&self, other: &SysGraphNode) -> bool { + self.base==other.base + } +} /// Improved System State Graph #[derive(Serialize, Deserialize, Clone, Debug, Default)] pub struct SysMapFeedbackState { - graph: DiGraph, + graph: DiGraph, entrypoint: NodeIndex, name: String, } impl SysMapFeedbackState { pub fn new() -> Self { - let mut graph = DiGraph::::new(); - let ind = graph.add_node(MiniFreeRTOSSystemState::default()); + let mut graph = DiGraph::::new(); + let ind = graph.add_node(SysGraphNode::default()); Self {graph: graph, entrypoint: ind, name: String::from("SysMap")} } - fn insert(&mut self, list: Vec) { + fn insert(&mut self, list: Vec, input: &Vec) { let mut current_index = self.entrypoint; for n in list { let mut done = false; for i in self.graph.neighbors_directed(current_index, Direction::Outgoing) { - if n == self.graph[i] { + if n == self.graph[i].base { done = true; current_index = i; break; } } if !done { - let j = self.graph.add_node(n); + let j = self.graph.add_node(SysGraphNode::from(n,input.clone())); self.graph.add_edge(current_index, j, ()); current_index = j; } } } - fn update(&mut self, list: &Vec) -> bool { + fn update(&mut self, list: &Vec, input: &Vec) -> bool { let mut current_index = self.entrypoint; let mut novel = false; for n in list { let mut matching : Option = None; for i in self.graph.neighbors_directed(current_index, Direction::Outgoing) { let tmp = &self.graph[i]; - if n == tmp { + if n == &tmp.base { matching = Some(i); current_index = i; break; @@ -75,14 +113,14 @@ impl SysMapFeedbackState match matching { None => { novel = true; - let j = self.graph.add_node(n.clone()); + let j = self.graph.add_node(SysGraphNode::from(n.clone(),input.clone())); self.graph.add_edge(current_index, j, ()); current_index = j; }, Some(i) => { - if n.get_time() > self.graph[i].get_time() { + if n.get_time() > self.graph[i].base.get_time() { novel = true; - self.graph[i]=n.clone(); + self.graph[i]=SysGraphNode::from(n.clone(),input.clone()); } } } @@ -101,7 +139,7 @@ impl FeedbackState for SysMapFeedbackState { fn reset(&mut self) -> Result<(), Error> { self.graph.clear(); - self.entrypoint = self.graph.add_node(MiniFreeRTOSSystemState::default()); + self.entrypoint = self.graph.add_node(SysGraphNode::default()); Ok(()) } } @@ -141,7 +179,7 @@ where .feedback_states_mut() .match_name_mut::("SysMap") .unwrap(); - Ok(feedbackstate.update(&observer.last_run)) + Ok(feedbackstate.update(&observer.last_run, &observer.last_input)) } } impl Named for SysMapFeedback diff --git a/fuzzers/wcet_qemu_sys/src/sysstate/observers.rs b/fuzzers/wcet_qemu_sys/src/sysstate/observers.rs index 76f762ed85..8e39aced75 100644 --- a/fuzzers/wcet_qemu_sys/src/sysstate/observers.rs +++ b/fuzzers/wcet_qemu_sys/src/sysstate/observers.rs @@ -1,3 +1,4 @@ +use libafl::inputs::HasTargetBytes; use libafl::bolts::HasLen; use libafl::bolts::tuples::Named; use libafl::Error; @@ -22,10 +23,13 @@ use super::{ pub struct QemuSysStateObserver { pub last_run: Vec, + pub last_input: Vec, name: String, } impl Observer for QemuSysStateObserver +where + I: HasTargetBytes { #[inline] fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> { @@ -36,6 +40,7 @@ impl Observer for QemuSysStateObserver #[inline] fn post_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> { unsafe {self.last_run = refine_system_states(&mut CURRENT_SYSSTATE_VEC);} + self.last_input=_input.target_bytes().as_slice().to_owned(); // let mut hasher = DefaultHasher::new(); // let mut a = self.parse_last(); // a[0].start_tick=21355; @@ -66,7 +71,7 @@ impl HasLen for QemuSysStateObserver impl QemuSysStateObserver { pub fn new() -> Self { - Self{last_run: vec![], name: "sysstate".to_string()} + Self{last_run: vec![], last_input: vec![], name: "sysstate".to_string()} } }