fix interrupt input, graph output

This commit is contained in:
Alwin Berger 2022-05-01 22:07:37 +02:00
parent 0b638d9020
commit 01e40ded1d
4 changed files with 56 additions and 31 deletions

View File

@ -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<u32> = 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::<SysGraphFeedbackState>("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(())

View File

@ -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<u32> = 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);

View File

@ -64,7 +64,7 @@ impl VariantTuple {
}
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
struct SysGraphNode
pub struct SysGraphNode
{
base: RefinedFreeRTOSSystemState,
variants: Vec<VariantTuple>,
@ -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<CS, I, S> =
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
pub struct SysGraphFeedbackState
{
graph: DiGraph<SysGraphNode, ()>,
pub graph: DiGraph<SysGraphNode, ()>,
entrypoint: NodeIndex,
exit: NodeIndex,
name: String,
}
impl SysGraphFeedbackState
{
pub fn new() -> Self {
let mut graph = DiGraph::<SysGraphNode, ()>::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<RefinedFreeRTOSSystemState>, input: &Vec<u8>) {
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(())
}
}

View File

@ -90,21 +90,6 @@ where
I: Input,
QT: QemuHelperTuple<I, S>,
{
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::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
if !h.must_instrument(pc) {
return;