From ffedc1fd41678995de184317f47e8bb442aa7c16 Mon Sep 17 00:00:00 2001 From: Alwin Berger Date: Thu, 23 May 2024 10:28:34 +0200 Subject: [PATCH] revert changes to interrupt injection --- fuzzers/FRET/src/fuzzer.rs | 19 +++- fuzzers/FRET/src/mutational.rs | 166 ++++++++++++++++++--------------- 2 files changed, 104 insertions(+), 81 deletions(-) diff --git a/fuzzers/FRET/src/fuzzer.rs b/fuzzers/FRET/src/fuzzer.rs index 662ce1c128..408e06ad94 100644 --- a/fuzzers/FRET/src/fuzzer.rs +++ b/fuzzers/FRET/src/fuzzer.rs @@ -439,11 +439,22 @@ pub fn fuzz() { unsafe { #[cfg(feature = "fuzz_int")] { - let times = input_bytes_to_interrupt_times(buf); - for (i,t) in times.iter().enumerate() { - libafl_interrupt_offsets[i] = *t; + let mut start_tick : u32 = 0; + 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]; + } + if i == 0 || true { + unsafe {start_tick = max(u32::from_le_bytes(t) % LIMIT, FIRST_INT);} + } else { + start_tick = u32::saturating_add(start_tick,max(unsafe{MINIMUM_INTER_ARRIVAL_TIME},u32::from_le_bytes(t))); + } + libafl_interrupt_offsets[i] = start_tick; + libafl_num_interrupts = i+1; + } } - libafl_num_interrupts = times.len(); if buf.len() > libafl_num_interrupts*4 { buf = &buf[libafl_num_interrupts*4..]; diff --git a/fuzzers/FRET/src/mutational.rs b/fuzzers/FRET/src/mutational.rs index 1fce4b401d..c5b601accc 100644 --- a/fuzzers/FRET/src/mutational.rs +++ b/fuzzers/FRET/src/mutational.rs @@ -91,7 +91,7 @@ where .borrow_mut().clone(); let mut newinput = _input.input_mut().as_mut().unwrap().clone(); let mut do_rerun = false; - if state.rand_mut().between(1, 100) <= 50 // only attempt the mutation half of the time + // if state.rand_mut().between(1, 100) <= 50 // only attempt the mutation half of the time { // need our own random generator, because borrowing rules let mut myrand = StdRand::new(); @@ -107,11 +107,22 @@ where let mut interrupt_offsets : [u32; 32] = [u32::MAX; 32]; let mut num_interrupts : usize = 0; { - let times = input_bytes_to_interrupt_times(&target_bytes); - for (i,t) in times.iter().enumerate() { - interrupt_offsets[i] = *t; + let mut start_tick : u32 = 0; + for i in 0..DO_NUM_INTERRUPT { + let mut t : [u8; 4] = [0,0,0,0]; + if target_bytes.len() > (i+1)*4 { + for j in 0 as usize..4 as usize { + t[j]=target_bytes[i*4+j]; + } + if i == 0 || true { + start_tick = max(u32::from_le_bytes(t),FIRST_INT); + } else { + start_tick = u32::saturating_add(start_tick,max(unsafe{MINIMUM_INTER_ARRIVAL_TIME},u32::from_le_bytes(t))); + } + interrupt_offsets[i] = start_tick; + num_interrupts = i+1; + } } - num_interrupts = times.len(); } interrupt_offsets.sort_unstable(); @@ -126,83 +137,84 @@ where let hist = metadata.get::().unwrap(); let maxtick : u64 = hist.1.0; drop(hist); - if interrupt_offsets[0] as u64 > maxtick { + if interrupt_offsets[0] as u64 > maxtick { // place interrupt in reachable range do_rerun = true; for _ in 0..num_interrupts { prefix.push(u32::to_le_bytes(myrand.between(0, min(maxtick, u32::MAX as u64)).try_into().expect("ticks > u32"))); } } else { - let choice = myrand.between(1,100); - if choice <= 25 { // 0.5*0.25 = 12.5% of the time fully randomize all interrupts - do_rerun = true; - // let metadata = state.metadata_map(); - let hist = metadata.get::().unwrap(); - let maxtick : u64 = hist.1.0; - // let maxtick : u64 = (_input.exec_time().expect("No duration found").as_nanos() >> 4).try_into().unwrap(); - let mut numbers : Vec = vec![]; - for i in 0..num_interrupts { - prefix.push(u32::to_le_bytes(myrand.between(0, min(maxtick, u32::MAX as u64)).try_into().expect("ticks > u32"))); - } - } - else if choice <= 75 { // 0.5 * 0.25 = 12.5% of cases - let feedbackstate = match state - .named_metadata_map_mut() - .get_mut::("stgfeedbackstate") { - Some(s) => s, - None => { - panic!("STGfeedbackstate not visible") - } - }; - let tmp = _input.metadata_map().get::(); - if tmp.is_some() { - let trace = tmp.expect("STGNodeMetadata not found"); - let mut node_indices = vec![]; - for i in (0..trace.intervals.len()).into_iter() { - if let Some(abb) = &trace.intervals[i].abb { - if let Some(idx) = feedbackstate.state_abb_hash_index.get(&(abb.get_hash(), trace.intervals[i].start_state)) { - node_indices.push(Some(idx)); - continue; - } - } - node_indices.push(None); - } - // let mut marks : HashMap= HashMap::new(); // interrupt -> block hit - // for i in 0..trace.intervals.len() { - // let curr = &trace.intervals[i]; - // let m = interrupt_offsets[0..num_interrupts].iter().filter(|x| (curr.start_tick..curr.end_tick).contains(&((**x) as u64))); - // for k in m { - // marks.insert(*k,i); - // } - // } - // walk backwards trough the trace and try moving the interrupt to a block that does not have an outgoing interrupt edge or ist already hit by a predecessor - for i in (0..num_interrupts).rev() { - let mut lb = FIRST_INT; - let mut ub : u32 = trace.intervals[trace.intervals.len()-1].end_tick.try_into().expect("ticks > u32"); - if i > 0 { - lb = u32::saturating_add(interrupt_offsets[i-1],unsafe{MINIMUM_INTER_ARRIVAL_TIME}); - } - if i < num_interrupts-1 { - ub = u32::saturating_sub(interrupt_offsets[i+1],unsafe{MINIMUM_INTER_ARRIVAL_TIME}); - } - let alternatives : Vec<_> = (0..trace.intervals.len()).filter(|x| - node_indices[*x].is_some() && - (trace.intervals[*x].start_tick < (lb as u64) && (lb as u64) < trace.intervals[*x].end_tick - || trace.intervals[*x].start_tick > (lb as u64) && trace.intervals[*x].start_tick < (ub as u64)) - ).collect(); - let not_yet_hit : Vec<_> = alternatives.iter().filter( - |x| feedbackstate.graph.edges_directed(*node_indices[**x].unwrap(), petgraph::Direction::Outgoing).any(|y| y.weight().event != CaptureEvent::ISRStart)).collect(); - if not_yet_hit.len() > 0 { - let replacement = &trace.intervals[*myrand.choose(not_yet_hit)]; - interrupt_offsets[i] = (myrand.between(replacement.start_tick, - replacement.end_tick)).try_into().expect("ticks > u32"); - // println!("chose new alternative, i: {} {} -> {}",i,tmp, interrupt_offsets[i]); - do_rerun = true; - break; - } - } - } - } - else { // old version of the alternative search + // let choice = myrand.between(1,100); + // if choice <= 25 { // 0.5*0.25 = 12.5% of the time fully randomize all interrupts + // do_rerun = true; + // // let metadata = state.metadata_map(); + // let hist = metadata.get::().unwrap(); + // let maxtick : u64 = hist.1.0; + // // let maxtick : u64 = (_input.exec_time().expect("No duration found").as_nanos() >> 4).try_into().unwrap(); + // let mut numbers : Vec = vec![]; + // for i in 0..num_interrupts { + // prefix.push(u32::to_le_bytes(myrand.between(0, min(maxtick, u32::MAX as u64)).try_into().expect("ticks > u32"))); + // } + // } + // else if choice <= 75 { // 0.5 * 0.25 = 12.5% of cases + // let feedbackstate = match state + // .named_metadata_map_mut() + // .get_mut::("stgfeedbackstate") { + // Some(s) => s, + // None => { + // panic!("STGfeedbackstate not visible") + // } + // }; + // let tmp = _input.metadata_map().get::(); + // if tmp.is_some() { + // let trace = tmp.expect("STGNodeMetadata not found"); + // let mut node_indices = vec![]; + // for i in (0..trace.intervals.len()).into_iter() { + // if let Some(abb) = &trace.intervals[i].abb { + // if let Some(idx) = feedbackstate.state_abb_hash_index.get(&(abb.get_hash(), trace.intervals[i].start_state)) { + // node_indices.push(Some(idx)); + // continue; + // } + // } + // node_indices.push(None); + // } + // // let mut marks : HashMap= HashMap::new(); // interrupt -> block hit + // // for i in 0..trace.intervals.len() { + // // let curr = &trace.intervals[i]; + // // let m = interrupt_offsets[0..num_interrupts].iter().filter(|x| (curr.start_tick..curr.end_tick).contains(&((**x) as u64))); + // // for k in m { + // // marks.insert(*k,i); + // // } + // // } + // // walk backwards trough the trace and try moving the interrupt to a block that does not have an outgoing interrupt edge or ist already hit by a predecessor + // for i in (0..num_interrupts).rev() { + // let mut lb = FIRST_INT; + // let mut ub : u32 = trace.intervals[trace.intervals.len()-1].end_tick.try_into().expect("ticks > u32"); + // if i > 0 { + // lb = u32::saturating_add(interrupt_offsets[i-1],unsafe{MINIMUM_INTER_ARRIVAL_TIME}); + // } + // if i < num_interrupts-1 { + // ub = u32::saturating_sub(interrupt_offsets[i+1],unsafe{MINIMUM_INTER_ARRIVAL_TIME}); + // } + // let alternatives : Vec<_> = (0..trace.intervals.len()).filter(|x| + // node_indices[*x].is_some() && + // (trace.intervals[*x].start_tick < (lb as u64) && (lb as u64) < trace.intervals[*x].end_tick + // || trace.intervals[*x].start_tick > (lb as u64) && trace.intervals[*x].start_tick < (ub as u64)) + // ).collect(); + // let not_yet_hit : Vec<_> = alternatives.iter().filter( + // |x| feedbackstate.graph.edges_directed(*node_indices[**x].unwrap(), petgraph::Direction::Outgoing).any(|y| y.weight().event != CaptureEvent::ISRStart)).collect(); + // if not_yet_hit.len() > 0 { + // let replacement = &trace.intervals[*myrand.choose(not_yet_hit)]; + // interrupt_offsets[i] = (myrand.between(replacement.start_tick, + // replacement.end_tick)).try_into().expect("ticks > u32"); + // // println!("chose new alternative, i: {} {} -> {}",i,tmp, interrupt_offsets[i]); + // do_rerun = true; + // break; + // } + // } + // } + // } + // else { // old version of the alternative search + { let tmp = _input.metadata_map().get::(); if tmp.is_some() { let trace = tmp.expect("STGNodeMetadata not found");