From 2ac787489534185591d4e6634a88155f0077e837 Mon Sep 17 00:00:00 2001 From: Alwin Berger Date: Tue, 16 Jan 2024 15:53:57 +0100 Subject: [PATCH] fix build --- fuzzers/FRET/src/clock.rs | 7 +- fuzzers/FRET/src/fuzzer.rs | 2 +- fuzzers/FRET/src/lib.rs | 1 - fuzzers/FRET/src/main.rs | 1 - fuzzers/FRET/src/mutational.rs | 9 +- fuzzers/FRET/src/qemustate.rs | 4 +- fuzzers/FRET/src/systemstate/feedbacks.rs | 9 +- fuzzers/FRET/src/systemstate/graph.rs | 5 +- fuzzers/FRET/src/systemstate/helpers.rs | 19 +-- fuzzers/FRET/src/systemstate/schedulers.rs | 4 +- fuzzers/FRET/src/worst.rs | 37 ++++-- libafl_qemu/src/emu.rs | 33 ++++-- libafl_qemu/src/hooks.rs | 132 ++++++--------------- 13 files changed, 120 insertions(+), 143 deletions(-) diff --git a/fuzzers/FRET/src/clock.rs b/fuzzers/FRET/src/clock.rs index 55b519ff87..503946814f 100644 --- a/fuzzers/FRET/src/clock.rs +++ b/fuzzers/FRET/src/clock.rs @@ -25,7 +25,8 @@ use libafl_qemu::{ helper::{QemuHelper, QemuHelperTuple, QemuInstrumentationFilter}, }; use libafl::events::EventFirer; -use libafl::state::HasClientPerfMonitor; +use libafl::state::MaybeHasClientPerfMonitor; +use libafl::prelude::State; use libafl::inputs::Input; use libafl::feedbacks::Feedback; use libafl::SerdeAny; @@ -203,7 +204,7 @@ pub struct ClockTimeFeedback { impl Feedback for ClockTimeFeedback where - S: UsesInput + HasClientPerfMonitor + HasMetadata, + S: State + UsesInput + MaybeHasClientPerfMonitor + HasMetadata, { #[allow(clippy::wrong_self_convention)] fn is_interesting( @@ -280,7 +281,7 @@ pub struct QemuClockIncreaseFeedback { impl Feedback for QemuClockIncreaseFeedback where - S: UsesInput + HasNamedMetadata + HasClientPerfMonitor + Debug, + S: State + UsesInput + HasNamedMetadata + MaybeHasClientPerfMonitor + Debug, { fn is_interesting( &mut self, diff --git a/fuzzers/FRET/src/fuzzer.rs b/fuzzers/FRET/src/fuzzer.rs index 833c6cd7c8..5a83eff762 100644 --- a/fuzzers/FRET/src/fuzzer.rs +++ b/fuzzers/FRET/src/fuzzer.rs @@ -469,7 +469,7 @@ pub fn fuzz() { QemuStateRestoreHelper::new(), QemuSystemStateHelper::new(svh,curr_tcb_pointer,task_queue_addr,task_delay_addr,task_delay_overflow_addr,input_counter_ptr,app_range.clone()) ); - let mut hooks = QemuHooks::new(&emu,qhelpers); + let mut hooks = QemuHooks::new(emu.clone(),qhelpers); #[cfg(not(feature = "systemstate"))] let observer_list = tuple_list!(edges_observer, clock_time_observer); diff --git a/fuzzers/FRET/src/lib.rs b/fuzzers/FRET/src/lib.rs index 4f300be90b..62aea9374f 100644 --- a/fuzzers/FRET/src/lib.rs +++ b/fuzzers/FRET/src/lib.rs @@ -1,4 +1,3 @@ -#![feature(is_sorted)] #[cfg(target_os = "linux")] mod fuzzer; #[cfg(target_os = "linux")] diff --git a/fuzzers/FRET/src/main.rs b/fuzzers/FRET/src/main.rs index c907864a84..7575ece678 100644 --- a/fuzzers/FRET/src/main.rs +++ b/fuzzers/FRET/src/main.rs @@ -1,4 +1,3 @@ -#![feature(is_sorted)] //! A libfuzzer-like fuzzer using qemu for binary-only coverage #[cfg(target_os = "linux")] mod fuzzer; diff --git a/fuzzers/FRET/src/mutational.rs b/fuzzers/FRET/src/mutational.rs index 552ab9b7fe..1be5f1019a 100644 --- a/fuzzers/FRET/src/mutational.rs +++ b/fuzzers/FRET/src/mutational.rs @@ -14,9 +14,10 @@ use libafl::{ mark_feature_time, stages::{Stage}, start_timer, - state::{HasClientPerfMonitor, HasCorpus, HasRand, UsesState, HasMetadata}, + state::{MaybeHasClientPerfMonitor, HasCorpus, HasRand, UsesState, HasMetadata}, Error, prelude::{HasBytesVec, UsesInput, new_hash_feedback, MutationResult, Mutator, CorpusId}, }; +use libafl::prelude::State; use crate::{systemstate::{FreeRTOSSystemStateMetadata, RefinedFreeRTOSSystemState}, fuzzer::DO_NUM_INTERRUPT, clock::IcHist}; pub const MINIMUM_INTER_ARRIVAL_TIME : u32 = 700 * 1000 * (1 << 4); @@ -35,7 +36,7 @@ where E: UsesState, EM: UsesState, Z: Evaluator, - Z::State: HasClientPerfMonitor + HasCorpus + HasRand, + Z::State: MaybeHasClientPerfMonitor + HasCorpus + HasRand, { pub fn new() -> Self { Self { phantom: PhantomData } @@ -47,7 +48,7 @@ where E: UsesState, EM: UsesState, Z: Evaluator, - Z::State: HasClientPerfMonitor + HasCorpus + HasRand + HasMetadata, + Z::State: MaybeHasClientPerfMonitor + HasCorpus + HasRand + HasMetadata, ::Input: HasBytesVec { fn perform( @@ -237,7 +238,7 @@ where E: UsesState, EM: UsesState, Z: Evaluator, - Z::State: HasClientPerfMonitor + HasCorpus + HasRand, + Z::State: MaybeHasClientPerfMonitor + HasCorpus + HasRand, { type State = Z::State; } \ No newline at end of file diff --git a/fuzzers/FRET/src/qemustate.rs b/fuzzers/FRET/src/qemustate.rs index 2da9b57fea..d815059f8f 100644 --- a/fuzzers/FRET/src/qemustate.rs +++ b/fuzzers/FRET/src/qemustate.rs @@ -44,13 +44,13 @@ where { const HOOKS_DO_SIDE_EFFECTS: bool = true; - fn init_hooks(&self, _hooks: &QemuHooks<'_, QT, S>) + fn init_hooks(&self, _hooks: &QemuHooks) where QT: QemuHelperTuple, { } - fn first_exec(&self, _hooks: &QemuHooks<'_, QT, S>) + fn first_exec(&self, _hooks: &QemuHooks) where QT: QemuHelperTuple, { diff --git a/fuzzers/FRET/src/systemstate/feedbacks.rs b/fuzzers/FRET/src/systemstate/feedbacks.rs index 03214f1f7d..b9aaeddf31 100644 --- a/fuzzers/FRET/src/systemstate/feedbacks.rs +++ b/fuzzers/FRET/src/systemstate/feedbacks.rs @@ -11,7 +11,8 @@ use std::collections::hash_map::DefaultHasher; use std::hash::Hasher; use std::hash::Hash; use libafl::events::EventFirer; -use libafl::state::HasClientPerfMonitor; +use libafl::state::MaybeHasClientPerfMonitor; +use libafl::prelude::State; use libafl::feedbacks::Feedback; use libafl_bolts::Named; use libafl::Error; @@ -62,7 +63,7 @@ pub struct NovelSystemStateFeedback impl Feedback for NovelSystemStateFeedback where - S: UsesInput + HasClientPerfMonitor + HasNamedMetadata, + S: State + UsesInput + MaybeHasClientPerfMonitor + HasNamedMetadata, { fn is_interesting( &mut self, @@ -176,7 +177,7 @@ pub struct HitSystemStateFeedback impl Feedback for HitSystemStateFeedback where - S: UsesInput + HasClientPerfMonitor, + S: State + UsesInput + MaybeHasClientPerfMonitor, { fn is_interesting( &mut self, @@ -228,7 +229,7 @@ pub struct DumpSystraceFeedback impl Feedback for DumpSystraceFeedback where - S: UsesInput + HasClientPerfMonitor, + S: State + UsesInput + MaybeHasClientPerfMonitor, { fn is_interesting( &mut self, diff --git a/fuzzers/FRET/src/systemstate/graph.rs b/fuzzers/FRET/src/systemstate/graph.rs index 09e55fc752..f29da3120d 100644 --- a/fuzzers/FRET/src/systemstate/graph.rs +++ b/fuzzers/FRET/src/systemstate/graph.rs @@ -10,6 +10,7 @@ use libafl::prelude::HasTargetBytes; use libafl::prelude::UsesInput; use libafl::state::HasNamedMetadata; use libafl::state::UsesState; +use libafl::prelude::State; use core::marker::PhantomData; use libafl::state::HasCorpus; use libafl::state::HasSolutions; @@ -29,7 +30,7 @@ use std::collections::hash_map::DefaultHasher; use std::hash::Hasher; use std::hash::Hash; use libafl::events::EventFirer; -use libafl::state::HasClientPerfMonitor; +use libafl::state::MaybeHasClientPerfMonitor; use libafl::feedbacks::Feedback; use libafl_bolts::Named; use libafl::Error; @@ -284,7 +285,7 @@ impl SysMapFeedback { impl Feedback for SysMapFeedback where - S: UsesInput + HasClientPerfMonitor + HasNamedMetadata, + S: State + UsesInput + MaybeHasClientPerfMonitor + HasNamedMetadata, S::Input: HasTargetBytes, { #[allow(clippy::wrong_self_convention)] diff --git a/fuzzers/FRET/src/systemstate/helpers.rs b/fuzzers/FRET/src/systemstate/helpers.rs index b4bac0ec23..9e9e32e165 100644 --- a/fuzzers/FRET/src/systemstate/helpers.rs +++ b/fuzzers/FRET/src/systemstate/helpers.rs @@ -10,6 +10,7 @@ use libafl_qemu::QemuHooks; use libafl_qemu::edges::QemuEdgesMapMetadata; use libafl_qemu::emu; use libafl_qemu::hooks; +use libafl_qemu::Hook; use crate::systemstate::RawFreeRTOSSystemState; use crate::systemstate::CURRENT_SYSTEMSTATE_VEC; use crate::systemstate::NUM_PRIOS; @@ -72,13 +73,13 @@ impl QemuHelper for QemuSystemStateHelper where S: UsesInput, { - fn first_exec(&self, _hooks: &QemuHooks<'_, QT, S>) + fn first_exec(&self, _hooks: &QemuHooks) where QT: QemuHelperTuple, { - _hooks.instruction(self.kerneladdr, exec_syscall_hook::, false); + _hooks.instruction(self.kerneladdr, Hook::Function(exec_syscall_hook::), false); #[cfg(feature = "trace_abbs")] - _hooks.jmps(Some(gen_jmp_is_syscall::), Some(trace_api_call::)); + _hooks.jmps(Hook::Function(gen_jmp_is_syscall::), Hook::Function(trace_api_call::)); } // TODO: refactor duplicate code @@ -133,10 +134,10 @@ fn trigger_collection(emulator: &Emulator, h: &QemuSystemStateHelper) { 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()).can_do_io; - (*c.raw_ptr()).can_do_io = 1; + 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()).can_do_io = can_do_io; + (*c.raw_ptr()).neg.can_do_io = can_do_io; } let mut buf : [u8; 4] = [0,0,0,0]; match h.input_counter { @@ -183,7 +184,7 @@ fn trigger_collection(emulator: &Emulator, h: &QemuSystemStateHelper) { } pub fn exec_syscall_hook( - hooks: &mut QemuHooks<'_, QT, S>, + hooks: &mut QemuHooks, _state: Option<&mut S>, _pc: GuestAddr, ) @@ -199,7 +200,7 @@ where thread_local!(static LAST_API_CALL : UnsafeCell> = UnsafeCell::new(None)); pub fn gen_jmp_is_syscall( - hooks: &mut QemuHooks<'_, QT, S>, + hooks: &mut QemuHooks, _state: Option<&mut S>, src: GuestAddr, dest: GuestAddr, @@ -218,7 +219,7 @@ where } pub fn trace_api_call( - _hooks: &mut QemuHooks<'_, QT, S>, + _hooks: &mut QemuHooks, _state: Option<&mut S>, src: GuestAddr, dest: GuestAddr, id: u64 ) diff --git a/fuzzers/FRET/src/systemstate/schedulers.rs b/fuzzers/FRET/src/systemstate/schedulers.rs index 729a767010..e9c0e20759 100644 --- a/fuzzers/FRET/src/systemstate/schedulers.rs +++ b/fuzzers/FRET/src/systemstate/schedulers.rs @@ -160,14 +160,14 @@ pub struct GenerationScheduler { impl UsesState for GenerationScheduler where - S: UsesInput, + S: State + UsesInput, { type State = S; } impl Scheduler for GenerationScheduler where - S: HasCorpus + HasMetadata, + S: State + HasCorpus + HasMetadata, S::Input: HasLen, { /// get first element in current gen, diff --git a/fuzzers/FRET/src/worst.rs b/fuzzers/FRET/src/worst.rs index 9ecc565c76..b40062d232 100644 --- a/fuzzers/FRET/src/worst.rs +++ b/fuzzers/FRET/src/worst.rs @@ -13,7 +13,8 @@ use hashbrown::{HashMap}; use libafl::observers::ObserversTuple; use libafl::executors::ExitKind; use libafl::events::EventFirer; -use libafl::state::{HasClientPerfMonitor, HasCorpus, UsesState}; +use libafl::state::{MaybeHasClientPerfMonitor, HasCorpus, UsesState}; +use libafl::prelude::State; use libafl::inputs::Input; use libafl::feedbacks::Feedback; use libafl::state::HasMetadata; @@ -101,7 +102,7 @@ pub struct SortedFeedback { impl Feedback for SortedFeedback where - S: UsesInput + HasClientPerfMonitor, + S: State + UsesInput + MaybeHasClientPerfMonitor, S::Input: HasTargetBytes, { #[allow(clippy::wrong_self_convention)] @@ -122,12 +123,24 @@ where if tmp.len()<32 {return Ok(false);} let tmp = Vec::::from(&tmp[0..32]); // tmp.reverse(); - if tmp.is_sorted_by(|a,b| match a.partial_cmp(b).unwrap_or(Less) { - Less => Some(Greater), - Equal => Some(Greater), - Greater => Some(Less), - }) {return Ok(true)}; - return Ok(false); + // if tmp.is_sorted_by(|a,b| match a.partial_cmp(b).unwrap_or(Less) { + // Less => Some(Greater), + // Equal => Some(Greater), + // Greater => Some(Less), + // }) {return Ok(true)}; + let mut is_sorted = true; + if tmp[0]=tmp[i]; + if !is_sorted {break;} + } + } + return Ok(is_sorted); } } @@ -162,7 +175,7 @@ pub struct ExecTimeReachedFeedback impl Feedback for ExecTimeReachedFeedback where - S: UsesInput + HasClientPerfMonitor, + S: State + UsesInput + MaybeHasClientPerfMonitor, { #[allow(clippy::wrong_self_convention)] fn is_interesting( @@ -211,7 +224,7 @@ pub struct ExecTimeCollectorFeedback impl Feedback for ExecTimeCollectorFeedback where - S: UsesInput + HasClientPerfMonitor, + S: State + UsesInput + MaybeHasClientPerfMonitor, { #[allow(clippy::wrong_self_convention)] fn is_interesting( @@ -276,7 +289,7 @@ pub struct ExecTimeIncFeedback impl Feedback for ExecTimeIncFeedback where - S: UsesInput + HasClientPerfMonitor, + S: State + UsesInput + MaybeHasClientPerfMonitor, { #[allow(clippy::wrong_self_convention)] fn is_interesting( @@ -344,7 +357,7 @@ pub struct AlwaysTrueFeedback impl Feedback for AlwaysTrueFeedback where - S: UsesInput + HasClientPerfMonitor, + S: State + UsesInput + MaybeHasClientPerfMonitor, { #[allow(clippy::wrong_self_convention)] fn is_interesting( diff --git a/libafl_qemu/src/emu.rs b/libafl_qemu/src/emu.rs index 19afdbeb9a..1f69251703 100644 --- a/libafl_qemu/src/emu.rs +++ b/libafl_qemu/src/emu.rs @@ -404,10 +404,10 @@ extern "C" { // void (*exec)(target_ulong src, target_ulong dst, uint64_t id, uint64_t data), // uint64_t data); fn libafl_add_jmp_hook( - gen: Option u64>, - exec: Option, + gen: Option u64>, // data,src,dest + exec: Option, // data,src,dest,id data: u64, - ); + ) -> usize; } #[cfg(emulation_mode = "usermode")] @@ -1520,13 +1520,28 @@ impl Emulator { } } - pub fn add_jmp_hooks( + // pub fn add_jmp_hooks( + // &self, + // gen: Option u64>, + // exec: Option, + // data: u64, + // ) { + // unsafe { libafl_add_jmp_hook(gen, exec, data) } + // } + pub fn add_jmp_hooks>( &self, - gen: Option u64>, - exec: Option, - data: u64, - ) { - unsafe { libafl_add_jmp_hook(gen, exec, data) } + data: T, + gen: Option u64>, + exec: Option, + ) -> HookId { + unsafe { + let data: u64 = data.into().0; + let gen: Option u64> = + core::mem::transmute(gen); + let exec: Option = core::mem::transmute(exec); + let num = libafl_add_jmp_hook(gen, exec, data); + HookId(num) + } } #[cfg(emulation_mode = "systemmode")] diff --git a/libafl_qemu/src/hooks.rs b/libafl_qemu/src/hooks.rs index b4181cabe4..1009b22339 100644 --- a/libafl_qemu/src/hooks.rs +++ b/libafl_qemu/src/hooks.rs @@ -535,77 +535,11 @@ where } } -static mut JMP_HOOKS: Vec<(Hook, Hook)> = vec![]; +static mut JMP_HOOKS: Vec> = vec![]; +create_gen_wrapper!(jmp, (src: GuestAddr, dest: GuestAddr), u64, 1); +create_exec_wrapper!(jmp, (src: GuestAddr, dst: GuestAddr, id: u64), 0, 1); -extern "C" fn gen_jmp_hook_wrapper(src: GuestAddr, dst: GuestAddr, index: u64) -> u64 -where - S: UsesInput, - QT: QemuHelperTuple, -{ - unsafe { - let hooks = get_qemu_hooks::(); - let (gen, _) = &mut JMP_HOOKS[index as usize]; - match gen { - Hook::Function(ptr) => { - let func: fn( - &mut QemuHooks<'_, QT, S>, - Option<&mut S>, - GuestAddr, - GuestAddr, - ) -> Option = transmute(*ptr); - (func)(hooks, inprocess_get_state::(), src, dst).map_or(SKIP_EXEC_HOOK, |id| id) - } - Hook::Closure(ptr) => { - let func: &mut Box< - dyn FnMut( - &mut QemuHooks<'_, QT, S>, - Option<&mut S>, - GuestAddr, - GuestAddr, - ) -> Option, - > = transmute(ptr); - (func)(hooks, inprocess_get_state::(), src, dst).map_or(SKIP_EXEC_HOOK, |id| id) - } - _ => 0, - } - } -} -extern "C" fn exec_jmp_hook_wrapper(src: GuestAddr, dst: GuestAddr, id: u64, index: u64) -where - S: UsesInput, - QT: QemuHelperTuple, -{ - unsafe { - let hooks = get_qemu_hooks::(); - let (_, exec) = &mut JMP_HOOKS[index as usize]; - match exec { - Hook::Function(ptr) => { - let func: fn( - &mut QemuHooks<'_, QT, S>, - Option<&mut S>, - GuestAddr, - GuestAddr, - u64, - ) = transmute(*ptr); - (func)(hooks, inprocess_get_state::(), src, dst, id); - } - Hook::Closure(ptr) => { - let func: &mut Box< - dyn FnMut( - &mut QemuHooks<'_, QT, S>, - Option<&mut S>, - GuestAddr, - GuestAddr, - u64, - ), - > = transmute(ptr); - (func)(hooks, inprocess_get_state::(), src, dst, id); - } - _ => (), - } - } -} static mut HOOKS_IS_INITIALIZED: bool = false; static mut FIRST_EXEC: bool = true; @@ -1483,34 +1417,46 @@ where pub fn jmps( &self, - generation_hook: Option< + generation_hook: Hook< fn(&mut Self, Option<&mut S>, src: GuestAddr, dest: GuestAddr) -> Option, + Box< + dyn for<'a> FnMut( + &'a mut Self, + Option<&'a mut S>, + GuestAddr, + GuestAddr, + ) -> Option, + >, + extern "C" fn(*const (), src: GuestAddr, dest: GuestAddr) -> u64, >, - execution_hook: Option, src: GuestAddr, dest: GuestAddr, id: u64)>, - ) { + execution_hook: Hook< + fn(&mut Self, Option<&mut S>, src: GuestAddr, dest: GuestAddr, id: u64), + Box FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr, GuestAddr, u64)>, + extern "C" fn(*const (), src: GuestAddr, dest: GuestAddr, id: u64), + >, + ) -> HookId { unsafe { - let index = JMP_HOOKS.len(); - self.emulator.add_jmp_hooks( - if generation_hook.is_none() { - None - } else { - Some(gen_jmp_hook_wrapper::) - }, - if execution_hook.is_none() { - None - } else { - Some(exec_jmp_hook_wrapper::) - }, - index as u64, + let gen = get_raw_hook!( + generation_hook, + jmp_gen_hook_wrapper::, + extern "C" fn(&mut HookState<1>, src: GuestAddr, dest: GuestAddr) -> u64 ); - JMP_HOOKS.push(( - generation_hook.map_or(Hook::Empty, |hook| { - Hook::Function(hook as *const libc::c_void) - }), - execution_hook.map_or(Hook::Empty, |hook| { - Hook::Function(hook as *const libc::c_void) - }), - )); + let exec = get_raw_hook!( + execution_hook, + jmp_0_exec_hook_wrapper::, + extern "C" fn(&mut HookState<1>, src: GuestAddr, dest: GuestAddr, id: u64) + ); + JMP_HOOKS.push(HookState { + id: HookId(0), + gen: hook_to_repr!(generation_hook), + post_gen: HookRepr::Empty, + execs: [hook_to_repr!(execution_hook)], + }); + let id = self + .emulator + .add_jmp_hooks(JMP_HOOKS.last_mut().unwrap(), gen, exec); + JMP_HOOKS.last_mut().unwrap().id = id; + id } } }