add snapshot path, debug prints
This commit is contained in:
parent
9369eae37b
commit
99bd30c233
1
fuzzers/wcet_qemu_sys/.gitignore
vendored
1
fuzzers/wcet_qemu_sys/.gitignore
vendored
@ -3,3 +3,4 @@
|
|||||||
demo
|
demo
|
||||||
*.ron
|
*.ron
|
||||||
*.bsp
|
*.bsp
|
||||||
|
tmp*
|
||||||
|
@ -7,7 +7,6 @@ edition = "2021"
|
|||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
std = []
|
std = []
|
||||||
showmap = []
|
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
debug = true
|
debug = true
|
||||||
|
4
fuzzers/wcet_qemu_sys/fuzzer.sh
Executable file
4
fuzzers/wcet_qemu_sys/fuzzer.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
mkdir -p tmp/test_in tmp/test_out
|
||||||
|
[ ! -f tmp/test_in/test ] && echo " !test" > tmp/test_in/test
|
||||||
|
[ ! -f tmp/dummy.qcow2 ] && qemu-img create -f qcow2 tmp/dummy.qcow2 32M
|
||||||
|
LD_LIBRARY_PATH=target/debug target/debug/fuzzer --libafl-snapshot tmp/dummy.qcow2 --libafl-out tmp/test_out --libafl-in tmp/test_in --libafl-kernel $@
|
4
fuzzers/wcet_qemu_sys/showmap.sh
Executable file
4
fuzzers/wcet_qemu_sys/showmap.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
mkdir -p tmp/test_in tmp/test_out
|
||||||
|
[ ! -f tmp/test_in/test ] && echo " !test" > tmp/test_in/test
|
||||||
|
[ ! -f tmp/dummy.qcow2 ] && qemu-img create -f qcow2 tmp/dummy.qcow2 32M
|
||||||
|
LD_LIBRARY_PATH=target/debug target/debug/showmap --libafl-snapshot tmp/dummy.qcow2 --libafl-out tmp/test_out --libafl-in tmp/test_in --libafl-kernel $@
|
@ -1,11 +1,6 @@
|
|||||||
//! A singlethreaded QEMU fuzzer that can auto-restart.
|
//! A singlethreaded QEMU fuzzer that can auto-restart.
|
||||||
|
|
||||||
use libafl::mutators::ByteFlipMutator;
|
|
||||||
use libafl::mutators::BitFlipMutator;
|
|
||||||
use wcet_qemu_sys::worst::LenTimeMaximizerCorpusScheduler;
|
|
||||||
use libafl::corpus::MinimizerCorpusScheduler;
|
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use libafl::events::SimpleEventManager;
|
|
||||||
use clap::{App, Arg};
|
use clap::{App, Arg};
|
||||||
use core::{cell::RefCell, time::Duration};
|
use core::{cell::RefCell, time::Duration};
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
@ -28,7 +23,7 @@ use libafl::{
|
|||||||
tuples::{tuple_list, Merge},
|
tuples::{tuple_list, Merge},
|
||||||
},
|
},
|
||||||
corpus::{
|
corpus::{
|
||||||
Corpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, PowerQueueCorpusScheduler,
|
Corpus, OnDiskCorpus, PowerQueueCorpusScheduler,
|
||||||
},
|
},
|
||||||
executors::{ExitKind, ShadowExecutor, TimeoutExecutor},
|
executors::{ExitKind, ShadowExecutor, TimeoutExecutor},
|
||||||
feedback_or,
|
feedback_or,
|
||||||
@ -40,13 +35,14 @@ use libafl::{
|
|||||||
scheduled::havoc_mutations, token_mutations::I2SRandReplace, tokens_mutations,
|
scheduled::havoc_mutations, token_mutations::I2SRandReplace, tokens_mutations,
|
||||||
StdMOptMutator, StdScheduledMutator, Tokens,
|
StdMOptMutator, StdScheduledMutator, Tokens,
|
||||||
},
|
},
|
||||||
observers::{TimeObserver, VariableMapObserver},
|
observers::{VariableMapObserver},
|
||||||
stages::{
|
stages::{
|
||||||
calibrate::CalibrationStage,
|
calibrate::CalibrationStage,
|
||||||
power::{PowerMutationalStage, PowerSchedule},
|
power::{PowerMutationalStage, PowerSchedule},
|
||||||
ShadowTracingStage, StdMutationalStage,
|
ShadowTracingStage, StdMutationalStage,
|
||||||
},
|
},
|
||||||
state::{HasCorpus, HasMetadata, StdState},
|
state::{HasCorpus, HasMetadata, StdState},
|
||||||
|
events::SimpleEventManager,
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
use libafl_qemu::{
|
use libafl_qemu::{
|
||||||
@ -65,7 +61,7 @@ use libafl_qemu::{
|
|||||||
clock::ClockFeedback,
|
clock::ClockFeedback,
|
||||||
clock::QemuClockIncreaseFeedback
|
clock::QemuClockIncreaseFeedback
|
||||||
};
|
};
|
||||||
use wcet_qemu_sys::worst::{HitFeedback,HitcountsMapObserver,HitImprovingFeedback};
|
use wcet_qemu_sys::worst::{HitFeedback,HitcountsMapObserver,HitImprovingFeedback,LenTimeMaximizerCorpusScheduler};
|
||||||
|
|
||||||
|
|
||||||
/// The fuzzer main
|
/// The fuzzer main
|
||||||
@ -121,6 +117,13 @@ pub fn main() {
|
|||||||
.long("libafl-edges")
|
.long("libafl-edges")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("snapshot")
|
||||||
|
.help("The qcow2 file used for snapshots")
|
||||||
|
.long("libafl-snapshot")
|
||||||
|
.required(true)
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
.try_get_matches_from(filter_qemu_args())
|
.try_get_matches_from(filter_qemu_args())
|
||||||
{
|
{
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
@ -178,7 +181,9 @@ pub fn main() {
|
|||||||
None => None
|
None => None
|
||||||
};
|
};
|
||||||
|
|
||||||
fuzz(out_dir, crashes, in_dir, tokens, logfile, timeout, kernel, edges)
|
let snapshot = PathBuf::from(res.value_of("snapshot").unwrap().to_string());
|
||||||
|
|
||||||
|
fuzz(out_dir, crashes, in_dir, tokens, logfile, timeout, kernel, edges, snapshot)
|
||||||
.expect("An error occurred while fuzzing");
|
.expect("An error occurred while fuzzing");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,6 +210,7 @@ fn fuzz(
|
|||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
kernel: PathBuf,
|
kernel: PathBuf,
|
||||||
dump_edges: Option<PathBuf>,
|
dump_edges: Option<PathBuf>,
|
||||||
|
snapshot: PathBuf,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
env::remove_var("LD_LIBRARY_PATH");
|
env::remove_var("LD_LIBRARY_PATH");
|
||||||
|
|
||||||
@ -217,7 +223,7 @@ fn fuzz(
|
|||||||
"--semihosting-config", "enable=on,target=native",
|
"--semihosting-config", "enable=on,target=native",
|
||||||
"-kernel", kernel.to_str().unwrap(),
|
"-kernel", kernel.to_str().unwrap(),
|
||||||
"-serial", "stdio", "-nographic",
|
"-serial", "stdio", "-nographic",
|
||||||
"-snapshot", "-drive", "if=none,format=qcow2,file=dummy.qcow2",
|
"-snapshot", "-drive", format!("if=none,format=qcow2,file={}",snapshot.to_string_lossy()).as_str(),
|
||||||
"-icount", "shift=auto,align=off,sleep=off",
|
"-icount", "shift=auto,align=off,sleep=off",
|
||||||
"-S"
|
"-S"
|
||||||
].iter().map(|x| x.to_string()).collect();
|
].iter().map(|x| x.to_string()).collect();
|
||||||
@ -373,10 +379,8 @@ fn fuzz(
|
|||||||
unsafe {
|
unsafe {
|
||||||
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);
|
||||||
// println!("{:#?}",edges_copy);
|
|
||||||
|
|
||||||
emu.run();
|
emu.run();
|
||||||
// println!("{:#?}",edges_copy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExitKind::Ok
|
ExitKind::Ok
|
||||||
|
@ -1,16 +1,9 @@
|
|||||||
//! A singlethreaded QEMU fuzzer that can auto-restart.
|
//! A singlethreaded QEMU fuzzer that can auto-restart.
|
||||||
|
|
||||||
use wcet_qemu_sys::worst::DumpMapFeedback;
|
use wcet_qemu_sys::{
|
||||||
use wcet_qemu_sys::worst::DummyFeedback;
|
worst::{DumpMapFeedback,DummyFeedback,HitcountsMapObserver},
|
||||||
use libafl_qemu::QemuInstrumentationFilter;
|
system_trace::QemuSystemStateHelper,
|
||||||
use wcet_qemu_sys::system_trace::QemuSystemStateHelper;
|
};
|
||||||
use libafl_qemu::QemuExecutor;
|
|
||||||
use libafl::Evaluator;
|
|
||||||
use libafl::inputs::Input;
|
|
||||||
use libafl::corpus::InMemoryCorpus;
|
|
||||||
use libafl::events::SimpleEventManager;
|
|
||||||
use libafl::stats::SimpleStats;
|
|
||||||
use wcet_qemu_sys::worst::HitcountsMapObserver;
|
|
||||||
use clap::{App, Arg};
|
use clap::{App, Arg};
|
||||||
use std::{
|
use std::{
|
||||||
env,
|
env,
|
||||||
@ -24,21 +17,26 @@ use libafl::{
|
|||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
tuples::{tuple_list},
|
tuples::{tuple_list},
|
||||||
},
|
},
|
||||||
corpus::{QueueCorpusScheduler},
|
corpus::{InMemoryCorpus,QueueCorpusScheduler},
|
||||||
executors::{ExitKind},
|
executors::{ExitKind},
|
||||||
fuzzer::{StdFuzzer},
|
fuzzer::{StdFuzzer},
|
||||||
inputs::{BytesInput, HasTargetBytes},
|
inputs::{Input,BytesInput, HasTargetBytes},
|
||||||
observers::{VariableMapObserver},
|
observers::{VariableMapObserver},
|
||||||
state::{StdState},
|
state::{StdState},
|
||||||
Error,
|
Error,
|
||||||
|
Evaluator,
|
||||||
|
stats::SimpleStats,
|
||||||
|
events::SimpleEventManager,
|
||||||
};
|
};
|
||||||
use libafl_qemu::{
|
use libafl_qemu::{
|
||||||
edges,
|
edges,
|
||||||
edges::QemuEdgeCoverageHelper,
|
edges::QemuEdgeCoverageHelper,
|
||||||
emu::Emulator, filter_qemu_args,
|
emu::Emulator, filter_qemu_args,
|
||||||
snapshot_sys::QemuSysSnapshotHelper,
|
|
||||||
elf::EasyElf,
|
elf::EasyElf,
|
||||||
|
snapshot_sys::QemuSysSnapshotHelper,
|
||||||
clock::{QemuClockObserver},
|
clock::{QemuClockObserver},
|
||||||
|
QemuInstrumentationFilter,
|
||||||
|
QemuExecutor,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -90,6 +88,13 @@ pub fn main() {
|
|||||||
.long("libafl-edges")
|
.long("libafl-edges")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("snapshot")
|
||||||
|
.help("The qcow2 file used for snapshots")
|
||||||
|
.long("libafl-snapshot")
|
||||||
|
.required(true)
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
.try_get_matches_from(filter_qemu_args())
|
.try_get_matches_from(filter_qemu_args())
|
||||||
{
|
{
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
@ -135,8 +140,9 @@ pub fn main() {
|
|||||||
None => None
|
None => None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let snapshot = PathBuf::from(res.value_of("snapshot").unwrap().to_string());
|
||||||
|
|
||||||
fuzz(in_dir, kernel, edges)
|
fuzz(in_dir, kernel, edges, snapshot)
|
||||||
.expect("An error occurred while fuzzing");
|
.expect("An error occurred while fuzzing");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,6 +164,7 @@ fn fuzz(
|
|||||||
seed_dir: PathBuf,
|
seed_dir: PathBuf,
|
||||||
kernel: PathBuf,
|
kernel: PathBuf,
|
||||||
dump_edges: Option<PathBuf>,
|
dump_edges: Option<PathBuf>,
|
||||||
|
snapshot: PathBuf,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
//=========== Setup emulator
|
//=========== Setup emulator
|
||||||
let mut env: Vec<(String, String)> = env::vars().collect();
|
let mut env: Vec<(String, String)> = env::vars().collect();
|
||||||
@ -169,7 +176,7 @@ fn fuzz(
|
|||||||
"--semihosting-config", "enable=on,target=native",
|
"--semihosting-config", "enable=on,target=native",
|
||||||
"-kernel", kernel.to_str().unwrap(),
|
"-kernel", kernel.to_str().unwrap(),
|
||||||
"-serial", "stdio", "-nographic",
|
"-serial", "stdio", "-nographic",
|
||||||
"-snapshot", "-drive", "if=none,format=qcow2,file=dummy.qcow2",
|
"-snapshot", "-drive", format!("if=none,format=qcow2,file={}",snapshot.to_string_lossy()).as_str(),
|
||||||
"-icount", "shift=auto,align=off,sleep=off",
|
"-icount", "shift=auto,align=off,sleep=off",
|
||||||
"-S"
|
"-S"
|
||||||
].iter().map(|x| x.to_string()).collect();
|
].iter().map(|x| x.to_string()).collect();
|
||||||
|
@ -175,8 +175,6 @@ where
|
|||||||
EM: EventFirer<I>,
|
EM: EventFirer<I>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
{
|
{
|
||||||
// TODO Replace with match_name_type when stable
|
|
||||||
// let observer = _observers.match_name::<HitcountsMapObserver<O>>("edges").expect("SelectedEdgeObserver not found");
|
|
||||||
let observer = _observers.match_name::<HitcountsMapObserver<VariableMapObserver<u8>>>("edges")
|
let observer = _observers.match_name::<HitcountsMapObserver<VariableMapObserver<u8>>>("edges")
|
||||||
.expect("HitcountsMapObserver not found");
|
.expect("HitcountsMapObserver not found");
|
||||||
if self.target_map.len() == 0 { return Ok(true) };
|
if self.target_map.len() == 0 { return Ok(true) };
|
||||||
@ -190,8 +188,8 @@ where
|
|||||||
}
|
}
|
||||||
let mean_sum_of_squares = (sum_of_square_difference as f64) / (self.target_map.len() as f64);
|
let mean_sum_of_squares = (sum_of_square_difference as f64) / (self.target_map.len() as f64);
|
||||||
let hit_target = mean_sum_of_squares <= self.target_msd;
|
let hit_target = mean_sum_of_squares <= self.target_msd;
|
||||||
// eprintln!("hit target: {} {} {:?}",hit_target,mean_sum_of_squares, _input);
|
|
||||||
if hit_target {
|
if hit_target {
|
||||||
|
#[cfg(debug_assertions)] eprintln!("Hit Feedback trigger");
|
||||||
Ok(true)
|
Ok(true)
|
||||||
} else {
|
} else {
|
||||||
Ok(false)
|
Ok(false)
|
||||||
@ -305,8 +303,6 @@ where
|
|||||||
EM: EventFirer<I>,
|
EM: EventFirer<I>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
{
|
{
|
||||||
// TODO Replace with match_name_type when stable
|
|
||||||
// let observer = _observers.match_name::<HitcountsMapObserver<O>>("edges").expect("SelectedEdgeObserver not found");
|
|
||||||
let observer = _observers.match_name::<HitcountsMapObserver<VariableMapObserver<u8>>>("edges")
|
let observer = _observers.match_name::<HitcountsMapObserver<VariableMapObserver<u8>>>("edges")
|
||||||
.expect("HitcountsMapObserver not found");
|
.expect("HitcountsMapObserver not found");
|
||||||
if self.target_map.len() == 0 { return Ok(true) };
|
if self.target_map.len() == 0 { return Ok(true) };
|
||||||
@ -320,9 +316,8 @@ where
|
|||||||
}
|
}
|
||||||
let mean_sum_of_squares = (sum_of_square_difference as f64) / (self.target_map.len() as f64);
|
let mean_sum_of_squares = (sum_of_square_difference as f64) / (self.target_map.len() as f64);
|
||||||
let hit_target = mean_sum_of_squares < self.best_msd;
|
let hit_target = mean_sum_of_squares < self.best_msd;
|
||||||
// eprintln!("improving: {}",hit_target);
|
|
||||||
if hit_target {
|
if hit_target {
|
||||||
// println!("Hit Improving: {}",mean_sum_of_squares);
|
#[cfg(debug_assertions)] eprintln!("Hit Improving: {}",mean_sum_of_squares);
|
||||||
self.best_msd = mean_sum_of_squares;
|
self.best_msd = mean_sum_of_squares;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
} else {
|
} else {
|
||||||
@ -383,7 +378,7 @@ where
|
|||||||
fs::write(s,ron::to_string(&observer.edgemap).expect("Error serializing hashmap")).expect("Can not dump to file");
|
fs::write(s,ron::to_string(&observer.edgemap).expect("Error serializing hashmap")).expect("Can not dump to file");
|
||||||
self.dumpfile = None
|
self.dumpfile = None
|
||||||
},
|
},
|
||||||
None => ()//println!("{:#?}",observer.edgemap),
|
None => println!("{:?}",observer.edgemap),
|
||||||
};
|
};
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
@ -507,7 +502,6 @@ where
|
|||||||
I: Input + HasLen,
|
I: Input + HasLen,
|
||||||
{
|
{
|
||||||
fn compute(entry: &mut Testcase<I>) -> Result<u64, Error> {
|
fn compute(entry: &mut Testcase<I>) -> Result<u64, Error> {
|
||||||
// TODO maybe enforce entry.exec_time().is_some()
|
|
||||||
let execs_per_hour = (3600.0/entry.exec_time().expect("testcase.exec_time is needed for scheduler").as_secs_f64()) as u64;
|
let execs_per_hour = (3600.0/entry.exec_time().expect("testcase.exec_time is needed for scheduler").as_secs_f64()) as u64;
|
||||||
let execs_times_length_per_hour = execs_per_hour*entry.cached_len()? as u64;
|
let execs_times_length_per_hour = execs_per_hour*entry.cached_len()? as u64;
|
||||||
Ok(execs_times_length_per_hour)
|
Ok(execs_times_length_per_hour)
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
mkdir -p target/test_in target/test_out
|
|
||||||
[ ! -f target/test_in/test ] && echo " !test" > target/test_in/test
|
|
||||||
LD_LIBRARY_PATH=target/debug target/debug/wcet_qemu_sys --libafl-out target/test_out --libafl-in target/test_in --libafl-kernel $@
|
|
Loading…
x
Reference in New Issue
Block a user