fuzz multiple interrupts

This commit is contained in:
Alwin Berger 2023-03-02 15:30:53 +01:00
parent 9336b932d0
commit 3c586f5047
3 changed files with 32 additions and 14 deletions

View File

@ -67,6 +67,12 @@ rule build_afl_int:
shell: shell:
"cargo build --target-dir {output} {def_flags},feed_afl,feed_longest,fuzz_int" "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: rule run_bench:
input: input:
"build/{target}.elf", "build/{target}.elf",
@ -94,7 +100,7 @@ rule run_bench:
export SEED_RANDOM=1 export SEED_RANDOM=1
export TIME_DUMP=$(pwd)/{output[0]} export TIME_DUMP=$(pwd)/{output[0]}
export CASE_DUMP=$(pwd)/{output[2]} export CASE_DUMP=$(pwd)/{output[2]}
export FUZZ_ITERS=3600 export FUZZ_ITERS=10800
export FUZZER=$(pwd)/{input[1]}/debug/fret export FUZZER=$(pwd)/{input[1]}/debug/fret
set +e set +e
../fuzzer.sh > {output[1]} 2>&1 ../fuzzer.sh > {output[1]} 2>&1
@ -177,4 +183,4 @@ rule all_compare_afl_longest:
rule all_micro: rule all_micro:
input: input:
expand("timedump/{fuzzer}/{target}.{num}", fuzzer=['afl_int','state_int','random_int'], target=['micro_int'],num=range(0,10)) expand("timedump/{fuzzer}/{target}.{num}", fuzzer=['afl_int','state_int','random_int','feedlongest_int'], target=['waters_int'],num=range(0,3))

View File

@ -16,5 +16,6 @@ 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
waters_int,main_waters,FUZZ_INPUT,4096,trigger_Qemu_break
micro_branchless,main_branchless,FUZZ_INPUT,4,trigger_Qemu_break micro_branchless,main_branchless,FUZZ_INPUT,4,trigger_Qemu_break
micro_int,main_branchless,FUZZ_INPUT,16,trigger_Qemu_break micro_int,main_branchless,FUZZ_INPUT,16,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 waters_int main_waters FUZZ_INPUT 4096 trigger_Qemu_break
20 micro_branchless main_branchless FUZZ_INPUT 4 trigger_Qemu_break
21 micro_int main_branchless FUZZ_INPUT 16 trigger_Qemu_break

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::{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::{ use libafl::{
bolts::{ bolts::{
@ -40,6 +40,8 @@ use crate::{
systemstate::{helpers::QemuSystemStateHelper, observers::QemuSystemStateObserver, feedbacks::{DumpSystraceFeedback, NovelSystemStateFeedback}, graph::{SysMapFeedback, SysGraphFeedbackState, GraphMaximizerCorpusScheduler}}, worst::{TimeMaximizerCorpusScheduler, ExecTimeIncFeedback, TimeStateMaximizerCorpusScheduler}, 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; pub static mut MAX_INPUT_SIZE: usize = 32;
/// Read ELF program headers to resolve physical load addresses. /// Read ELF program headers to resolve physical load addresses.
fn virt2phys(vaddr: GuestPhysAddr, tab: &EasyElf) -> GuestPhysAddr { fn virt2phys(vaddr: GuestPhysAddr, tab: &EasyElf) -> GuestPhysAddr {
@ -55,7 +57,8 @@ fn virt2phys(vaddr: GuestPhysAddr, tab: &EasyElf) -> GuestPhysAddr {
} }
extern "C" { extern "C" {
static mut libafl_int_offset : u32; static mut libafl_interrupt_offsets : [u32; 32];
static mut libafl_num_interrupts : usize;
} }
pub fn fuzz() { pub fn fuzz() {
@ -64,7 +67,7 @@ pub fn fuzz() {
str::parse::<usize>(&s).expect("FUZZ_SIZE was not a number"); str::parse::<usize>(&s).expect("FUZZ_SIZE was not a number");
}; };
// Hardcoded parameters // Hardcoded parameters
let timeout = Duration::from_secs(1); let timeout = Duration::from_secs(10);
let broker_port = 1337; let broker_port = 1337;
let cores = Cores::from_cmdline("1").unwrap(); let cores = Cores::from_cmdline("1").unwrap();
let corpus_dirs = [PathBuf::from("./corpus")]; let corpus_dirs = [PathBuf::from("./corpus")];
@ -147,7 +150,7 @@ pub fn fuzz() {
.expect("Symbol or env BREAKPOINT not found"); .expect("Symbol or env BREAKPOINT not found");
println!("Breakpoint address = {:#x}", breakpoint); println!("Breakpoint address = {:#x}", breakpoint);
unsafe { unsafe {
libafl_int_offset = 0; libafl_num_interrupts = 0;
} }
if let Ok(input_len) = env::var("FUZZ_INPUT_LEN") { 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 buf = target.as_slice();
let mut len = buf.len(); let mut len = buf.len();
unsafe { unsafe {
#[cfg(feature = "fuzz_int")] // #[cfg(feature = "fuzz_int")]
{ {
let mut t : [u8; 4] = [0,0,0,0]; for i in 0..DO_NUM_INTERRUPT {
for i in 0..min(4,len) { let mut t : [u8; 4] = [0,0,0,0];
t[i as usize]=buf[i as usize]; 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 { if len > MAX_INPUT_SIZE {
buf = &buf[0..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 // Wrap the executor to keep track of the timeout
let mut executor = TimeoutExecutor::new(executor, timeout); let mut executor = TimeoutExecutor::new(executor, timeout);
let mutations = havoc_mutations();
// Setup an havoc mutator with a mutational stage // 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)); let mut stages = tuple_list!(StdMutationalStage::new(mutator));
if env::var("DO_SHOWMAP").is_ok() { if env::var("DO_SHOWMAP").is_ok() {