From b85e0a6d5b1ec1826d81a9f012ef109598412888 Mon Sep 17 00:00:00 2001 From: Alwin Berger Date: Wed, 16 Feb 2022 23:36:23 +0100 Subject: [PATCH] parse raw freertos system state --- fuzzers/wcet_qemu_sys/src/freertos.rs | 3 +- fuzzers/wcet_qemu_sys/src/system_trace.rs | 103 +++++++++++++++++++--- 2 files changed, 93 insertions(+), 13 deletions(-) diff --git a/fuzzers/wcet_qemu_sys/src/freertos.rs b/fuzzers/wcet_qemu_sys/src/freertos.rs index aeeb2d51ba..2b22eb6cb0 100644 --- a/fuzzers/wcet_qemu_sys/src/freertos.rs +++ b/fuzzers/wcet_qemu_sys/src/freertos.rs @@ -118,4 +118,5 @@ impl_emu_lookup!(TCB_t); impl_emu_lookup!(List_t); impl_emu_lookup!(ListItem_t); impl_emu_lookup!(MiniListItem_t); -impl_emu_lookup!(void_ptr); \ No newline at end of file +impl_emu_lookup!(void_ptr); +impl_emu_lookup!(TaskStatus_t); diff --git a/fuzzers/wcet_qemu_sys/src/system_trace.rs b/fuzzers/wcet_qemu_sys/src/system_trace.rs index 0b8d6d4de6..041ed78208 100644 --- a/fuzzers/wcet_qemu_sys/src/system_trace.rs +++ b/fuzzers/wcet_qemu_sys/src/system_trace.rs @@ -1,3 +1,6 @@ +use crate::freertos::emu_lookup; +use crate::freertos::rtos_struct; +use crate::freertos::List_t; use crate::freertos::TCB_t; use crate::freertos::rtos_struct::List_Item_struct; use libafl::events::EventFirer; @@ -34,16 +37,40 @@ pub struct FreeRTOSSystemStateRaw { dumping_ground: HashMap, } +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct MiniTCB { + task_name: String, + priority: u32, + base_priority: u32, + mutexes_held: u32, + notify_value: u32, + notify_state: u8, +} + +impl MiniTCB { + pub fn from_tcb(input: &TCB_t) -> Self { + unsafe { + let tmp = std::mem::transmute::<[i8; 10],[u8; 10]>(input.pcTaskName); + let name : String = std::str::from_utf8(&tmp).expect("TCB name was not utf8").chars().filter(|x| *x != '\0').collect::(); + Self { + task_name: name, + priority: input.uxPriority, + base_priority: input.uxBasePriority, + mutexes_held: input.uxMutexesHeld, + notify_value: input.ulNotifiedValue[0], + notify_state: input.ucNotifyState[0], + } + } + } +} + /// Refined information about the states an execution transitioned between #[derive(Debug, Default, Serialize, Deserialize)] pub struct QemuSystemStateMetadata { -} - -impl QemuSystemStateMetadata { - #[must_use] - pub fn new() -> Self { - Self {} - } + start_tick: u64, + end_tick: u64, + current_task: MiniTCB, + ready_list_after: Vec, } libafl::impl_serdeany!(QemuSystemStateMetadata); @@ -122,7 +149,7 @@ where // println!("{:?}",std::str::from_utf8(¤t_tcb.pcTaskName)); for i in 0..NUM_PRIOS { - let mut target : u32 = LISTBYTES*u32::try_from(i).unwrap()+h.ready_queues; + let target : u32 = LISTBYTES*u32::try_from(i).unwrap()+h.ready_queues; sysstate.prio_ready_lists[i] = freertos::emu_lookup::lookup(emulator, target); // println!("List at {}: {:?}",target, sysstate.prio_ready_lists[i]); let mut next_index = sysstate.prio_ready_lists[i].pxIndex; @@ -144,15 +171,16 @@ where sysstate.dumping_ground.insert(next_index,List_Item_struct(next_item)); next_index=new_next_index; } + // Handle edge case where the end marker was not included yet + if (target..target+LISTBYTES).contains(&next_index) { + let next_item : freertos::MiniListItem_t = freertos::emu_lookup::lookup(emulator, next_index); + sysstate.dumping_ground.insert(next_index,List_MiniItem_struct(next_item)); + } } unsafe { CURRENT_SYSSTATE_VEC.push(sysstate); } } -extern "C" fn test_gen_hook(pc: u64) -> u64 { - u32::MAX as u64 -} - pub fn gen_not_exec_block_hook( _emulator: &Emulator, helpers: &mut QT, @@ -193,6 +221,7 @@ impl Observer for QemuSysStateObserver #[inline] fn post_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> { unsafe {self.last_run.append(&mut CURRENT_SYSSTATE_VEC);} + println!("{:#?}",self.parse_last()); Ok(()) } } @@ -217,8 +246,58 @@ impl QemuSysStateObserver { pub fn new() -> Self { Self{last_run: vec![], name: "sysstate".to_string()} } + + pub fn parse_last(&self) -> Vec { + let mut ret = Vec::::new(); + let mut start_tick : u64 = 0; + for i in 0..self.last_run.len() { + let mut collector = Vec::::new(); + for j in self.last_run[i].prio_ready_lists.iter().rev() { + let mut tmp = list_to_tcb_vec(j,&self.last_run[i].dumping_ground).iter().map(|x| MiniTCB::from_tcb(x)).collect(); + collector.append(&mut tmp); + } + ret.push(QemuSystemStateMetadata { + current_task: MiniTCB::from_tcb(&self.last_run[i].current_tcb), + start_tick: start_tick, + end_tick: self.last_run[i].qemu_tick, + ready_list_after: collector, + }); + start_tick=self.last_run[i].qemu_tick; + } + return ret; + } } +pub fn list_to_tcb_vec(list: &List_t, dump: &HashMap) -> Vec +{ + let mut ret : Vec = Vec::new(); + if list.uxNumberOfItems == 0 {return ret;} + let first_list_index = match dump.get(&list.pxIndex).expect("List_t entry was not in Hashmap") { + List_Item_struct(li) => li.pxNext, + List_MiniItem_struct(mli) => match dump.get(&mli.pxNext).expect("MiniListItem pointer invaild") { + List_Item_struct(li) => li.pxNext, + _ => panic!("MiniListItem of a non empty List does not point to ListItem"), + }, + _ => panic!("List_t entry was not a ListItem"), + }; + let mut next_index = first_list_index; + for _ in 0..list.uxNumberOfItems { + let next_list_item = match dump.get(&next_index).expect("List_t entry was not in Hashmap") { + List_Item_struct(li) => li, + List_MiniItem_struct(mli) => match dump.get(&mli.pxNext).expect("MiniListItem pointer invaild") { + List_Item_struct(li) => li, + _ => panic!("MiniListItem of a non empty List does not point to ListItem"), + }, + _ => panic!("List_t entry was not a ListItem"), + }; + match dump.get(&next_list_item.pvOwner).expect("ListItem Owner not in Hashmap") { + TCB_struct(t) => {ret.push(*t)}, + _ => panic!("List content does not equal type"), + } + next_index=next_list_item.pxNext; + } + ret +} //============================= Feedback /// A Feedback reporting interesting System-State Transitions