From 3c586f50470dc9259110dfddb47ddefadb2d798c Mon Sep 17 00:00:00 2001 From: Alwin Berger Date: Thu, 2 Mar 2023 15:30:53 +0100 Subject: [PATCH] fuzz multiple interrupts --- fuzzers/FRET/benchmark/Snakefile | 10 +++++-- fuzzers/FRET/benchmark/target_symbols.csv | 1 + fuzzers/FRET/src/fuzzer.rs | 35 +++++++++++++++-------- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/fuzzers/FRET/benchmark/Snakefile b/fuzzers/FRET/benchmark/Snakefile index faae700ba5..a02d25dabb 100644 --- a/fuzzers/FRET/benchmark/Snakefile +++ b/fuzzers/FRET/benchmark/Snakefile @@ -67,6 +67,12 @@ rule build_afl_int: shell: "cargo build --target-dir {output} {def_flags},feed_afl,feed_longest,fuzz_int" +rule build_feedlongest_int: + output: + directory("bins/target_feedlongest_int") + shell: + "cargo build --target-dir {output} {def_flags},feed_longest,fuzz_int" + rule run_bench: input: "build/{target}.elf", @@ -94,7 +100,7 @@ rule run_bench: export SEED_RANDOM=1 export TIME_DUMP=$(pwd)/{output[0]} export CASE_DUMP=$(pwd)/{output[2]} - export FUZZ_ITERS=3600 + export FUZZ_ITERS=10800 export FUZZER=$(pwd)/{input[1]}/debug/fret set +e ../fuzzer.sh > {output[1]} 2>&1 @@ -177,4 +183,4 @@ rule all_compare_afl_longest: rule all_micro: input: - expand("timedump/{fuzzer}/{target}.{num}", fuzzer=['afl_int','state_int','random_int'], target=['micro_int'],num=range(0,10)) \ No newline at end of file + expand("timedump/{fuzzer}/{target}.{num}", fuzzer=['afl_int','state_int','random_int','feedlongest_int'], target=['waters_int'],num=range(0,3)) \ No newline at end of file diff --git a/fuzzers/FRET/benchmark/target_symbols.csv b/fuzzers/FRET/benchmark/target_symbols.csv index cdf2bb942b..0e817c947d 100644 --- a/fuzzers/FRET/benchmark/target_symbols.csv +++ b/fuzzers/FRET/benchmark/target_symbols.csv @@ -16,5 +16,6 @@ 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 +waters_int,main_waters,FUZZ_INPUT,4096,trigger_Qemu_break micro_branchless,main_branchless,FUZZ_INPUT,4,trigger_Qemu_break micro_int,main_branchless,FUZZ_INPUT,16,trigger_Qemu_break \ No newline at end of file diff --git a/fuzzers/FRET/src/fuzzer.rs b/fuzzers/FRET/src/fuzzer.rs index 4259067bed..c3da007b39 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::{self, abort}, io::{Read, Write}, fs::{self, OpenOptions}, cmp::min}; +use std::{env, path::PathBuf, process::{self, abort}, io::{Read, Write}, fs::{self, OpenOptions}, cmp::min, mem::transmute_copy, collections::btree_map::Range}; use libafl::{ bolts::{ @@ -40,6 +40,8 @@ use crate::{ systemstate::{helpers::QemuSystemStateHelper, observers::QemuSystemStateObserver, feedbacks::{DumpSystraceFeedback, NovelSystemStateFeedback}, graph::{SysMapFeedback, SysGraphFeedbackState, GraphMaximizerCorpusScheduler}}, worst::{TimeMaximizerCorpusScheduler, ExecTimeIncFeedback, TimeStateMaximizerCorpusScheduler}, }; +pub const MAX_NUM_INTERRUPT: usize = 32; +pub const DO_NUM_INTERRUPT: usize = 32; pub static mut MAX_INPUT_SIZE: usize = 32; /// Read ELF program headers to resolve physical load addresses. fn virt2phys(vaddr: GuestPhysAddr, tab: &EasyElf) -> GuestPhysAddr { @@ -55,7 +57,8 @@ fn virt2phys(vaddr: GuestPhysAddr, tab: &EasyElf) -> GuestPhysAddr { } extern "C" { - static mut libafl_int_offset : u32; + static mut libafl_interrupt_offsets : [u32; 32]; + static mut libafl_num_interrupts : usize; } pub fn fuzz() { @@ -64,7 +67,7 @@ pub fn fuzz() { str::parse::(&s).expect("FUZZ_SIZE was not a number"); }; // Hardcoded parameters - let timeout = Duration::from_secs(1); + let timeout = Duration::from_secs(10); let broker_port = 1337; let cores = Cores::from_cmdline("1").unwrap(); let corpus_dirs = [PathBuf::from("./corpus")]; @@ -147,7 +150,7 @@ pub fn fuzz() { .expect("Symbol or env BREAKPOINT not found"); println!("Breakpoint address = {:#x}", breakpoint); unsafe { - libafl_int_offset = 0; + libafl_num_interrupts = 0; } if let Ok(input_len) = env::var("FUZZ_INPUT_LEN") { @@ -177,15 +180,22 @@ pub fn fuzz() { let mut buf = target.as_slice(); let mut len = buf.len(); unsafe { - #[cfg(feature = "fuzz_int")] + // #[cfg(feature = "fuzz_int")] { - let mut t : [u8; 4] = [0,0,0,0]; - for i in 0..min(4,len) { - t[i as usize]=buf[i as usize]; + for i in 0..DO_NUM_INTERRUPT { + let mut t : [u8; 4] = [0,0,0,0]; + if len > (i+1)*4 { + for j in 0 as usize..4 as usize { + t[j]=buf[i*4+j]; + } + libafl_interrupt_offsets[i] = u32::from_le_bytes(t); + libafl_num_interrupts = i+1; + } + } + if buf.len() > libafl_num_interrupts*4 { + buf = &buf[libafl_num_interrupts*4..]; + len = buf.len(); } - libafl_int_offset = u32::from_le_bytes(t); - buf = &buf[min(4,len) as usize..]; - len = buf.len(); } if len > MAX_INPUT_SIZE { buf = &buf[0..MAX_INPUT_SIZE]; @@ -323,8 +333,9 @@ pub fn fuzz() { // Wrap the executor to keep track of the timeout let mut executor = TimeoutExecutor::new(executor, timeout); + let mutations = havoc_mutations(); // Setup an havoc mutator with a mutational stage - let mutator = StdScheduledMutator::new(havoc_mutations()); + let mutator = StdScheduledMutator::new(mutations); let mut stages = tuple_list!(StdMutationalStage::new(mutator)); if env::var("DO_SHOWMAP").is_ok() {