diff --git a/fuzzers/wcet_qemu_sys/src/freertos.rs b/fuzzers/wcet_qemu_sys/src/freertos.rs new file mode 100644 index 0000000000..53e290a7d2 --- /dev/null +++ b/fuzzers/wcet_qemu_sys/src/freertos.rs @@ -0,0 +1,524 @@ +/* automatically generated by rust-bindgen 0.59.2 */ + +use std::ops::Deref; + +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct __uint8_t(pub ::std::os::raw::c_uchar); +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct __uint16_t(pub ::std::os::raw::c_ushort); +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct __uint32_t(pub ::std::os::raw::c_uint); +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct StackType_t(pub u32); +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct StackType_t_ptr(pub u32); +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct UBaseType_t(pub ::std::os::raw::c_uint); +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Default)] +pub struct TickType_t(pub u32); + +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Default)] +pub struct void_ptr(pub ::std::os::raw::c_uint); + +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Default)] +pub struct xLIST_ptr(pub ::std::os::raw::c_uint); + +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Default)] +pub struct xLIST_ITEM_ptr(pub ::std::os::raw::c_uint); + +#[repr(C)] +#[derive(Debug, Copy, Clone, Default)] +pub struct xLIST_ITEM { + pub xItemValue: TickType_t, + pub pxNext: xLIST_ITEM_ptr, + pub pxPrevious: xLIST_ITEM_ptr, + pub pvOwner: void_ptr, + pub pvContainer: xLIST_ptr, +} +#[test] +fn bindgen_test_layout_xLIST_ITEM() { + assert_eq!( + ::std::mem::size_of::(), + 20usize, + concat!("Size of: ", stringify!(xLIST_ITEM)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(xLIST_ITEM)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).xItemValue as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(xLIST_ITEM), + "::", + stringify!(xItemValue) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).pxNext as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(xLIST_ITEM), + "::", + stringify!(pxNext) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).pxPrevious as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(xLIST_ITEM), + "::", + stringify!(pxPrevious) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).pvOwner as *const _ as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(xLIST_ITEM), + "::", + stringify!(pvOwner) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).pvContainer as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(xLIST_ITEM), + "::", + stringify!(pvContainer) + ) + ); +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct ListItem_t(pub xLIST_ITEM); +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct xMINI_LIST_ITEM { + pub xItemValue: TickType_t, + pub pxNext: xLIST_ITEM_ptr, + pub pxPrevious: xLIST_ITEM_ptr, +} +#[test] +fn bindgen_test_layout_xMINI_LIST_ITEM() { + assert_eq!( + ::std::mem::size_of::(), + 12usize, + concat!("Size of: ", stringify!(xMINI_LIST_ITEM)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(xMINI_LIST_ITEM)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).xItemValue as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(xMINI_LIST_ITEM), + "::", + stringify!(xItemValue) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).pxNext as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(xMINI_LIST_ITEM), + "::", + stringify!(pxNext) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).pxPrevious as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(xMINI_LIST_ITEM), + "::", + stringify!(pxPrevious) + ) + ); +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct MiniListItem_t(pub xMINI_LIST_ITEM); +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct xLIST { + pub uxNumberOfItems: UBaseType_t, + pub pxIndex: xLIST_ITEM_ptr, + pub xListEnd: MiniListItem_t, +} +#[test] +fn bindgen_test_layout_xLIST() { + assert_eq!( + ::std::mem::size_of::(), + 20usize, + concat!("Size of: ", stringify!(xLIST)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(xLIST)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).uxNumberOfItems as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(xLIST), + "::", + stringify!(uxNumberOfItems) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).pxIndex as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(xLIST), + "::", + stringify!(pxIndex) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).xListEnd as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(xLIST), + "::", + stringify!(xListEnd) + ) + ); +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct List_t(pub xLIST); +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct TaskHandle_t(pub *mut tskTaskControlBlock); +pub const eTaskState_eRunning: eTaskState = 0; +pub const eTaskState_eReady: eTaskState = 1; +pub const eTaskState_eBlocked: eTaskState = 2; +pub const eTaskState_eSuspended: eTaskState = 3; +pub const eTaskState_eDeleted: eTaskState = 4; +pub const eTaskState_eInvalid: eTaskState = 5; +pub type eTaskState = ::std::os::raw::c_uint; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct xTASK_STATUS { + pub xHandle: TaskHandle_t, + pub pcTaskName: u32, + pub xTaskNumber: UBaseType_t, + pub eCurrentState: eTaskState, + pub uxCurrentPriority: UBaseType_t, + pub uxBasePriority: UBaseType_t, + pub ulRunTimeCounter: u32, + pub pxStackBase: StackType_t_ptr, + pub usStackHighWaterMark: u16, +} +#[test] +fn bindgen_test_layout_xTASK_STATUS() { + assert_eq!( + ::std::mem::size_of::(), + 36usize, + concat!("Size of: ", stringify!(xTASK_STATUS)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(xTASK_STATUS)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).xHandle as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(xTASK_STATUS), + "::", + stringify!(xHandle) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).pcTaskName as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(xTASK_STATUS), + "::", + stringify!(pcTaskName) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).xTaskNumber as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(xTASK_STATUS), + "::", + stringify!(xTaskNumber) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).eCurrentState as *const _ as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(xTASK_STATUS), + "::", + stringify!(eCurrentState) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).uxCurrentPriority as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(xTASK_STATUS), + "::", + stringify!(uxCurrentPriority) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).uxBasePriority as *const _ as usize }, + 20usize, + concat!( + "Offset of field: ", + stringify!(xTASK_STATUS), + "::", + stringify!(uxBasePriority) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ulRunTimeCounter as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(xTASK_STATUS), + "::", + stringify!(ulRunTimeCounter) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).pxStackBase as *const _ as usize }, + 28usize, + concat!( + "Offset of field: ", + stringify!(xTASK_STATUS), + "::", + stringify!(pxStackBase) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).usStackHighWaterMark as *const _ as usize + }, + 32usize, + concat!( + "Offset of field: ", + stringify!(xTASK_STATUS), + "::", + stringify!(usStackHighWaterMark) + ) + ); +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct TaskStatus_t(pub xTASK_STATUS); +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct tskTaskControlBlock { + pub pxTopOfStack: StackType_t_ptr, + pub xStateListItem: ListItem_t, + pub xEventListItem: ListItem_t, + pub uxPriority: UBaseType_t, + pub pxStack: StackType_t_ptr, + pub pcTaskName: [::std::os::raw::c_char; 10usize], + pub uxBasePriority: UBaseType_t, + pub uxMutexesHeld: UBaseType_t, + pub ulNotifiedValue: [u32; 1usize], + pub ucNotifyState: [u8; 1usize], + pub ucStaticallyAllocated: u8, + pub ucDelayAborted: u8, +} +#[test] +fn bindgen_test_layout_tskTaskControlBlock() { + assert_eq!( + ::std::mem::size_of::(), + 80usize, + concat!("Size of: ", stringify!(tskTaskControlBlock)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(tskTaskControlBlock)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).pxTopOfStack as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(tskTaskControlBlock), + "::", + stringify!(pxTopOfStack) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).xStateListItem as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(tskTaskControlBlock), + "::", + stringify!(xStateListItem) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).xEventListItem as *const _ as usize + }, + 24usize, + concat!( + "Offset of field: ", + stringify!(tskTaskControlBlock), + "::", + stringify!(xEventListItem) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).uxPriority as *const _ as usize }, + 44usize, + concat!( + "Offset of field: ", + stringify!(tskTaskControlBlock), + "::", + stringify!(uxPriority) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).pxStack as *const _ as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(tskTaskControlBlock), + "::", + stringify!(pxStack) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).pcTaskName as *const _ as usize }, + 52usize, + concat!( + "Offset of field: ", + stringify!(tskTaskControlBlock), + "::", + stringify!(pcTaskName) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).uxBasePriority as *const _ as usize + }, + 64usize, + concat!( + "Offset of field: ", + stringify!(tskTaskControlBlock), + "::", + stringify!(uxBasePriority) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).uxMutexesHeld as *const _ as usize + }, + 68usize, + concat!( + "Offset of field: ", + stringify!(tskTaskControlBlock), + "::", + stringify!(uxMutexesHeld) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).ulNotifiedValue as *const _ as usize + }, + 72usize, + concat!( + "Offset of field: ", + stringify!(tskTaskControlBlock), + "::", + stringify!(ulNotifiedValue) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).ucNotifyState as *const _ as usize + }, + 76usize, + concat!( + "Offset of field: ", + stringify!(tskTaskControlBlock), + "::", + stringify!(ucNotifyState) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).ucStaticallyAllocated as *const _ + as usize + }, + 77usize, + concat!( + "Offset of field: ", + stringify!(tskTaskControlBlock), + "::", + stringify!(ucStaticallyAllocated) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).ucDelayAborted as *const _ as usize + }, + 78usize, + concat!( + "Offset of field: ", + stringify!(tskTaskControlBlock), + "::", + stringify!(ucDelayAborted) + ) + ); +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct tskTCB(pub tskTaskControlBlock); +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct TCB_t(pub tskTCB); diff --git a/fuzzers/wcet_qemu_sys/src/main.rs b/fuzzers/wcet_qemu_sys/src/main.rs index fcdf8ce275..0440b6238c 100644 --- a/fuzzers/wcet_qemu_sys/src/main.rs +++ b/fuzzers/wcet_qemu_sys/src/main.rs @@ -2,6 +2,7 @@ pub mod fuzzer; pub mod showmap; pub mod worst; +pub mod freertos; use libafl_qemu::{ edges, edges::QemuEdgeCoverageHelper, diff --git a/fuzzers/wcet_qemu_sys/src/showmap.rs b/fuzzers/wcet_qemu_sys/src/showmap.rs index d112bb765a..ad34f75bc8 100644 --- a/fuzzers/wcet_qemu_sys/src/showmap.rs +++ b/fuzzers/wcet_qemu_sys/src/showmap.rs @@ -1,16 +1,7 @@ //! A singlethreaded QEMU fuzzer that can auto-restart. use libafl::feedbacks::CrashFeedback; -use std::fs::File; use std::path::Path; -use libafl::corpus::Corpus; -use libafl::state::HasCorpus; -use libafl::Fuzzer; -use libafl::bolts::tuples::Merge; -use libafl::mutators::tokens_mutations; -use libafl::mutators::havoc_mutations; -use libafl::mutators::StdScheduledMutator; -use libafl::stages::StdMutationalStage; use libafl_qemu::QemuExecutor; use libafl::bolts::tuples::Named; use libafl::observers::ObserversTuple; @@ -23,7 +14,6 @@ use libafl::corpus::InMemoryCorpus; use libafl::events::SimpleEventManager; use libafl::stats::SimpleStats; use crate::worst::HitcountsMapObserver; -use crate::worst::HitFeedback; use clap::{App, Arg}; use std::{ env, @@ -49,10 +39,10 @@ use libafl_qemu::{ edges, edges::QemuEdgeCoverageHelper, emu::Emulator, filter_qemu_args, - snapshot_sys, snapshot_sys::QemuSysSnapshotHelper, elf::EasyElf, }; +use crate::freertos; /// The fuzzer main @@ -208,6 +198,16 @@ fn fuzz( .expect("Symbol trigger_Qemu_break not found"); let check_breakpoint = virt2phys(check_breakpoint,&elf.goblin()); println!("Breakpoint at {:#x}", check_breakpoint); + let curr_tcb_pointer = elf // loads to the address specified in elf, without respecting program headers + .resolve_symbol("pxCurrentTCB", 0) + .expect("Symbol pxCurrentTCBC not found"); + // let curr_tcb_pointer = virt2phys(curr_tcb_pointer,&elf.goblin()); + println!("TCB pointer at {:#x}", curr_tcb_pointer); + // let task_queue_addr = elf + // .resolve_symbol("pxReadyTasksLists", 0) + // .expect("Symbol pxReadyTasksLists not found"); + // // let task_queue_addr = virt2phys(task_queue_addr,&elf.goblin()); + // println!("Task Queue at {:#x}", task_queue_addr); @@ -269,12 +269,42 @@ fn fuzz( } unsafe { + // let mut addr_buf : [u8; 4] = [0u8; 4]; + // emu.read_mem(test_length_ptr,&mut addr_buf); + // println!("current len: {}",u32::from_le_bytes(addr_buf)); + //==end test emu.write_mem(test_length_ptr,&(len as u32).to_le_bytes()); emu.write_mem(input_addr,buf); + //== next test + // emu.read_mem(test_length_ptr,&mut addr_buf); + // println!("new len: {}, expected: {}",u32::from_le_bytes(addr_buf),len); // println!("{:#?}",edges_copy); emu.run(); // println!("{:#?}",edges_copy); + // let mut buf_struct : [u8; 5*std::mem::size_of::()] = [1u8; 5*std::mem::size_of::()]; + // emu.read_mem(task_queue_addr, &mut buf_struct); + // let mut prio_lists : Vec = Vec::new(); + // for i in 0..5 { + // let mut tmp : [u8; std::mem::size_of::()] = [0u8; std::mem::size_of::()]; + // emu.read_mem(task_queue_addr+i*40, &mut tmp); + // let list_struct = std::mem::transmute::<[u8; std::mem::size_of::()], freertos::List_t>(tmp); + // prio_lists.push(list_struct); + // } + // println!("Raw Buffer: {:?}",buf_struct); + // println!("Lists: {:?}",prio_lists); + //====== experiment inspecting the current tcb + let mut curr_tcb_addr : [u8; 4] = [1u8; 4]; + emu.read_mem(curr_tcb_pointer,&mut curr_tcb_addr); + let curr_tcb_addr = u32::from_le_bytes(curr_tcb_addr); + println!("tcb addr: {:x}",curr_tcb_addr); + + let mut tmp : [u8; std::mem::size_of::()] = [1u8; std::mem::size_of::()]; + emu.read_mem(curr_tcb_addr.into(), &mut tmp); + println!("Raw TCB: {:?}",tmp); + let tcb = std::mem::transmute::<[u8; std::mem::size_of::()], freertos::TCB_t>(tmp); + println!("TCB: {:?}",tcb); + } ExitKind::Ok