From 01e40ded1d1ecef2c13aeef9038db662c8c81201 Mon Sep 17 00:00:00 2001 From: Alwin Berger Date: Sun, 1 May 2022 22:07:37 +0200 Subject: [PATCH] fix interrupt input, graph output --- fuzzers/wcet_qemu_sys/src/bin/fuzzer.rs | 36 +++++++++++++++---- fuzzers/wcet_qemu_sys/src/bin/showmap.rs | 11 +++--- fuzzers/wcet_qemu_sys/src/sysstate/graph.rs | 25 ++++++++++--- fuzzers/wcet_qemu_sys/src/sysstate/helpers.rs | 15 -------- 4 files changed, 56 insertions(+), 31 deletions(-) diff --git a/fuzzers/wcet_qemu_sys/src/bin/fuzzer.rs b/fuzzers/wcet_qemu_sys/src/bin/fuzzer.rs index c3142bb3c2..8c1b70c111 100644 --- a/fuzzers/wcet_qemu_sys/src/bin/fuzzer.rs +++ b/fuzzers/wcet_qemu_sys/src/bin/fuzzer.rs @@ -1,5 +1,8 @@ //! A singlethreaded QEMU fuzzer that can auto-restart. +use libafl::bolts::tuples::MatchName; +use libafl::state::HasFeedbackStates; +use wcet_qemu_sys::sysstate::graph::SysGraphMetadata; use wcet_qemu_sys::sysstate::helpers::INTR_OFFSET; use wcet_qemu_sys::sysstate::graph::RandGraphSnippetMutator; use wcet_qemu_sys::sysstate::graph::GraphMaximizerCorpusScheduler; @@ -29,6 +32,8 @@ use std::{ path::PathBuf, process, }; +use petgraph::prelude::DiGraph; +use petgraph::dot::{Dot, Config}; use libafl::{ bolts::{ @@ -292,7 +297,7 @@ fn fuzz( "-kernel", kernel.to_str().unwrap(), "-serial", "stdio", "-nographic", "-snapshot", "-drive", format!("if=none,format=qcow2,file={}",snapshot.to_string_lossy()).as_str(), - "-icount", "shift=auto,align=off,sleep=off", + "-icount", "shift=3,align=off,sleep=off", "-S" ].iter().map(|x| x.to_string()).collect(); let env: Vec<(String, String)> = env::vars().collect(); @@ -416,11 +421,12 @@ fn fuzz( let mut buf = target.as_slice(); let mut len = buf.len(); let mut int_tick : Option = None; - if len > 4 { + if len > 2 { let mut t : [u8; 4] = [0,0,0,0]; // 4 extra bytes determine the tick to execute an interrupt - t.copy_from_slice(&buf[0..4]); + t[0]=buf[0]; + t[1]=buf[1]; int_tick = Some(u32::from_le_bytes(t)); - buf = &buf[4..]; + buf = &buf[2..]; len = buf.len(); } if len >= 32 { @@ -429,7 +435,7 @@ fn fuzz( } unsafe { - libafl_int_offset = int_tick.unwrap_or(0); + libafl_int_offset = 347780+int_tick.unwrap_or(0); // INTR_OFFSET = int_tick; emu.write_mem(test_length_ptr,&(len as u32).to_le_bytes()); emu.write_mem(input_addr,buf); @@ -506,9 +512,27 @@ fn fuzz( dup2(null_fd, io::stderr().as_raw_fd())?; } + // fuzzer + // .fuzz_for_solution(&mut stages, &mut executor, &mut state, &mut mgr) + // .expect("Error in the fuzzing loop"); fuzzer - .fuzz_for_solution(&mut stages, &mut executor, &mut state, &mut mgr) + .fuzz_loop_for(&mut stages, &mut executor, &mut state, &mut mgr, 20) .expect("Error in the fuzzing loop"); + + + let feedbackstate = state + .feedback_states() + .match_name::("SysMap") + .unwrap(); + let newgraph = feedbackstate.graph.map( + |_, n| n.get_taskname(), + |_, e| e, + ); + // println!("{:?}",feedbackstate.graph); + // println!("{:?}",Dot::with_config(&feedbackstate.graph, &[Config::EdgeNoLabel])); + let tempg = format!("{:?}",Dot::with_config(&newgraph, &[Config::EdgeNoLabel])); + fs::write("./graph.dot",tempg).expect("Graph can not be written"); + // Never reached Ok(()) diff --git a/fuzzers/wcet_qemu_sys/src/bin/showmap.rs b/fuzzers/wcet_qemu_sys/src/bin/showmap.rs index 98a65c1f21..bcb0d16734 100644 --- a/fuzzers/wcet_qemu_sys/src/bin/showmap.rs +++ b/fuzzers/wcet_qemu_sys/src/bin/showmap.rs @@ -216,7 +216,7 @@ fn fuzz( "-kernel", kernel.to_str().unwrap(), "-serial", "stdio", "-nographic", "-snapshot", "-drive", format!("if=none,format=qcow2,file={}",snapshot.to_string_lossy()).as_str(), - "-icount", "shift=auto,align=off,sleep=off", + "-icount", "shift=3,align=off,sleep=off", "-S" ].iter().map(|x| x.to_string()).collect(); let emu = Emulator::new(&mut args, &mut env); @@ -339,11 +339,12 @@ fn fuzz( let mut buf = target.as_slice(); let mut len = buf.len(); let mut int_tick : Option = None; - if len > 4 { + if len > 2 { let mut t : [u8; 4] = [0,0,0,0]; // 4 extra bytes determine the tick to execute an interrupt - t.copy_from_slice(&buf[0..4]); + t[0]=buf[0]; + t[1]=buf[1]; int_tick = Some(u32::from_le_bytes(t)); - buf = &buf[4..]; + buf = &buf[2..]; len = buf.len(); } if len >= 32 { @@ -352,7 +353,7 @@ fn fuzz( } unsafe { - libafl_int_offset = int_tick.unwrap_or(0); + libafl_int_offset = 347780+int_tick.unwrap_or(0); // INTR_OFFSET = int_tick; emu.write_mem(test_length_ptr,&(len as u32).to_le_bytes()); emu.write_mem(input_addr,buf); diff --git a/fuzzers/wcet_qemu_sys/src/sysstate/graph.rs b/fuzzers/wcet_qemu_sys/src/sysstate/graph.rs index 434fa47c81..a9601d0bf0 100644 --- a/fuzzers/wcet_qemu_sys/src/sysstate/graph.rs +++ b/fuzzers/wcet_qemu_sys/src/sysstate/graph.rs @@ -64,7 +64,7 @@ impl VariantTuple { } #[derive(Serialize, Deserialize, Clone, Debug, Default)] -struct SysGraphNode +pub struct SysGraphNode { base: RefinedFreeRTOSSystemState, variants: Vec, @@ -101,6 +101,9 @@ impl SysGraphNode { } return interesting; } + pub fn get_taskname(&self) -> &str { + &self.base.current_task.task_name + } } impl PartialEq for SysGraphNode { fn eq(&self, other: &SysGraphNode) -> bool { @@ -148,16 +151,22 @@ pub type GraphMaximizerCorpusScheduler = #[derive(Serialize, Deserialize, Clone, Debug, Default)] pub struct SysGraphFeedbackState { - graph: DiGraph, + pub graph: DiGraph, entrypoint: NodeIndex, + exit: NodeIndex, name: String, } impl SysGraphFeedbackState { pub fn new() -> Self { let mut graph = DiGraph::::new(); - let ind = graph.add_node(SysGraphNode::default()); - Self {graph: graph, entrypoint: ind, name: String::from("SysMap")} + let mut entry = SysGraphNode::default(); + entry.base.current_task.task_name="Start".to_string(); + let mut exit = SysGraphNode::default(); + exit.base.current_task.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")} } fn insert(&mut self, list: Vec, input: &Vec) { let mut current_index = self.entrypoint; @@ -205,6 +214,7 @@ impl SysGraphFeedbackState } trace.push(current_index); } + self.graph.update_edge(current_index, self.exit, ()); // every path ends in the exit noded return (novel, trace); } } @@ -219,7 +229,12 @@ impl FeedbackState for SysGraphFeedbackState { fn reset(&mut self) -> Result<(), Error> { self.graph.clear(); - self.entrypoint = self.graph.add_node(SysGraphNode::default()); + let mut entry = SysGraphNode::default(); + entry.base.current_task.task_name="Start".to_string(); + let mut exit = SysGraphNode::default(); + exit.base.current_task.task_name="End".to_string(); + self.entrypoint = self.graph.add_node(entry); + self.exit = self.graph.add_node(exit); Ok(()) } } diff --git a/fuzzers/wcet_qemu_sys/src/sysstate/helpers.rs b/fuzzers/wcet_qemu_sys/src/sysstate/helpers.rs index 030c25a830..a61ae25fd5 100644 --- a/fuzzers/wcet_qemu_sys/src/sysstate/helpers.rs +++ b/fuzzers/wcet_qemu_sys/src/sysstate/helpers.rs @@ -90,21 +90,6 @@ where I: Input, QT: QemuHelperTuple, { - unsafe { - match INTR_OFFSET { - None => (), - Some(off) => { - if emulator.get_ticks() > off { - if !INTR_DONE { - libafl_qemu::emu::libafl_send_irq(0); - INTR_DONE = true; - } - } else { - INTR_DONE = false; - } - }, - } - } let h = helpers.match_first_type::().expect("QemuSystemHelper not found in helper tupel"); if !h.must_instrument(pc) { return;