diff --git a/fuzzers/FRET/src/systemstate/mutators.rs b/fuzzers/FRET/src/systemstate/mutators.rs index f081ab1b06..bd62c2192f 100644 --- a/fuzzers/FRET/src/systemstate/mutators.rs +++ b/fuzzers/FRET/src/systemstate/mutators.rs @@ -14,6 +14,7 @@ use libafl::prelude::Corpus; use libafl::prelude::UsesInput; use core::marker::PhantomData; use std::cmp::max; +use std::cmp::min; use libafl::state::HasCorpus; use libafl::state::HasSolutions; use libafl::state::HasRand; @@ -68,8 +69,6 @@ where target_bytes = input.bytes().to_vec(); } - let mut target_tick = 0; - // produce a slice of absolute interrupt times let mut interrupt_offsets : [u32; 32] = [0u32; 32]; let mut num_interrupts : usize = 0; @@ -92,8 +91,11 @@ where } } + println!("Vor Mutator: {:?}", interrupt_offsets[0..num_interrupts].to_vec()); + // let num_i = min(target_bytes.len() / 4, DO_NUM_INTERRUPT); + let mut suffix = target_bytes.split_off(4 * num_interrupts); let mut prefix : Vec<[u8; 4]> = vec![]; - let mut suffix : Vec = vec![]; + // let mut suffix : Vec = vec![]; // #[cfg(feature = "feed_systemtrace")] { let tmp = _input.metadata().get::(); @@ -110,26 +112,78 @@ where let m = interrupt_offsets[0..num_interrupts].iter().any(|x| (curr.start_tick..curr.end_tick).contains(&(*x as u64))); if m { marks.push((curr, i, 1)); - // println!("1: {}",curr.current_task.task_name); + println!("1: {}",curr.current_task.task_name); } else if last_m { marks.push((curr, i, 2)); - // println!("2: {}",curr.current_task.task_name); + println!("2: {}",curr.current_task.task_name); } else { marks.push((curr, i, 0)); } last_m = m; } - let untouched : Vec = marks.iter().filter_map( - |x| if x.2 == 0 { - Some(x.0.start_tick.try_into().expect("ticks > u32")) - } else { - None - } - ).collect(); - let mut numbers : Vec = vec![]; for i in 0..num_interrupts { - numbers.push(myrand.choose(untouched.clone().into_iter()).try_into().expect("ticks > u32")); + // bounds based on minimum inter-arrival time + let mut lb = 0; + let mut ub : u32 = marks[marks.len()-1].0.end_tick.try_into().expect("ticks > u32"); + if i > 0 { + lb = interrupt_offsets[i-1]+MINIMUM_INTER_ARRIVAL_TIME; + } + if i < num_interrupts-1 { + ub = interrupt_offsets[i+1]-MINIMUM_INTER_ARRIVAL_TIME; + } + // get old hit and handler + let old_hit = marks.iter().filter( + |x| x.0.start_tick < (interrupt_offsets[i] as u64) && (interrupt_offsets[i] as u64) < x.0.end_tick + ).next(); + let old_handler = match old_hit { + Some(s) => if s.1 < num_interrupts-1 && s.1 < marks.len()-1 { + Some(marks[s.1+1]) + } else {None}, + None => None + }; + // find reachable alternatives + let alternatives : Vec<_> = marks.iter().filter(|x| + ( + x.0.start_tick < (lb as u64) && (lb as u64) < x.0.end_tick + || x.0.start_tick < (ub as u64) && (ub as u64) < x.0.end_tick ) + ).collect(); + // in cases there are no alternatives + if alternatives.len() == 0 { + if old_hit.is_none() { + // choose something random + let untouched : Vec<_> = marks.iter().filter( + |x| x.2 == 0 + ).collect(); + let tmp = interrupt_offsets[i]; + let choice = myrand.choose(untouched); + interrupt_offsets[i] = myrand.between(choice.0.start_tick, choice.0.end_tick) + .try_into().expect("tick > u32"); + // println!("no alternatives, choose random i: {} {} -> {}",i,tmp,interrupt_offsets[i]); + continue; + } else { + // do nothing + // println!("no alternatives, do nothing i: {} {}",i,interrupt_offsets[i]); + continue; + } + } + let replacement = myrand.choose(alternatives); + if (old_hit.map_or(false, |x| x == replacement)) { + // use the old value + // println!("chose old value, do nothing i: {} {}",i,interrupt_offsets[i]); + continue; + } else { + let extra = if (old_hit.map_or(false, |x| x.1 < replacement.1)) { + // move futher back, respect old_handler + old_handler.map_or(0, |x| x.0.end_tick - x.0.start_tick) + } else { 0 }; + let tmp = interrupt_offsets[i]; + interrupt_offsets[i] = (myrand.between(replacement.0.start_tick, + replacement.0.end_tick) + extra).try_into().expect("ticks > u32"); + // println!("chose new alternative, i: {} {} -> {}",i,tmp, interrupt_offsets[i]); + } } + // println!("Mutator: {:?}", interrupt_offsets[0..num_interrupts].to_vec()); + let mut numbers : Vec = interrupt_offsets[0..num_interrupts].to_vec(); numbers.sort(); let mut start : u32 = 0; for i in 0..numbers.len() { @@ -140,7 +194,6 @@ where for i in 0..numbers.len() { prefix.push(u32::to_le_bytes(numbers[i])); } - suffix = target_bytes[4*num_interrupts..].to_vec(); } // #[cfg(feature = "sched_state")] // {