From ba01f600eeb0d1b0419ba6c32115d459835d8922 Mon Sep 17 00:00:00 2001 From: Alwin Berger Date: Tue, 24 Jan 2023 09:11:45 +0100 Subject: [PATCH] re-add system state fuzzing --- fuzzers/FRET/Cargo.toml | 2 +- fuzzers/FRET/benchmark/Makefile | 2 ++ fuzzers/FRET/benchmark/target_symbols.csv | 3 +- fuzzers/FRET/src/fuzzer.rs | 15 +++++---- fuzzers/FRET/src/systemstate/feedbacks.rs | 40 ++++++++++++---------- fuzzers/FRET/src/systemstate/graph.rs | 4 +-- fuzzers/FRET/src/systemstate/helpers.rs | 41 +++++++++++++++++------ 7 files changed, 68 insertions(+), 39 deletions(-) diff --git a/fuzzers/FRET/Cargo.toml b/fuzzers/FRET/Cargo.toml index 62ffbf41c9..4002869e5c 100644 --- a/fuzzers/FRET/Cargo.toml +++ b/fuzzers/FRET/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Andrea Fioraldi ", "Dominik Maier = env::vars().collect(); let emu = Emulator::new(&args, &env); - emu.set_breakpoint(main_addr); - unsafe { - emu.run(); - } - emu.remove_breakpoint(main_addr); + // emu.set_breakpoint(main_addr); + // unsafe { + // emu.run(); + // } + // emu.remove_breakpoint(main_addr); emu.set_breakpoint(breakpoint); // BREAKPOINT @@ -214,7 +214,8 @@ pub fn fuzz() { ); #[cfg(feature = "systemstate")] let mut feedback = feedback_or!( - DumpSystraceFeedback::with_dump(None), + // DumpSystraceFeedback::with_dump(None), + NovelSystemStateFeedback::default(), feedback ); diff --git a/fuzzers/FRET/src/systemstate/feedbacks.rs b/fuzzers/FRET/src/systemstate/feedbacks.rs index eeb8790c53..0ba77c68fe 100644 --- a/fuzzers/FRET/src/systemstate/feedbacks.rs +++ b/fuzzers/FRET/src/systemstate/feedbacks.rs @@ -31,12 +31,12 @@ use std::cmp::Ordering; /// Shared Metadata for a systemstateFeedback #[derive(Debug, Serialize, Deserialize, SerdeAny, Clone, Default)] -pub struct systemstateFeedbackState +pub struct SystemStateFeedbackState { known_traces: HashMap, // encounters,ticks,length longest: Vec, } -impl Named for systemstateFeedbackState +impl Named for SystemStateFeedbackState { #[inline] fn name(&self) -> &str { @@ -52,7 +52,7 @@ impl Named for systemstateFeedbackState // } // } -/// A Feedback reporting novel System-State Transitions. Depends on [`QemusystemstateObserver`] +/// A Feedback reporting novel System-State Transitions. Depends on [`QemuSystemStateObserver`] #[derive(Serialize, Deserialize, Clone, Debug, Default)] pub struct NovelSystemStateFeedback { @@ -77,13 +77,19 @@ where OT: ObserversTuple { let observer = observers.match_name::("systemstate") - .expect("QemusystemstateObserver not found"); - let clock_observer = observers.match_name::("clock") //TODO not fixed - .expect("QemusystemstateObserver not found"); - let feedbackstate = state + .expect("QemuSystemStateObserver not found"); + let clock_observer = observers.match_name::("clocktime") //TODO not fixed + .expect("QemuClockObserver not found"); + let feedbackstate = match state .named_metadata_mut() - .get_mut::("systemstate") - .unwrap(); + .get_mut::("systemstate") { + Some(s) => s, + None => { + let n=SystemStateFeedbackState::default(); + state.named_metadata_mut().insert(n, "systemstate"); + state.named_metadata_mut().get_mut::("systemstate").unwrap() + } + }; // let feedbackstate = state // .feedback_states_mut() // .match_name_mut::("systemstate") @@ -161,14 +167,14 @@ pub fn match_traces_name(target: &Vec, last: &Vec>, } -impl Feedback for HitsystemstateFeedback +impl Feedback for HitSystemStateFeedback where S: UsesInput + HasClientPerfMonitor, { @@ -185,7 +191,7 @@ where OT: ObserversTuple { let observer = observers.match_name::("systemstate") - .expect("QemusystemstateObserver not found"); + .expect("QemuSystemStateObserver not found"); // Do Stuff match &self.target { Some(s) => { @@ -197,7 +203,7 @@ where } } -impl Named for HitsystemstateFeedback +impl Named for HitSystemStateFeedback { #[inline] fn name(&self) -> &str { @@ -205,13 +211,13 @@ impl Named for HitsystemstateFeedback } } -impl HitsystemstateFeedback { +impl HitSystemStateFeedback { pub fn new(target: Option>) -> Self { Self {target: target.map(|x| x.into_iter().map(|y| y.current_task.task_name).collect())} } } //=========================== Debugging Feedback -/// A [`Feedback`] meant to dump the system-traces for debugging. Depends on [`QemusystemstateObserver`] +/// A [`Feedback`] meant to dump the system-traces for debugging. Depends on [`QemuSystemStateObserver`] #[derive(Debug)] pub struct DumpSystraceFeedback { @@ -237,7 +243,7 @@ where OT: ObserversTuple { let observer = observers.match_name::("systemstate") - .expect("QemusystemstateObserver not found"); + .expect("QemuSystemStateObserver not found"); let names : Vec = observer.last_run.iter().map(|x| x.current_task.task_name.clone()).collect(); match &self.dumpfile { Some(s) => { diff --git a/fuzzers/FRET/src/systemstate/graph.rs b/fuzzers/FRET/src/systemstate/graph.rs index 5f885a4f7e..7c6da55557 100644 --- a/fuzzers/FRET/src/systemstate/graph.rs +++ b/fuzzers/FRET/src/systemstate/graph.rs @@ -247,7 +247,7 @@ impl SysGraphFeedbackState } } -/// A Feedback reporting novel System-State Transitions. Depends on [`QemusystemstateObserver`] +/// A Feedback reporting novel System-State Transitions. Depends on [`QemuSystemStateObserver`] #[derive(Serialize, Deserialize, Clone, Debug, Default)] pub struct SysMapFeedback { @@ -279,7 +279,7 @@ where OT: ObserversTuple, { let observer = observers.match_name::("systemstate") - .expect("QemusystemstateObserver not found"); + .expect("QemuSystemStateObserver not found"); let feedbackstate = state .named_metadata_mut() .get_mut::("SysMap") diff --git a/fuzzers/FRET/src/systemstate/helpers.rs b/fuzzers/FRET/src/systemstate/helpers.rs index 5d5605d920..8da48f0950 100644 --- a/fuzzers/FRET/src/systemstate/helpers.rs +++ b/fuzzers/FRET/src/systemstate/helpers.rs @@ -2,6 +2,7 @@ use std::cell::UnsafeCell; use std::io::Write; use std::ops::Range; use libafl::prelude::UsesInput; +use libafl_qemu::Emulator; use libafl_qemu::GuestAddr; use libafl_qemu::QemuHooks; use libafl_qemu::edges::QemuEdgesMapMetadata; @@ -70,19 +71,23 @@ where _hooks.instruction(self.kerneladdr, exec_syscall_hook::, false); _hooks.jmps(Some(gen_jmp_is_syscall::), Some(trace_api_call::)); } + + // TODO: refactor duplicate code + fn pre_exec(&mut self, _emulator: &Emulator, _input: &S::Input) { + unsafe { + CURRENT_SYSTEMSTATE_VEC.clear(); + let p = LAST_API_CALL.with(|x| x.get()); + *p = None; + } + } + + fn post_exec(&mut self, emulator: &Emulator, _input: &S::Input) { + trigger_collection(emulator, self) + } } -pub fn exec_syscall_hook( - hooks: &mut QemuHooks<'_, QT, S>, - _state: Option<&mut S>, - _pc: u32, -) -where - S: UsesInput, - QT: QemuHelperTuple, -{ - let emulator = hooks.emulator(); - let h = hooks.helpers().match_first_type::().expect("QemuSystemHelper not found in helper tupel"); +#[inline] +fn trigger_collection(emulator: &Emulator, h: &QemuSystemStateHelper) { let listbytes : u32 = u32::try_from(std::mem::size_of::()).unwrap(); let mut systemstate = RawFreeRTOSSystemState::default(); unsafe { @@ -151,6 +156,20 @@ where unsafe { CURRENT_SYSTEMSTATE_VEC.push(systemstate); } } +pub fn exec_syscall_hook( + hooks: &mut QemuHooks<'_, QT, S>, + _state: Option<&mut S>, + _pc: u32, +) +where + S: UsesInput, + QT: QemuHelperTuple, +{ + let emulator = hooks.emulator(); + let h = hooks.helpers().match_first_type::().expect("QemuSystemHelper not found in helper tupel"); + trigger_collection(emulator, h); +} + thread_local!(static LAST_API_CALL : UnsafeCell> = UnsafeCell::new(None)); pub fn gen_jmp_is_syscall(