revert changes to interrupt injection

This commit is contained in:
Alwin Berger 2024-05-23 10:28:34 +02:00
parent 7701fff969
commit ffedc1fd41
2 changed files with 104 additions and 81 deletions

View File

@ -439,11 +439,22 @@ pub fn fuzz() {
unsafe { unsafe {
#[cfg(feature = "fuzz_int")] #[cfg(feature = "fuzz_int")]
{ {
let times = input_bytes_to_interrupt_times(buf); let mut start_tick : u32 = 0;
for (i,t) in times.iter().enumerate() { for i in 0..DO_NUM_INTERRUPT {
libafl_interrupt_offsets[i] = *t; 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 { if buf.len() > libafl_num_interrupts*4 {
buf = &buf[libafl_num_interrupts*4..]; buf = &buf[libafl_num_interrupts*4..];

View File

@ -91,7 +91,7 @@ where
.borrow_mut().clone(); .borrow_mut().clone();
let mut newinput = _input.input_mut().as_mut().unwrap().clone(); let mut newinput = _input.input_mut().as_mut().unwrap().clone();
let mut do_rerun = false; 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 // need our own random generator, because borrowing rules
let mut myrand = StdRand::new(); let mut myrand = StdRand::new();
@ -107,11 +107,22 @@ where
let mut interrupt_offsets : [u32; 32] = [u32::MAX; 32]; let mut interrupt_offsets : [u32; 32] = [u32::MAX; 32];
let mut num_interrupts : usize = 0; let mut num_interrupts : usize = 0;
{ {
let times = input_bytes_to_interrupt_times(&target_bytes); let mut start_tick : u32 = 0;
for (i,t) in times.iter().enumerate() { for i in 0..DO_NUM_INTERRUPT {
interrupt_offsets[i] = *t; 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(); interrupt_offsets.sort_unstable();
@ -126,83 +137,84 @@ where
let hist = metadata.get::<IcHist>().unwrap(); let hist = metadata.get::<IcHist>().unwrap();
let maxtick : u64 = hist.1.0; let maxtick : u64 = hist.1.0;
drop(hist); drop(hist);
if interrupt_offsets[0] as u64 > maxtick { if interrupt_offsets[0] as u64 > maxtick { // place interrupt in reachable range
do_rerun = true; do_rerun = true;
for _ in 0..num_interrupts { 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"))); prefix.push(u32::to_le_bytes(myrand.between(0, min(maxtick, u32::MAX as u64)).try_into().expect("ticks > u32")));
} }
} else { } else {
let choice = myrand.between(1,100); // let choice = myrand.between(1,100);
if choice <= 25 { // 0.5*0.25 = 12.5% of the time fully randomize all interrupts // if choice <= 25 { // 0.5*0.25 = 12.5% of the time fully randomize all interrupts
do_rerun = true; // do_rerun = true;
// let metadata = state.metadata_map(); // // let metadata = state.metadata_map();
let hist = metadata.get::<IcHist>().unwrap(); // let hist = metadata.get::<IcHist>().unwrap();
let maxtick : u64 = hist.1.0; // let maxtick : u64 = hist.1.0;
// let maxtick : u64 = (_input.exec_time().expect("No duration found").as_nanos() >> 4).try_into().unwrap(); // // let maxtick : u64 = (_input.exec_time().expect("No duration found").as_nanos() >> 4).try_into().unwrap();
let mut numbers : Vec<u32> = vec![]; // let mut numbers : Vec<u32> = vec![];
for i in 0..num_interrupts { // 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"))); // 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 // else if choice <= 75 { // 0.5 * 0.25 = 12.5% of cases
let feedbackstate = match state // let feedbackstate = match state
.named_metadata_map_mut() // .named_metadata_map_mut()
.get_mut::<STGFeedbackState>("stgfeedbackstate") { // .get_mut::<STGFeedbackState>("stgfeedbackstate") {
Some(s) => s, // Some(s) => s,
None => { // None => {
panic!("STGfeedbackstate not visible") // panic!("STGfeedbackstate not visible")
} // }
}; // };
let tmp = _input.metadata_map().get::<STGNodeMetadata>(); // let tmp = _input.metadata_map().get::<STGNodeMetadata>();
if tmp.is_some() { // if tmp.is_some() {
let trace = tmp.expect("STGNodeMetadata not found"); // let trace = tmp.expect("STGNodeMetadata not found");
let mut node_indices = vec![]; // let mut node_indices = vec![];
for i in (0..trace.intervals.len()).into_iter() { // for i in (0..trace.intervals.len()).into_iter() {
if let Some(abb) = &trace.intervals[i].abb { // 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)) { // if let Some(idx) = feedbackstate.state_abb_hash_index.get(&(abb.get_hash(), trace.intervals[i].start_state)) {
node_indices.push(Some(idx)); // node_indices.push(Some(idx));
continue; // continue;
} // }
} // }
node_indices.push(None); // node_indices.push(None);
} // }
// let mut marks : HashMap<u32, usize>= HashMap::new(); // interrupt -> block hit // // let mut marks : HashMap<u32, usize>= HashMap::new(); // interrupt -> block hit
// for i in 0..trace.intervals.len() { // // for i in 0..trace.intervals.len() {
// let curr = &trace.intervals[i]; // // 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))); // // let m = interrupt_offsets[0..num_interrupts].iter().filter(|x| (curr.start_tick..curr.end_tick).contains(&((**x) as u64)));
// for k in m { // // for k in m {
// marks.insert(*k,i); // // 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 // // 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() { // for i in (0..num_interrupts).rev() {
let mut lb = FIRST_INT; // let mut lb = FIRST_INT;
let mut ub : u32 = trace.intervals[trace.intervals.len()-1].end_tick.try_into().expect("ticks > u32"); // let mut ub : u32 = trace.intervals[trace.intervals.len()-1].end_tick.try_into().expect("ticks > u32");
if i > 0 { // if i > 0 {
lb = u32::saturating_add(interrupt_offsets[i-1],unsafe{MINIMUM_INTER_ARRIVAL_TIME}); // lb = u32::saturating_add(interrupt_offsets[i-1],unsafe{MINIMUM_INTER_ARRIVAL_TIME});
} // }
if i < num_interrupts-1 { // if i < num_interrupts-1 {
ub = u32::saturating_sub(interrupt_offsets[i+1],unsafe{MINIMUM_INTER_ARRIVAL_TIME}); // ub = u32::saturating_sub(interrupt_offsets[i+1],unsafe{MINIMUM_INTER_ARRIVAL_TIME});
} // }
let alternatives : Vec<_> = (0..trace.intervals.len()).filter(|x| // let alternatives : Vec<_> = (0..trace.intervals.len()).filter(|x|
node_indices[*x].is_some() && // 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) && (lb as u64) < trace.intervals[*x].end_tick
|| trace.intervals[*x].start_tick > (lb as u64) && trace.intervals[*x].start_tick < (ub as u64)) // || trace.intervals[*x].start_tick > (lb as u64) && trace.intervals[*x].start_tick < (ub as u64))
).collect(); // ).collect();
let not_yet_hit : Vec<_> = alternatives.iter().filter( // 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(); // |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 { // if not_yet_hit.len() > 0 {
let replacement = &trace.intervals[*myrand.choose(not_yet_hit)]; // let replacement = &trace.intervals[*myrand.choose(not_yet_hit)];
interrupt_offsets[i] = (myrand.between(replacement.start_tick, // interrupt_offsets[i] = (myrand.between(replacement.start_tick,
replacement.end_tick)).try_into().expect("ticks > u32"); // replacement.end_tick)).try_into().expect("ticks > u32");
// println!("chose new alternative, i: {} {} -> {}",i,tmp, interrupt_offsets[i]); // // println!("chose new alternative, i: {} {} -> {}",i,tmp, interrupt_offsets[i]);
do_rerun = true; // do_rerun = true;
break; // break;
} // }
} // }
} // }
} // }
else { // old version of the alternative search // else { // old version of the alternative search
{
let tmp = _input.metadata_map().get::<STGNodeMetadata>(); let tmp = _input.metadata_map().get::<STGNodeMetadata>();
if tmp.is_some() { if tmp.is_some() {
let trace = tmp.expect("STGNodeMetadata not found"); let trace = tmp.expect("STGNodeMetadata not found");