clean trace from ISRs without effect, prevent race-conditions
This commit is contained in:
parent
6793d48dbd
commit
7e79f4051d
@ -335,6 +335,8 @@ pub fn fuzz() {
|
||||
let task_queue_addr = load_symbol(&elf, "pxReadyTasksLists", false);
|
||||
let task_delay_addr = load_symbol(&elf, "pxDelayedTaskList", false);
|
||||
let task_delay_overflow_addr = load_symbol(&elf, "pxOverflowDelayedTaskList", false);
|
||||
let scheduler_lock = load_symbol(&elf, "uxSchedulerSuspended", false);
|
||||
let critical_section = load_symbol(&elf, "uxCriticalNesting", false);
|
||||
// let task_queue_addr = virt2phys(task_queue_addr,&elf.goblin());
|
||||
#[cfg(feature = "systemstate")]
|
||||
println!("Task Queue at {:#x}", task_queue_addr);
|
||||
@ -589,7 +591,7 @@ pub fn fuzz() {
|
||||
let qhelpers = tuple_list!(
|
||||
QemuEdgeCoverageHelper::default(),
|
||||
QemuStateRestoreHelper::new(),
|
||||
QemuSystemStateHelper::new(api_addreses,api_ranges,isr_addreses,isr_ranges,curr_tcb_pointer,task_queue_addr,task_delay_addr,task_delay_overflow_addr,input_counter_ptr,app_range.clone())
|
||||
QemuSystemStateHelper::new(api_addreses,api_ranges,isr_addreses,isr_ranges,curr_tcb_pointer,task_queue_addr,task_delay_addr,task_delay_overflow_addr,scheduler_lock, critical_section,input_counter_ptr,app_range.clone())
|
||||
);
|
||||
let mut hooks = QemuHooks::new(emu.clone(),qhelpers);
|
||||
|
||||
|
@ -17,6 +17,7 @@ use crate::systemstate::extract_abbs_from_trace;
|
||||
use crate::systemstate::RawFreeRTOSSystemState;
|
||||
use crate::systemstate::CURRENT_SYSTEMSTATE_VEC;
|
||||
use crate::systemstate::NUM_PRIOS;
|
||||
use super::freertos::void_ptr;
|
||||
use super::freertos::TCB_t;
|
||||
use super::freertos::rtos_struct::List_Item_struct;
|
||||
use super::freertos::rtos_struct::*;
|
||||
@ -92,6 +93,8 @@ pub struct QemuSystemStateHelper {
|
||||
ready_queues: GuestAddr,
|
||||
delay_queue: GuestAddr,
|
||||
delay_queue_overflow: GuestAddr,
|
||||
scheduler_lock_addr: GuestAddr,
|
||||
critical_addr: GuestAddr,
|
||||
input_counter: Option<GuestAddr>,
|
||||
app_range: Range<GuestAddr>,
|
||||
}
|
||||
@ -107,6 +110,8 @@ impl QemuSystemStateHelper {
|
||||
ready_queues: GuestAddr,
|
||||
delay_queue: GuestAddr,
|
||||
delay_queue_overflow: GuestAddr,
|
||||
scheduler_lock_addr: GuestAddr,
|
||||
critical_addr: GuestAddr,
|
||||
input_counter: Option<GuestAddr>,
|
||||
app_range: Range<GuestAddr>,
|
||||
) -> Self {
|
||||
@ -119,6 +124,8 @@ impl QemuSystemStateHelper {
|
||||
ready_queues: ready_queues,
|
||||
delay_queue,
|
||||
delay_queue_overflow,
|
||||
scheduler_lock_addr,
|
||||
critical_addr,
|
||||
input_counter: input_counter,
|
||||
app_range,
|
||||
}
|
||||
@ -156,7 +163,7 @@ where
|
||||
trigger_collection(emulator,(None, None), self);
|
||||
unsafe {
|
||||
let c = emulator.cpu_from_index(0);
|
||||
let pc = c.read_reg::<i32, u32>(15).unwrap();;
|
||||
let pc = c.read_reg::<i32, u32>(15).unwrap();
|
||||
CURRENT_SYSTEMSTATE_VEC[CURRENT_SYSTEMSTATE_VEC.len()-1].edge = (Some(pc),None);
|
||||
CURRENT_SYSTEMSTATE_VEC[CURRENT_SYSTEMSTATE_VEC.len()-1].capture_point = (CaptureEvent::End,"Breakpoint");
|
||||
}
|
||||
@ -173,7 +180,7 @@ where
|
||||
}
|
||||
unsafe {
|
||||
let abbs = extract_abbs_from_trace(&CURRENT_SYSTEMSTATE_VEC);
|
||||
println!("{:?}", abbs);
|
||||
//println!("{:?}", abbs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -213,44 +220,6 @@ fn read_freertos_list(systemstate : &mut RawFreeRTOSSystemState, emulator: &Emul
|
||||
fn trigger_collection(emulator: &Emulator, edge: (Option<GuestAddr>,Option<GuestAddr>), h: &QemuSystemStateHelper) {
|
||||
let listbytes : GuestAddr = GuestAddr::try_from(std::mem::size_of::<freertos::List_t>()).unwrap();
|
||||
let mut systemstate = RawFreeRTOSSystemState::default();
|
||||
unsafe {
|
||||
// TODO: investigate why can_do_io is not set sometimes, as this is just a workaround
|
||||
let c = emulator.cpu_from_index(0);
|
||||
let can_do_io = (*c.raw_ptr()).neg.can_do_io;
|
||||
(*c.raw_ptr()).neg.can_do_io = true;
|
||||
systemstate.qemu_tick = emu::icount_get_raw();
|
||||
(*c.raw_ptr()).neg.can_do_io = can_do_io;
|
||||
}
|
||||
let mut buf : [u8; 4] = [0,0,0,0];
|
||||
match h.input_counter {
|
||||
Some(s) => unsafe { emulator.read_mem(s, &mut buf); },
|
||||
None => (),
|
||||
};
|
||||
systemstate.input_counter = GuestAddr::from_le_bytes(buf);
|
||||
|
||||
let curr_tcb_addr : freertos::void_ptr = freertos::emu_lookup::lookup(emulator, h.tcb_addr);
|
||||
if curr_tcb_addr == 0 {
|
||||
return;
|
||||
};
|
||||
systemstate.current_tcb = freertos::emu_lookup::lookup(emulator,curr_tcb_addr);
|
||||
|
||||
// println!("{:?}",std::str::from_utf8(¤t_tcb.pcTaskName));
|
||||
|
||||
// Extract delay list
|
||||
let mut target : GuestAddr = h.delay_queue;
|
||||
target = freertos::emu_lookup::lookup(emulator, target);
|
||||
systemstate.delay_list = read_freertos_list(&mut systemstate, emulator, target);
|
||||
|
||||
// Extract delay list overflow
|
||||
let mut target : GuestAddr = h.delay_queue_overflow;
|
||||
target = freertos::emu_lookup::lookup(emulator, target);
|
||||
systemstate.delay_list_overflow = read_freertos_list(&mut systemstate, emulator, target);
|
||||
|
||||
// Extract priority lists
|
||||
for i in 0..NUM_PRIOS {
|
||||
let target : GuestAddr = listbytes*GuestAddr::try_from(i).unwrap()+h.ready_queues;
|
||||
systemstate.prio_ready_lists[i] = read_freertos_list(&mut systemstate, emulator, target);
|
||||
}
|
||||
|
||||
// Note type of capture
|
||||
match edge.1 {
|
||||
@ -284,10 +253,57 @@ fn trigger_collection(emulator: &Emulator, edge: (Option<GuestAddr>,Option<Guest
|
||||
},
|
||||
}
|
||||
if systemstate.capture_point.0 == CaptureEvent::Undefined {
|
||||
println!("Not found: {:#x} {:#x}", edge.0.unwrap_or(0), edge.1.unwrap_or(0));
|
||||
// println!("Not found: {:#x} {:#x}", edge.0.unwrap_or(0), edge.1.unwrap_or(0));
|
||||
}
|
||||
systemstate.edge = edge;
|
||||
|
||||
|
||||
unsafe {
|
||||
// TODO: investigate why can_do_io is not set sometimes, as this is just a workaround
|
||||
let c = emulator.cpu_from_index(0);
|
||||
let can_do_io = (*c.raw_ptr()).neg.can_do_io;
|
||||
(*c.raw_ptr()).neg.can_do_io = true;
|
||||
systemstate.qemu_tick = emu::icount_get_raw();
|
||||
(*c.raw_ptr()).neg.can_do_io = can_do_io;
|
||||
}
|
||||
let mut buf : [u8; 4] = [0,0,0,0];
|
||||
match h.input_counter {
|
||||
Some(s) => unsafe { emulator.read_mem(s, &mut buf); },
|
||||
None => (),
|
||||
};
|
||||
systemstate.input_counter = GuestAddr::from_le_bytes(buf);
|
||||
|
||||
let curr_tcb_addr : freertos::void_ptr = freertos::emu_lookup::lookup(emulator, h.tcb_addr);
|
||||
if curr_tcb_addr == 0 {
|
||||
return;
|
||||
};
|
||||
|
||||
// println!("{:?}",std::str::from_utf8(¤t_tcb.pcTaskName));
|
||||
let critical : void_ptr = freertos::emu_lookup::lookup(emulator, h.critical_addr);
|
||||
let suspended : void_ptr = freertos::emu_lookup::lookup(emulator, h.scheduler_lock_addr);
|
||||
|
||||
// During ISRs it is only safe to extract structs if they are not currently being modified
|
||||
if (systemstate.capture_point.0==CaptureEvent::ISRStart || systemstate.capture_point.0==CaptureEvent::ISREnd) && critical == 0 && suspended == 0 {
|
||||
systemstate.current_tcb = freertos::emu_lookup::lookup(emulator,curr_tcb_addr);
|
||||
// Extract delay list
|
||||
let mut target : GuestAddr = h.delay_queue;
|
||||
target = freertos::emu_lookup::lookup(emulator, target);
|
||||
systemstate.delay_list = read_freertos_list(&mut systemstate, emulator, target);
|
||||
|
||||
// Extract delay list overflow
|
||||
let mut target : GuestAddr = h.delay_queue_overflow;
|
||||
target = freertos::emu_lookup::lookup(emulator, target);
|
||||
systemstate.delay_list_overflow = read_freertos_list(&mut systemstate, emulator, target);
|
||||
|
||||
// Extract priority lists
|
||||
for i in 0..NUM_PRIOS {
|
||||
let target : GuestAddr = listbytes*GuestAddr::try_from(i).unwrap()+h.ready_queues;
|
||||
systemstate.prio_ready_lists[i] = read_freertos_list(&mut systemstate, emulator, target);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsafe { CURRENT_SYSTEMSTATE_VEC.push(systemstate); }
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,8 @@ impl PartialEq for RefinedFreeRTOSSystemState {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.current_task == other.current_task && self.ready_list_after == other.ready_list_after &&
|
||||
self.delay_list_after == other.delay_list_after
|
||||
// && self.last_pc == other.last_pc
|
||||
// && self.edge == other.edge
|
||||
// && self.capture_point == other.capture_point
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ use libafl::Error;
|
||||
use libafl::observers::Observer;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use hashbrown::HashMap;
|
||||
use crate::systemstate::CaptureEvent;
|
||||
|
||||
use super::{
|
||||
CURRENT_SYSTEMSTATE_VEC,
|
||||
@ -43,7 +44,7 @@ where
|
||||
|
||||
#[inline]
|
||||
fn post_exec(&mut self, _state: &mut S, _input: &S::Input, _exit_kind: &ExitKind) -> Result<(), Error> {
|
||||
unsafe {self.last_run = refine_system_states(&mut CURRENT_SYSTEMSTATE_VEC);}
|
||||
unsafe {self.last_run = post_process_trace(refine_system_states(&mut CURRENT_SYSTEMSTATE_VEC));}
|
||||
self.last_input=_input.target_bytes().as_slice().to_owned();
|
||||
Ok(())
|
||||
}
|
||||
@ -168,4 +169,25 @@ fn refine_system_states(input: &mut Vec<RawFreeRTOSSystemState>) -> Vec<RefinedF
|
||||
start_tick=i.qemu_tick;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
fn post_process_trace(mut trace: Vec<RefinedFreeRTOSSystemState>) -> Vec<RefinedFreeRTOSSystemState> {
|
||||
// remove subsequent pairs of equal states where an ISRStart follows an ISREnd
|
||||
let mut i = 1;
|
||||
while i < trace.len() - 1 {
|
||||
if trace[i] == trace[i + 1] &&
|
||||
matches!(trace[i].capture_point.0, CaptureEvent::ISRStart) &&
|
||||
matches!(trace[i + 1].capture_point.0, CaptureEvent::ISREnd) &&
|
||||
trace[i].capture_point.1 == trace[i + 1].capture_point.1
|
||||
{
|
||||
// extend the end of the last ABB until the end of the next one
|
||||
trace[i-1].end_tick = trace[i+1].end_tick;
|
||||
|
||||
trace.remove(i + 1);
|
||||
trace.remove(i);
|
||||
} else {
|
||||
i+=1;
|
||||
}
|
||||
}
|
||||
trace
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user