diff --git a/fuzzers/FRET/benchmark/.gitignore b/fuzzers/FRET/benchmark/.gitignore index 0a356bac3c..7853e1e273 100644 --- a/fuzzers/FRET/benchmark/.gitignore +++ b/fuzzers/FRET/benchmark/.gitignore @@ -6,3 +6,5 @@ mnt .R* *.png *.pdf +bins +.snakemake \ No newline at end of file diff --git a/fuzzers/FRET/benchmark/Snakefile b/fuzzers/FRET/benchmark/Snakefile new file mode 100644 index 0000000000..b6f0d52db7 --- /dev/null +++ b/fuzzers/FRET/benchmark/Snakefile @@ -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)) \ No newline at end of file diff --git a/fuzzers/FRET/benchmark/target_symbols.csv b/fuzzers/FRET/benchmark/target_symbols.csv index f4f2b7fc51..fff51edf76 100644 --- a/fuzzers/FRET/benchmark/target_symbols.csv +++ b/fuzzers/FRET/benchmark/target_symbols.csv @@ -15,4 +15,5 @@ gsm_enc,gsm_enc_main,gsm_enc_pcmdata,6400,gsm_enc_return tmr,main,FUZZ_INPUT,32,trigger_Qemu_break tacle_rtos,prvStage0,FUZZ_INPUT,604,trigger_Qemu_break lift,main_lift,FUZZ_INPUT,100,trigger_Qemu_break -waters,main_waters,FUZZ_INPUT,4096,trigger_Qemu_break \ No newline at end of file +waters,main_waters,FUZZ_INPUT,4096,trigger_Qemu_break +micro_branchless,main_branchless,FUZZ_INPUT,4,trigger_Qemu_break \ No newline at end of file diff --git a/fuzzers/FRET/fuzzer.sh b/fuzzers/FRET/fuzzer.sh index fd791d8630..968a149f13 100755 --- a/fuzzers/FRET/fuzzer.sh +++ b/fuzzers/FRET/fuzzer.sh @@ -15,4 +15,11 @@ cd "$parent_path" [ -n "${11}" -a "${11}" != "+" -a -z "$TRACE_DUMP" ] && export TRACE_DUMP="${11}" [ -z "$FUZZER" ] && export FUZZER=target/debug/fret -$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 \ No newline at end of file +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 +if [ "$exitcode" = "101" ] +then + exit 101 +else + exit 0 +fi \ No newline at end of file diff --git a/fuzzers/FRET/src/fuzzer.rs b/fuzzers/FRET/src/fuzzer.rs index 5a3f751420..5dd33d2e9f 100644 --- a/fuzzers/FRET/src/fuzzer.rs +++ b/fuzzers/FRET/src/fuzzer.rs @@ -1,7 +1,7 @@ //! A fuzzer using qemu in systemmode for binary-only coverage of kernels //! 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::{ bolts::{ @@ -320,6 +320,19 @@ pub fn fuzz() { }; fuzzer.evaluate_input(&mut state, &mut executor, &mut mgr, BytesInput::new(show_input)) .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::() { + for i in ichist.0.iter() { + writeln!(file, "{}", i).expect("Write to dump failed"); + } + } + } } else { if let Ok(_) = env::var("SEED_RANDOM") { unsafe { @@ -405,8 +418,8 @@ pub fn fuzz() { } match worst_input { Some(wi) => { - let mut cd = String::from(&td); - cd.push_str(".case"); + // let cd = format!("{}.case",&td); + let cd = td.clone(); fs::write(&cd,wi).expect("Failed to write worst corpus element"); }, None => (),