benchmark using snakemake

This commit is contained in:
Alwin Berger 2023-02-16 22:56:43 +01:00
parent 2593bdf42f
commit f7a05d2a7c
5 changed files with 94 additions and 5 deletions

View File

@ -6,3 +6,5 @@ mnt
.R* .R*
*.png *.png
*.pdf *.pdf
bins
.snakemake

View File

@ -0,0 +1,66 @@
import csv
rule build_random:
output:
directory("bins/target_random")
shell:
"cargo build --target-dir {output}"
rule build_afl:
output:
directory("bins/target_afl")
shell:
"cargo build --target-dir {output}"
rule build_state:
output:
directory("bins/target_state")
shell:
"cargo build --target-dir {output} --features systemtrace"
rule build_graph:
output:
directory("bins/target_graph")
shell:
"cargo build --target-dir {output} --features systemgraph"
rule run_bench:
input:
"build/{target}.elf",
"bins/target_{fuzzer}"
output:
multiext("timedump/{fuzzer}/{target}.{num}", "", ".log", ".case")
run:
with open('target_symbols.csv') as csvfile:
reader = csv.DictReader(csvfile)
line = next((x for x in reader if x['kernel']==wildcards.target), None)
if line == None:
return False
kernel=line['kernel']
fuzz_main=line['main_function']
fuzz_input=line['input_symbol']
fuzz_len=line['input_size']
bkp=line['return_function']
script="""
mkdir -p $(dirname {output[0]})
export KERNEL=$(pwd)/{input[0]}
export FUZZ_MAIN={fuzz_main}
export FUZZ_INPUT={fuzz_input}
export FUZZ_INPUT_LEN={fuzz_len}
export BREAKPOINT={bkp}
export SEED_RANDOM=1
export TIME_DUMP=$(pwd)/{output[0]}
export CASE_DUMP=$(pwd)/{output[2]}
export FUZZ_ITERS=7200
export FUZZER=$(pwd)/{input[1]}/debug/fret
set +e
../fuzzer.sh > {output[1]} 2>&1
exit 0
"""
if wildcards.fuzzer == 'random':
script="export FUZZ_RANDOM=1\n"+script
shell(script)
rule all_periodic:
input:
expand("timedump/{fuzzer}/{target}.{num}", fuzzer=['random','afl','state','graph'], target=['waters'],num=range(0,10))

View File

@ -16,3 +16,4 @@ tmr,main,FUZZ_INPUT,32,trigger_Qemu_break
tacle_rtos,prvStage0,FUZZ_INPUT,604,trigger_Qemu_break tacle_rtos,prvStage0,FUZZ_INPUT,604,trigger_Qemu_break
lift,main_lift,FUZZ_INPUT,100,trigger_Qemu_break lift,main_lift,FUZZ_INPUT,100,trigger_Qemu_break
waters,main_waters,FUZZ_INPUT,4096,trigger_Qemu_break waters,main_waters,FUZZ_INPUT,4096,trigger_Qemu_break
micro_branchless,main_branchless,FUZZ_INPUT,4,trigger_Qemu_break
1 kernel main_function input_symbol input_size return_function
16 tacle_rtos prvStage0 FUZZ_INPUT 604 trigger_Qemu_break
17 lift main_lift FUZZ_INPUT 100 trigger_Qemu_break
18 waters main_waters FUZZ_INPUT 4096 trigger_Qemu_break
19 micro_branchless main_branchless FUZZ_INPUT 4 trigger_Qemu_break

View File

@ -15,4 +15,11 @@ cd "$parent_path"
[ -n "${11}" -a "${11}" != "+" -a -z "$TRACE_DUMP" ] && export TRACE_DUMP="${11}" [ -n "${11}" -a "${11}" != "+" -a -z "$TRACE_DUMP" ] && export TRACE_DUMP="${11}"
[ -z "$FUZZER" ] && export FUZZER=target/debug/fret [ -z "$FUZZER" ] && export FUZZER=target/debug/fret
set +e
$FUZZER -icount shift=4,align=off,sleep=off -machine mps2-an385 -monitor null -kernel $KERNEL -serial null -nographic -S -semihosting --semihosting-config enable=on,target=native -snapshot -drive if=none,format=qcow2,file=dummy.qcow2 $FUZZER -icount shift=4,align=off,sleep=off -machine mps2-an385 -monitor null -kernel $KERNEL -serial null -nographic -S -semihosting --semihosting-config enable=on,target=native -snapshot -drive if=none,format=qcow2,file=dummy.qcow2
if [ "$exitcode" = "101" ]
then
exit 101
else
exit 0
fi

View File

@ -1,7 +1,7 @@
//! A fuzzer using qemu in systemmode for binary-only coverage of kernels //! A fuzzer using qemu in systemmode for binary-only coverage of kernels
//! //!
use core::time::Duration; use core::time::Duration;
use std::{env, path::PathBuf, process, io::{Read, Write}, fs::{self, OpenOptions}}; use std::{env, path::PathBuf, process::{self, abort}, io::{Read, Write}, fs::{self, OpenOptions}};
use libafl::{ use libafl::{
bolts::{ bolts::{
@ -320,6 +320,19 @@ pub fn fuzz() {
}; };
fuzzer.evaluate_input(&mut state, &mut executor, &mut mgr, BytesInput::new(show_input)) fuzzer.evaluate_input(&mut state, &mut executor, &mut mgr, BytesInput::new(show_input))
.unwrap(); .unwrap();
if let Ok(td) = env::var("TIME_DUMP") {
let mut file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.append(true)
.open(td).expect("Could not open timedump");
if let Some(ichist) = state.metadata().get::<IcHist>() {
for i in ichist.0.iter() {
writeln!(file, "{}", i).expect("Write to dump failed");
}
}
}
} else { } else {
if let Ok(_) = env::var("SEED_RANDOM") { if let Ok(_) = env::var("SEED_RANDOM") {
unsafe { unsafe {
@ -405,8 +418,8 @@ pub fn fuzz() {
} }
match worst_input { match worst_input {
Some(wi) => { Some(wi) => {
let mut cd = String::from(&td); // let cd = format!("{}.case",&td);
cd.push_str(".case"); let cd = td.clone();
fs::write(&cd,wi).expect("Failed to write worst corpus element"); fs::write(&cd,wi).expect("Failed to write worst corpus element");
}, },
None => (), None => (),