fix interrupt input, graph output
This commit is contained in:
parent
0b638d9020
commit
01e40ded1d
@ -1,5 +1,8 @@
|
|||||||
//! A singlethreaded QEMU fuzzer that can auto-restart.
|
//! 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::helpers::INTR_OFFSET;
|
||||||
use wcet_qemu_sys::sysstate::graph::RandGraphSnippetMutator;
|
use wcet_qemu_sys::sysstate::graph::RandGraphSnippetMutator;
|
||||||
use wcet_qemu_sys::sysstate::graph::GraphMaximizerCorpusScheduler;
|
use wcet_qemu_sys::sysstate::graph::GraphMaximizerCorpusScheduler;
|
||||||
@ -29,6 +32,8 @@ use std::{
|
|||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
process,
|
process,
|
||||||
};
|
};
|
||||||
|
use petgraph::prelude::DiGraph;
|
||||||
|
use petgraph::dot::{Dot, Config};
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
bolts::{
|
bolts::{
|
||||||
@ -292,7 +297,7 @@ fn fuzz(
|
|||||||
"-kernel", kernel.to_str().unwrap(),
|
"-kernel", kernel.to_str().unwrap(),
|
||||||
"-serial", "stdio", "-nographic",
|
"-serial", "stdio", "-nographic",
|
||||||
"-snapshot", "-drive", format!("if=none,format=qcow2,file={}",snapshot.to_string_lossy()).as_str(),
|
"-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"
|
"-S"
|
||||||
].iter().map(|x| x.to_string()).collect();
|
].iter().map(|x| x.to_string()).collect();
|
||||||
let env: Vec<(String, String)> = env::vars().collect();
|
let env: Vec<(String, String)> = env::vars().collect();
|
||||||
@ -416,11 +421,12 @@ fn fuzz(
|
|||||||
let mut buf = target.as_slice();
|
let mut buf = target.as_slice();
|
||||||
let mut len = buf.len();
|
let mut len = buf.len();
|
||||||
let mut int_tick : Option<u32> = None;
|
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
|
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));
|
int_tick = Some(u32::from_le_bytes(t));
|
||||||
buf = &buf[4..];
|
buf = &buf[2..];
|
||||||
len = buf.len();
|
len = buf.len();
|
||||||
}
|
}
|
||||||
if len >= 32 {
|
if len >= 32 {
|
||||||
@ -429,7 +435,7 @@ fn fuzz(
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
libafl_int_offset = int_tick.unwrap_or(0);
|
libafl_int_offset = 347780+int_tick.unwrap_or(0);
|
||||||
// INTR_OFFSET = int_tick;
|
// INTR_OFFSET = int_tick;
|
||||||
emu.write_mem(test_length_ptr,&(len as u32).to_le_bytes());
|
emu.write_mem(test_length_ptr,&(len as u32).to_le_bytes());
|
||||||
emu.write_mem(input_addr,buf);
|
emu.write_mem(input_addr,buf);
|
||||||
@ -506,9 +512,27 @@ fn fuzz(
|
|||||||
dup2(null_fd, io::stderr().as_raw_fd())?;
|
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
|
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");
|
.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
|
// Never reached
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -216,7 +216,7 @@ fn fuzz(
|
|||||||
"-kernel", kernel.to_str().unwrap(),
|
"-kernel", kernel.to_str().unwrap(),
|
||||||
"-serial", "stdio", "-nographic",
|
"-serial", "stdio", "-nographic",
|
||||||
"-snapshot", "-drive", format!("if=none,format=qcow2,file={}",snapshot.to_string_lossy()).as_str(),
|
"-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"
|
"-S"
|
||||||
].iter().map(|x| x.to_string()).collect();
|
].iter().map(|x| x.to_string()).collect();
|
||||||
let emu = Emulator::new(&mut args, &mut env);
|
let emu = Emulator::new(&mut args, &mut env);
|
||||||
@ -339,11 +339,12 @@ fn fuzz(
|
|||||||
let mut buf = target.as_slice();
|
let mut buf = target.as_slice();
|
||||||
let mut len = buf.len();
|
let mut len = buf.len();
|
||||||
let mut int_tick : Option<u32> = None;
|
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
|
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));
|
int_tick = Some(u32::from_le_bytes(t));
|
||||||
buf = &buf[4..];
|
buf = &buf[2..];
|
||||||
len = buf.len();
|
len = buf.len();
|
||||||
}
|
}
|
||||||
if len >= 32 {
|
if len >= 32 {
|
||||||
@ -352,7 +353,7 @@ fn fuzz(
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
libafl_int_offset = int_tick.unwrap_or(0);
|
libafl_int_offset = 347780+int_tick.unwrap_or(0);
|
||||||
// INTR_OFFSET = int_tick;
|
// INTR_OFFSET = int_tick;
|
||||||
emu.write_mem(test_length_ptr,&(len as u32).to_le_bytes());
|
emu.write_mem(test_length_ptr,&(len as u32).to_le_bytes());
|
||||||
emu.write_mem(input_addr,buf);
|
emu.write_mem(input_addr,buf);
|
||||||
|
@ -64,7 +64,7 @@ impl VariantTuple {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
|
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
|
||||||
struct SysGraphNode
|
pub struct SysGraphNode
|
||||||
{
|
{
|
||||||
base: RefinedFreeRTOSSystemState,
|
base: RefinedFreeRTOSSystemState,
|
||||||
variants: Vec<VariantTuple>,
|
variants: Vec<VariantTuple>,
|
||||||
@ -101,6 +101,9 @@ impl SysGraphNode {
|
|||||||
}
|
}
|
||||||
return interesting;
|
return interesting;
|
||||||
}
|
}
|
||||||
|
pub fn get_taskname(&self) -> &str {
|
||||||
|
&self.base.current_task.task_name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl PartialEq for SysGraphNode {
|
impl PartialEq for SysGraphNode {
|
||||||
fn eq(&self, other: &SysGraphNode) -> bool {
|
fn eq(&self, other: &SysGraphNode) -> bool {
|
||||||
@ -148,16 +151,22 @@ pub type GraphMaximizerCorpusScheduler<CS, I, S> =
|
|||||||
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
|
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
|
||||||
pub struct SysGraphFeedbackState
|
pub struct SysGraphFeedbackState
|
||||||
{
|
{
|
||||||
graph: DiGraph<SysGraphNode, ()>,
|
pub graph: DiGraph<SysGraphNode, ()>,
|
||||||
entrypoint: NodeIndex,
|
entrypoint: NodeIndex,
|
||||||
|
exit: NodeIndex,
|
||||||
name: String,
|
name: String,
|
||||||
}
|
}
|
||||||
impl SysGraphFeedbackState
|
impl SysGraphFeedbackState
|
||||||
{
|
{
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let mut graph = DiGraph::<SysGraphNode, ()>::new();
|
let mut graph = DiGraph::<SysGraphNode, ()>::new();
|
||||||
let ind = graph.add_node(SysGraphNode::default());
|
let mut entry = SysGraphNode::default();
|
||||||
Self {graph: graph, entrypoint: ind, name: String::from("SysMap")}
|
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>) {
|
fn insert(&mut self, list: Vec<RefinedFreeRTOSSystemState>, input: &Vec<u8>) {
|
||||||
let mut current_index = self.entrypoint;
|
let mut current_index = self.entrypoint;
|
||||||
@ -205,6 +214,7 @@ impl SysGraphFeedbackState
|
|||||||
}
|
}
|
||||||
trace.push(current_index);
|
trace.push(current_index);
|
||||||
}
|
}
|
||||||
|
self.graph.update_edge(current_index, self.exit, ()); // every path ends in the exit noded
|
||||||
return (novel, trace);
|
return (novel, trace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -219,7 +229,12 @@ impl FeedbackState for SysGraphFeedbackState
|
|||||||
{
|
{
|
||||||
fn reset(&mut self) -> Result<(), Error> {
|
fn reset(&mut self) -> Result<(), Error> {
|
||||||
self.graph.clear();
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,21 +90,6 @@ where
|
|||||||
I: Input,
|
I: Input,
|
||||||
QT: QemuHelperTuple<I, S>,
|
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");
|
let h = helpers.match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
|
||||||
if !h.must_instrument(pc) {
|
if !h.must_instrument(pc) {
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user