From c1be6582a77c8498e027fc9d4a1922b86d0de95c Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 25 Apr 2024 12:02:18 +0200 Subject: [PATCH 01/31] match by ref fix --- fuzzers/forkserver_libafl_cc/src/main.rs | 2 +- libafl_bolts/src/tuples.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fuzzers/forkserver_libafl_cc/src/main.rs b/fuzzers/forkserver_libafl_cc/src/main.rs index 25ef3c26b5..ebbcf5549e 100644 --- a/fuzzers/forkserver_libafl_cc/src/main.rs +++ b/fuzzers/forkserver_libafl_cc/src/main.rs @@ -185,7 +185,7 @@ pub fn main() { if let Some(dynamic_map_size) = executor.coverage_map_size() { executor .observers_mut() - .match_by_ref_mut(observer_ref) + .match_by_ref_mut(&observer_ref) .unwrap() .as_mut() .truncate(dynamic_map_size); diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index 504049fbc5..aa86e7e975 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -566,10 +566,10 @@ pub struct Reference { #[cfg(feature = "alloc")] pub trait MatchNameRef { /// Search using name and `Reference ` - fn match_by_ref(&self, rf: Reference) -> Option<&T>; + fn match_by_ref(&self, rf: &Reference) -> Option<&T>; /// Search using name and `Reference ` - fn match_by_ref_mut(&mut self, rf: Reference) -> Option<&mut T>; + fn match_by_ref_mut(&mut self, rf: &Reference) -> Option<&mut T>; } #[cfg(feature = "alloc")] @@ -577,11 +577,11 @@ impl MatchNameRef for M where M: MatchName, { - fn match_by_ref(&self, rf: Reference) -> Option<&T> { + fn match_by_ref(&self, rf: &Reference) -> Option<&T> { self.match_name::(&rf.name) } - fn match_by_ref_mut(&mut self, rf: Reference) -> Option<&mut T> { + fn match_by_ref_mut(&mut self, rf: &Reference) -> Option<&mut T> { self.match_name_mut::(&rf.name) } } From d154b02e1749453f4df267f2004d182248bfce98 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 25 Apr 2024 12:45:09 +0200 Subject: [PATCH 02/31] impl Named for Reference --- libafl_bolts/src/tuples.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index aa86e7e975..1d548a2fc7 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -562,6 +562,13 @@ pub struct Reference { phantom: PhantomData, } +#[cfg(feature = "alloc")] +impl Named for Reference { + fn name(&self) -> &Cow<'static, str> { + &self.name + } +} + /// Search using `Reference ` #[cfg(feature = "alloc")] pub trait MatchNameRef { From ae65fd9f7a3a78dd272469f3008a7ea0b704c8ae Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 25 Apr 2024 13:39:16 +0200 Subject: [PATCH 03/31] rename --- fuzzers/forkserver_libafl_cc/src/main.rs | 2 +- libafl_bolts/src/tuples.rs | 31 ++++++++++++++++++------ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/fuzzers/forkserver_libafl_cc/src/main.rs b/fuzzers/forkserver_libafl_cc/src/main.rs index ebbcf5549e..458aa6b611 100644 --- a/fuzzers/forkserver_libafl_cc/src/main.rs +++ b/fuzzers/forkserver_libafl_cc/src/main.rs @@ -185,7 +185,7 @@ pub fn main() { if let Some(dynamic_map_size) = executor.coverage_map_size() { executor .observers_mut() - .match_by_ref_mut(&observer_ref) + .get_mut(&observer_ref) .unwrap() .as_mut() .truncate(dynamic_map_size); diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index 1d548a2fc7..6cb1aa4bce 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -219,9 +219,9 @@ where /// Returns the first element with the given type pub trait MatchFirstType { - /// Returns the first element with the given type as borrow, or [`Option::None`] + /// Returns the first element with the given type as borrow, or [`None`] fn match_first_type(&self) -> Option<&T>; - /// Returns the first element with the given type as mutable borrow, or [`Option::None`] + /// Returns the first element with the given type as mutable borrow, or [`None`] fn match_first_type_mut(&mut self) -> Option<&mut T>; } @@ -554,7 +554,7 @@ pub trait Referenceable: Named { #[cfg(feature = "alloc")] impl Referenceable for N where N: Named {} -/// Empty object with the type T +/// Object with the type T and the name associated with its concrete value #[derive(Debug)] #[cfg(feature = "alloc")] pub struct Reference { @@ -573,10 +573,10 @@ impl Named for Reference { #[cfg(feature = "alloc")] pub trait MatchNameRef { /// Search using name and `Reference ` - fn match_by_ref(&self, rf: &Reference) -> Option<&T>; + fn get(&self, rf: &Reference) -> Option<&T>; /// Search using name and `Reference ` - fn match_by_ref_mut(&mut self, rf: &Reference) -> Option<&mut T>; + fn get_mut(&mut self, rf: &Reference) -> Option<&mut T>; } #[cfg(feature = "alloc")] @@ -584,15 +584,32 @@ impl MatchNameRef for M where M: MatchName, { - fn match_by_ref(&self, rf: &Reference) -> Option<&T> { + fn get(&self, rf: &Reference) -> Option<&T> { self.match_name::(&rf.name) } - fn match_by_ref_mut(&mut self, rf: &Reference) -> Option<&mut T> { + fn get_mut(&mut self, rf: &Reference) -> Option<&mut T> { self.match_name_mut::(&rf.name) } } +// This is the dream, but sadly doesn't work +// https://rust-lang.github.io/rfcs/2451-re-rebalancing-coherence.html#concrete-orphan-rules +// #[cfg(feature = "alloc")] +// impl Index<&Reference> for M +// where +// M: MatchName, +// { +// type Output = T; +// +// fn index(&self, index: &Reference) -> &Self::Output { +// let Some(e) = self.get(index) else { +// panic!("{} not found in sequence", index.name) +// }; +// e +// } +// } + /// Allows prepending of values to a tuple pub trait Prepend { /// The Resulting [`TupleList`], of an [`Prepend::prepend()`] call, From 120a260e2e76f4463332804b5459a623606222c9 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 25 Apr 2024 15:46:28 +0200 Subject: [PATCH 04/31] magic indexing --- fuzzers/forkserver_libafl_cc/src/main.rs | 5 +- libafl/src/executors/combined.rs | 6 +- libafl/src/executors/command.rs | 10 +- libafl/src/executors/differential.rs | 24 ++-- libafl/src/executors/forkserver.rs | 10 +- libafl/src/executors/inprocess/inner.rs | 10 +- libafl/src/executors/inprocess/mod.rs | 12 +- libafl/src/executors/inprocess/stateful.rs | 6 +- libafl/src/executors/inprocess_fork/inner.rs | 10 +- libafl/src/executors/inprocess_fork/mod.rs | 12 +- .../src/executors/inprocess_fork/stateful.rs | 9 +- libafl/src/executors/mod.rs | 5 +- libafl/src/executors/shadow.rs | 6 +- libafl/src/executors/with_observers.rs | 10 +- libafl/src/fuzzer/mod.rs | 42 ++++--- libafl/src/stages/calibrate.rs | 4 +- libafl/src/stages/colorization.rs | 4 +- libafl/src/stages/mod.rs | 9 +- libafl/src/stages/tmin.rs | 10 +- libafl_bolts/src/tuples.rs | 107 +++++++++++++++--- libafl_frida/src/executor.rs | 4 +- libafl_nyx/src/executor.rs | 4 +- libafl_qemu/src/executor/mod.rs | 8 +- libafl_qemu/src/executor/stateful.rs | 4 +- libafl_tinyinst/src/executor.rs | 4 +- 25 files changed, 214 insertions(+), 121 deletions(-) diff --git a/fuzzers/forkserver_libafl_cc/src/main.rs b/fuzzers/forkserver_libafl_cc/src/main.rs index 458aa6b611..9c5c13b4c7 100644 --- a/fuzzers/forkserver_libafl_cc/src/main.rs +++ b/fuzzers/forkserver_libafl_cc/src/main.rs @@ -183,10 +183,7 @@ pub fn main() { .unwrap(); if let Some(dynamic_map_size) = executor.coverage_map_size() { - executor - .observers_mut() - .get_mut(&observer_ref) - .unwrap() + executor.observers_mut()[&observer_ref] .as_mut() .truncate(dynamic_map_size); } diff --git a/libafl/src/executors/combined.rs b/libafl/src/executors/combined.rs index eeff368eed..244f8937eb 100644 --- a/libafl/src/executors/combined.rs +++ b/libafl/src/executors/combined.rs @@ -3,6 +3,8 @@ use core::fmt::Debug; +use libafl_bolts::tuples::{RefIndexable, RefIndexableMut}; + use crate::{ executors::{Executor, ExitKind, HasObservers}, observers::UsesObservers, @@ -80,12 +82,12 @@ where A: HasObservers, { #[inline] - fn observers(&self) -> &Self::Observers { + fn observers(&self) -> RefIndexable { self.primary.observers() } #[inline] - fn observers_mut(&mut self) -> &mut Self::Observers { + fn observers_mut(&mut self) -> RefIndexableMut { self.primary.observers_mut() } } diff --git a/libafl/src/executors/command.rs b/libafl/src/executors/command.rs index 9754b0fe6e..b0799a4421 100644 --- a/libafl/src/executors/command.rs +++ b/libafl/src/executors/command.rs @@ -18,7 +18,7 @@ use std::{ use libafl_bolts::{ fs::{get_unique_std_input_file, InputFile}, - tuples::MatchName, + tuples::{MatchName, RefIndexable, RefIndexableMut}, AsSlice, }; @@ -397,12 +397,12 @@ where T: Debug, OT: ObserversTuple, { - fn observers(&self) -> &OT { - &self.observers + fn observers(&self) -> RefIndexable { + RefIndexable(&self.observers) } - fn observers_mut(&mut self) -> &mut OT { - &mut self.observers + fn observers_mut(&mut self) -> RefIndexableMut { + RefIndexableMut(&mut self.observers) } } diff --git a/libafl/src/executors/differential.rs b/libafl/src/executors/differential.rs index ff14ffc1e5..ae35a0b6da 100644 --- a/libafl/src/executors/differential.rs +++ b/libafl/src/executors/differential.rs @@ -4,7 +4,10 @@ //! use core::{cell::UnsafeCell, fmt::Debug, ptr}; -use libafl_bolts::{ownedref::OwnedMutPtr, tuples::MatchName}; +use libafl_bolts::{ + ownedref::OwnedMutPtr, + tuples::{MatchName, RefIndexable, RefIndexableMut}, +}; use serde::{Deserialize, Serialize}; use crate::{ @@ -238,26 +241,25 @@ where DOT: DifferentialObserversTuple, { #[inline] - fn observers(&self) -> &ProxyObserversTuple { + fn observers(&self) -> RefIndexable> { unsafe { self.observers .get() .as_mut() .unwrap() - .set(self.primary.observers(), self.secondary.observers()); - self.observers.get().as_ref().unwrap() + .set(self.primary.observers().0, self.secondary.observers().0); + RefIndexable(self.observers.get().as_ref().unwrap()) } } #[inline] - fn observers_mut(&mut self) -> &mut ProxyObserversTuple { + fn observers_mut(&mut self) -> RefIndexableMut> { unsafe { - self.observers - .get() - .as_mut() - .unwrap() - .set(self.primary.observers(), self.secondary.observers()); - self.observers.get().as_mut().unwrap() + self.observers.get().as_mut().unwrap().set( + self.primary.observers_mut().0, + self.secondary.observers_mut().0, + ); + RefIndexableMut(self.observers.get().as_mut().unwrap()) } } } diff --git a/libafl/src/executors/forkserver.rs b/libafl/src/executors/forkserver.rs index a14e83bacf..f076b2d7b1 100644 --- a/libafl/src/executors/forkserver.rs +++ b/libafl/src/executors/forkserver.rs @@ -22,7 +22,7 @@ use libafl_bolts::{ fs::{get_unique_std_input_file, InputFile}, os::{dup2, pipes::Pipe}, shmem::{ShMem, ShMemProvider, UnixShMemProvider}, - tuples::Prepend, + tuples::{Prepend, RefIndexable, RefIndexableMut}, AsSlice, AsSliceMut, Truncate, }; use nix::{ @@ -1211,13 +1211,13 @@ where SP: ShMemProvider, { #[inline] - fn observers(&self) -> &OT { - &self.observers + fn observers(&self) -> RefIndexable { + RefIndexable(&self.observers) } #[inline] - fn observers_mut(&mut self) -> &mut OT { - &mut self.observers + fn observers_mut(&mut self) -> RefIndexableMut { + RefIndexableMut(&mut self.observers) } } diff --git a/libafl/src/executors/inprocess/inner.rs b/libafl/src/executors/inprocess/inner.rs index bad296bce3..304bd768be 100644 --- a/libafl/src/executors/inprocess/inner.rs +++ b/libafl/src/executors/inprocess/inner.rs @@ -7,7 +7,7 @@ use core::{ time::Duration, }; -use libafl_bolts::tuples::{tuple_list, Merge}; +use libafl_bolts::tuples::{tuple_list, Merge, RefIndexable, RefIndexableMut}; #[cfg(windows)] use windows::Win32::System::Threading::SetThreadStackGuarantee; @@ -85,13 +85,13 @@ where S: State, { #[inline] - fn observers(&self) -> &OT { - &self.observers + fn observers(&self) -> RefIndexable { + RefIndexable(&self.observers) } #[inline] - fn observers_mut(&mut self) -> &mut OT { - &mut self.observers + fn observers_mut(&mut self) -> RefIndexableMut { + RefIndexableMut(&mut self.observers) } } diff --git a/libafl/src/executors/inprocess/mod.rs b/libafl/src/executors/inprocess/mod.rs index 87d07acf8e..42263ec681 100644 --- a/libafl/src/executors/inprocess/mod.rs +++ b/libafl/src/executors/inprocess/mod.rs @@ -16,7 +16,7 @@ use core::{ time::Duration, }; -use libafl_bolts::tuples::tuple_list; +use libafl_bolts::tuples::{tuple_list, RefIndexable, RefIndexableMut}; #[cfg(any(unix, feature = "std"))] use crate::executors::hooks::inprocess::GLOBAL_STATE; @@ -151,12 +151,12 @@ where S: State, { #[inline] - fn observers(&self) -> &OT { + fn observers(&self) -> RefIndexable { self.inner.observers() } #[inline] - fn observers_mut(&mut self) -> &mut OT { + fn observers_mut(&mut self) -> RefIndexableMut { self.inner.observers_mut() } } @@ -438,7 +438,7 @@ pub fn run_observers_and_save_state( E::State: HasExecutions + HasSolutions + HasCorpus, Z: HasObjective, { - let observers = executor.observers_mut(); + let mut observers = executor.observers_mut(); observers .post_exec_all(state, input, &exitkind) @@ -446,7 +446,7 @@ pub fn run_observers_and_save_state( let interesting = fuzzer .objective_mut() - .is_interesting(state, event_mgr, input, observers, &exitkind) + .is_interesting(state, event_mgr, input, &*observers, &exitkind) .expect("In run_observers_and_save_state objective failure."); if interesting { @@ -456,7 +456,7 @@ pub fn run_observers_and_save_state( new_testcase.set_parent_id_optional(*state.corpus().current()); fuzzer .objective_mut() - .append_metadata(state, event_mgr, observers, &mut new_testcase) + .append_metadata(state, event_mgr, &*observers, &mut new_testcase) .expect("Failed adding metadata"); state .solutions_mut() diff --git a/libafl/src/executors/inprocess/stateful.rs b/libafl/src/executors/inprocess/stateful.rs index 6454d4d6a9..9ccc2b2c6b 100644 --- a/libafl/src/executors/inprocess/stateful.rs +++ b/libafl/src/executors/inprocess/stateful.rs @@ -8,7 +8,7 @@ use core::{ time::Duration, }; -use libafl_bolts::tuples::tuple_list; +use libafl_bolts::tuples::{tuple_list, RefIndexable, RefIndexableMut}; use crate::{ events::{EventFirer, EventRestarter}, @@ -142,12 +142,12 @@ where S: State, { #[inline] - fn observers(&self) -> &OT { + fn observers(&self) -> RefIndexable { self.inner.observers() } #[inline] - fn observers_mut(&mut self) -> &mut OT { + fn observers_mut(&mut self) -> RefIndexableMut { self.inner.observers_mut() } } diff --git a/libafl/src/executors/inprocess_fork/inner.rs b/libafl/src/executors/inprocess_fork/inner.rs index 3c26c9d6ad..2424762db2 100644 --- a/libafl/src/executors/inprocess_fork/inner.rs +++ b/libafl/src/executors/inprocess_fork/inner.rs @@ -10,7 +10,7 @@ use core::{ use libafl_bolts::{ os::unix_signals::Signal, shmem::ShMemProvider, - tuples::{tuple_list, Merge}, + tuples::{tuple_list, Merge, RefIndexable, RefIndexableMut}, }; use nix::{ sys::wait::{waitpid, WaitStatus}, @@ -339,12 +339,12 @@ where Z: UsesState, { #[inline] - fn observers(&self) -> &OT { - &self.observers + fn observers(&self) -> RefIndexable { + RefIndexable(&self.observers) } #[inline] - fn observers_mut(&mut self) -> &mut OT { - &mut self.observers + fn observers_mut(&mut self) -> RefIndexableMut { + RefIndexableMut(&mut self.observers) } } diff --git a/libafl/src/executors/inprocess_fork/mod.rs b/libafl/src/executors/inprocess_fork/mod.rs index 67e1eb8233..d14697e29c 100644 --- a/libafl/src/executors/inprocess_fork/mod.rs +++ b/libafl/src/executors/inprocess_fork/mod.rs @@ -7,7 +7,7 @@ use core::{ use libafl_bolts::{ os::unix_signals::{ucontext_t, Signal}, shmem::ShMemProvider, - tuples::tuple_list, + tuples::{tuple_list, RefIndexable, RefIndexableMut}, }; use libc::siginfo_t; use nix::unistd::{fork, ForkResult}; @@ -255,12 +255,12 @@ where Z: UsesState, { #[inline] - fn observers(&self) -> &OT { + fn observers(&self) -> RefIndexable { self.inner.observers() } #[inline] - fn observers_mut(&mut self) -> &mut OT { + fn observers_mut(&mut self) -> RefIndexableMut { self.inner.observers_mut() } } @@ -295,7 +295,7 @@ pub mod child_signal_handlers { let data = addr_of_mut!(FORK_EXECUTOR_GLOBAL_DATA); if !data.is_null() && (*data).is_valid() { let executor = (*data).executor_mut::(); - let observers = executor.observers_mut(); + let mut observers = executor.observers_mut(); let state = (*data).state_mut::(); // Invalidate data to not execute again the observer hooks in the crash handler let input = (*data).take_current_input::<::Input>(); @@ -326,7 +326,7 @@ pub mod child_signal_handlers { { if data.is_valid() { let executor = data.executor_mut::(); - let observers = executor.observers_mut(); + let mut observers = executor.observers_mut(); let state = data.state_mut::(); let input = data.take_current_input::<::Input>(); observers @@ -349,7 +349,7 @@ pub mod child_signal_handlers { { if data.is_valid() { let executor = data.executor_mut::(); - let observers = executor.observers_mut(); + let mut observers = executor.observers_mut(); let state = data.state_mut::(); let input = data.take_current_input::<::Input>(); observers diff --git a/libafl/src/executors/inprocess_fork/stateful.rs b/libafl/src/executors/inprocess_fork/stateful.rs index cbe3e67caf..49cadf6fe2 100644 --- a/libafl/src/executors/inprocess_fork/stateful.rs +++ b/libafl/src/executors/inprocess_fork/stateful.rs @@ -5,7 +5,10 @@ use core::{ time::Duration, }; -use libafl_bolts::{shmem::ShMemProvider, tuples::tuple_list}; +use libafl_bolts::{ + shmem::ShMemProvider, + tuples::{tuple_list, RefIndexable, RefIndexableMut}, +}; use nix::unistd::{fork, ForkResult}; use super::super::hooks::ExecutorHooksTuple; @@ -245,12 +248,12 @@ where Z: UsesState, { #[inline] - fn observers(&self) -> &OT { + fn observers(&self) -> RefIndexable { self.inner.observers() } #[inline] - fn observers_mut(&mut self) -> &mut OT { + fn observers_mut(&mut self) -> RefIndexableMut { self.inner.observers_mut() } } diff --git a/libafl/src/executors/mod.rs b/libafl/src/executors/mod.rs index 824b8d58e7..fdc38ea3ae 100644 --- a/libafl/src/executors/mod.rs +++ b/libafl/src/executors/mod.rs @@ -15,6 +15,7 @@ pub use inprocess::InProcessExecutor; pub use inprocess_fork::InProcessForkExecutor; #[cfg(unix)] use libafl_bolts::os::unix_signals::Signal; +use libafl_bolts::tuples::{RefIndexable, RefIndexableMut}; use serde::{Deserialize, Serialize}; pub use shadow::ShadowExecutor; pub use with_observers::WithObservers; @@ -110,10 +111,10 @@ libafl_bolts::impl_serdeany!(DiffExitKind); /// Holds a tuple of Observers pub trait HasObservers: UsesObservers { /// Get the linked observers - fn observers(&self) -> &Self::Observers; + fn observers(&self) -> RefIndexable; /// Get the linked observers (mutable) - fn observers_mut(&mut self) -> &mut Self::Observers; + fn observers_mut(&mut self) -> RefIndexableMut; } /// An executor takes the given inputs, and runs the harness/target. diff --git a/libafl/src/executors/shadow.rs b/libafl/src/executors/shadow.rs index f2b30c0fec..c2116b99f9 100644 --- a/libafl/src/executors/shadow.rs +++ b/libafl/src/executors/shadow.rs @@ -2,6 +2,8 @@ use core::fmt::{self, Debug, Formatter}; +use libafl_bolts::tuples::{RefIndexable, RefIndexableMut}; + use crate::{ executors::{Executor, ExitKind, HasObservers}, observers::{ObserversTuple, UsesObservers}, @@ -94,12 +96,12 @@ where SOT: ObserversTuple, { #[inline] - fn observers(&self) -> &Self::Observers { + fn observers(&self) -> RefIndexable { self.executor.observers() } #[inline] - fn observers_mut(&mut self) -> &mut Self::Observers { + fn observers_mut(&mut self) -> RefIndexableMut { self.executor.observers_mut() } } diff --git a/libafl/src/executors/with_observers.rs b/libafl/src/executors/with_observers.rs index 78594ad776..7a7684a99c 100644 --- a/libafl/src/executors/with_observers.rs +++ b/libafl/src/executors/with_observers.rs @@ -2,6 +2,8 @@ use core::fmt::Debug; +use libafl_bolts::tuples::{RefIndexable, RefIndexableMut}; + use crate::{ executors::{Executor, ExitKind, HasObservers}, observers::{ObserversTuple, UsesObservers}, @@ -53,12 +55,12 @@ where E: UsesState, OT: ObserversTuple, { - fn observers(&self) -> &OT { - &self.observers + fn observers(&self) -> RefIndexable { + RefIndexable(&self.observers) } - fn observers_mut(&mut self) -> &mut OT { - &mut self.observers + fn observers_mut(&mut self) -> RefIndexableMut { + RefIndexableMut(&mut self.observers) } } diff --git a/libafl/src/fuzzer/mod.rs b/libafl/src/fuzzer/mod.rs index 8eac544ea6..eb5d99aa3b 100644 --- a/libafl/src/fuzzer/mod.rs +++ b/libafl/src/fuzzer/mod.rs @@ -541,9 +541,9 @@ where let exit_kind = self.execute_input(state, executor, manager, &input)?; let observers = executor.observers(); - self.scheduler.on_evaluation(state, &input, observers)?; + self.scheduler.on_evaluation(state, &input, &*observers)?; - self.execute_and_process(state, manager, input, observers, &exit_kind, send_events) + self.execute_and_process(state, manager, input, &*observers, &exit_kind, send_events) } } @@ -595,18 +595,22 @@ where // Maybe a solution #[cfg(not(feature = "introspection"))] - let is_solution = self - .objective_mut() - .is_interesting(state, manager, &input, observers, &exit_kind)?; + let is_solution = + self.objective_mut() + .is_interesting(state, manager, &input, &*observers, &exit_kind)?; #[cfg(feature = "introspection")] - let is_solution = self - .objective_mut() - .is_interesting_introspection(state, manager, &input, observers, &exit_kind)?; + let is_solution = self.objective_mut().is_interesting_introspection( + state, + manager, + &input, + &*observers, + &exit_kind, + )?; if is_solution { self.objective_mut() - .append_metadata(state, manager, observers, &mut testcase)?; + .append_metadata(state, manager, &*observers, &mut testcase)?; let idx = state.solutions_mut().add(testcase)?; let executions = *state.executions(); @@ -627,25 +631,29 @@ where // several is_interesting implementations collect some data about the run, later used in // append_metadata; we *must* invoke is_interesting here to collect it #[cfg(not(feature = "introspection"))] - let _corpus_worthy = self - .feedback_mut() - .is_interesting(state, manager, &input, observers, &exit_kind)?; + let _corpus_worthy = + self.feedback_mut() + .is_interesting(state, manager, &input, &*observers, &exit_kind)?; #[cfg(feature = "introspection")] - let _corpus_worthy = self - .feedback_mut() - .is_interesting_introspection(state, manager, &input, observers, &exit_kind)?; + let _corpus_worthy = self.feedback_mut().is_interesting_introspection( + state, + manager, + &input, + &*observers, + &exit_kind, + )?; // Add the input to the main corpus self.feedback_mut() - .append_metadata(state, manager, observers, &mut testcase)?; + .append_metadata(state, manager, &*observers, &mut testcase)?; let idx = state.corpus_mut().add(testcase)?; self.scheduler_mut().on_add(state, idx)?; let observers_buf = if manager.configuration() == EventConfig::AlwaysUnique { None } else { - manager.serialize_observers::(observers)? + manager.serialize_observers::(&*observers)? }; manager.fire( state, diff --git a/libafl/src/stages/calibrate.rs b/libafl/src/stages/calibrate.rs index c8ec6fcc1f..49a50a8392 100644 --- a/libafl/src/stages/calibrate.rs +++ b/libafl/src/stages/calibrate.rs @@ -248,8 +248,8 @@ where // If weighted scheduler or powerscheduler is used, update it if state.has_metadata::() { - let map = executor - .observers() + let observers = executor.observers(); + let map = observers .match_name::(&self.map_observer_name) .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))? .as_ref(); diff --git a/libafl/src/stages/colorization.rs b/libafl/src/stages/colorization.rs index 0042c5913f..a07e89a026 100644 --- a/libafl/src/stages/colorization.rs +++ b/libafl/src/stages/colorization.rs @@ -315,8 +315,8 @@ where let exit_kind = executor.run_target(fuzzer, state, manager, &input)?; - let observer = executor - .observers() + let observers = executor.observers(); + let observer = observers .match_name::(name) .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))? .as_ref(); diff --git a/libafl/src/stages/mod.rs b/libafl/src/stages/mod.rs index 033a512ed5..29fc9af677 100644 --- a/libafl/src/stages/mod.rs +++ b/libafl/src/stages/mod.rs @@ -429,11 +429,12 @@ where push_stage.set_current_corpus_idx(corpus_idx); - push_stage.init(fuzzer, state, event_mgr, executor.observers_mut())?; + push_stage.init(fuzzer, state, event_mgr, &mut *executor.observers_mut())?; loop { let input = - match push_stage.pre_exec(fuzzer, state, event_mgr, executor.observers_mut()) { + match push_stage.pre_exec(fuzzer, state, event_mgr, &mut *executor.observers_mut()) + { Some(Ok(next_input)) => next_input, Some(Err(err)) => return Err(err), None => break, @@ -445,14 +446,14 @@ where fuzzer, state, event_mgr, - executor.observers_mut(), + &mut *executor.observers_mut(), input, exit_kind, )?; } self.push_stage - .deinit(fuzzer, state, event_mgr, executor.observers_mut()) + .deinit(fuzzer, state, event_mgr, &mut *executor.observers_mut()) } #[inline] diff --git a/libafl/src/stages/tmin.rs b/libafl/src/stages/tmin.rs index 62fa4756e5..18e208f529 100644 --- a/libafl/src/stages/tmin.rs +++ b/libafl/src/stages/tmin.rs @@ -91,7 +91,7 @@ where fuzzer.execute_input(state, executor, manager, &base)?; let observers = executor.observers(); - let mut feedback = self.create_feedback(observers); + let mut feedback = self.create_feedback(&*observers); let mut i = 0; loop { @@ -130,7 +130,7 @@ where state, manager, input.clone(), - observers, + &*observers, &exit_kind, false, )?; @@ -139,7 +139,7 @@ where && state.solutions().count() == solution_count { // we do not care about interesting inputs! - if feedback.is_interesting(state, manager, &input, observers, &exit_kind)? { + if feedback.is_interesting(state, manager, &input, &*observers, &exit_kind)? { // we found a reduced corpus entry! use the smaller base base = input; base_post = Some(post.clone()); @@ -172,11 +172,11 @@ where // marked as interesting above; similarly, it should not trigger objectives fuzzer .feedback_mut() - .is_interesting(state, manager, &base, observers, &exit_kind)?; + .is_interesting(state, manager, &base, &*observers, &exit_kind)?; let mut testcase = Testcase::with_executions(base, *state.executions()); fuzzer .feedback_mut() - .append_metadata(state, manager, observers, &mut testcase)?; + .append_metadata(state, manager, &*observers, &mut testcase)?; let prev = state.corpus_mut().replace(base_corpus_idx, testcase)?; fuzzer .scheduler_mut() diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index 6cb1aa4bce..faae1e804f 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -8,8 +8,10 @@ use core::{ any::TypeId, marker::PhantomData, mem::transmute, + ops::{Index, IndexMut}, ptr::{addr_of, addr_of_mut}, }; +use std::ops::{Deref, DerefMut}; pub use tuple_list::{tuple_list, tuple_list_type, TupleList}; @@ -593,22 +595,95 @@ where } } -// This is the dream, but sadly doesn't work -// https://rust-lang.github.io/rfcs/2451-re-rebalancing-coherence.html#concrete-orphan-rules -// #[cfg(feature = "alloc")] -// impl Index<&Reference> for M -// where -// M: MatchName, -// { -// type Output = T; -// -// fn index(&self, index: &Reference) -> &Self::Output { -// let Some(e) = self.get(index) else { -// panic!("{} not found in sequence", index.name) -// }; -// e -// } -// } +#[cfg(feature = "alloc")] +#[derive(Debug)] +pub struct RefIndexable<'a, M>(pub &'a M); + +impl<'a, M> From<&'a M> for RefIndexable<'a, M> +where + M: MatchName, +{ + fn from(value: &'a M) -> Self { + RefIndexable(value) + } +} + +#[cfg(feature = "alloc")] +#[derive(Debug)] +pub struct RefIndexableMut<'a, M>(pub &'a mut M); + +impl<'a, M> From<&'a mut M> for RefIndexableMut<'a, M> +where + M: MatchName, +{ + fn from(value: &'a mut M) -> Self { + RefIndexableMut(value) + } +} + +impl<'a, M> Deref for RefIndexable<'a, M> { + type Target = M; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl<'a, M> Deref for RefIndexableMut<'a, M> { + type Target = M; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl<'a, M> DerefMut for RefIndexableMut<'a, M> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +#[cfg(feature = "alloc")] +impl<'a, T, M> Index<&Reference> for RefIndexable<'a, M> +where + M: MatchName, +{ + type Output = T; + + fn index(&self, index: &Reference) -> &Self::Output { + let Some(e) = self.get(index) else { + panic!("{} not found in sequence", index.name) + }; + e + } +} + +#[cfg(feature = "alloc")] +impl<'a, T, M> Index<&Reference> for RefIndexableMut<'a, M> +where + M: MatchName, +{ + type Output = T; + + fn index(&self, index: &Reference) -> &Self::Output { + let Some(e) = self.get(index) else { + panic!("{} not found in sequence", index.name) + }; + e + } +} + +#[cfg(feature = "alloc")] +impl<'a, T, M> IndexMut<&Reference> for RefIndexableMut<'a, M> +where + M: MatchName, +{ + fn index_mut(&mut self, index: &Reference) -> &mut Self::Output { + let Some(e) = self.get_mut(index) else { + panic!("{} not found in sequence", index.name) + }; + e + } +} /// Allows prepending of values to a tuple pub trait Prepend { diff --git a/libafl_frida/src/executor.rs b/libafl_frida/src/executor.rs index b3e437675c..7ce60bc78b 100644 --- a/libafl_frida/src/executor.rs +++ b/libafl_frida/src/executor.rs @@ -145,12 +145,12 @@ where OT: ObserversTuple, { #[inline] - fn observers(&self) -> &OT { + fn observers(&self) -> RefIndexable { self.base.observers() } #[inline] - fn observers_mut(&mut self) -> &mut OT { + fn observers_mut(&mut self) -> RefIndexableMut { self.base.observers_mut() } } diff --git a/libafl_nyx/src/executor.rs b/libafl_nyx/src/executor.rs index f39b56367d..15106ff372 100644 --- a/libafl_nyx/src/executor.rs +++ b/libafl_nyx/src/executor.rs @@ -146,11 +146,11 @@ where S: State, OT: ObserversTuple, { - fn observers(&self) -> &OT { + fn observers(&self) -> RefIndexable { &self.observers } - fn observers_mut(&mut self) -> &mut OT { + fn observers_mut(&mut self) -> RefIndexableMut { &mut self.observers } } diff --git a/libafl_qemu/src/executor/mod.rs b/libafl_qemu/src/executor/mod.rs index efb402d2fa..d01d48a835 100644 --- a/libafl_qemu/src/executor/mod.rs +++ b/libafl_qemu/src/executor/mod.rs @@ -343,12 +343,12 @@ where QT: QemuHelperTuple, { #[inline] - fn observers(&self) -> &OT { + fn observers(&self) -> RefIndexable { self.inner.observers() } #[inline] - fn observers_mut(&mut self) -> &mut OT { + fn observers_mut(&mut self) -> RefIndexableMut { self.inner.observers_mut() } } @@ -527,12 +527,12 @@ where Z: UsesState, { #[inline] - fn observers(&self) -> &OT { + fn observers(&self) -> RefIndexable { self.inner.observers() } #[inline] - fn observers_mut(&mut self) -> &mut OT { + fn observers_mut(&mut self) -> RefIndexableMut { self.inner.observers_mut() } } diff --git a/libafl_qemu/src/executor/stateful.rs b/libafl_qemu/src/executor/stateful.rs index b6413eba71..926684f2a7 100644 --- a/libafl_qemu/src/executor/stateful.rs +++ b/libafl_qemu/src/executor/stateful.rs @@ -199,12 +199,12 @@ where QT: QemuHelperTuple, { #[inline] - fn observers(&self) -> &OT { + fn observers(&self) -> RefIndexable { self.inner.observers() } #[inline] - fn observers_mut(&mut self) -> &mut OT { + fn observers_mut(&mut self) -> RefIndexableMut { self.inner.observers_mut() } } diff --git a/libafl_tinyinst/src/executor.rs b/libafl_tinyinst/src/executor.rs index 2a06d05462..1fa99287be 100644 --- a/libafl_tinyinst/src/executor.rs +++ b/libafl_tinyinst/src/executor.rs @@ -300,11 +300,11 @@ where SP: ShMemProvider, OT: ObserversTuple, { - fn observers(&self) -> &OT { + fn observers(&self) -> RefIndexable { &self.observers } - fn observers_mut(&mut self) -> &mut OT { + fn observers_mut(&mut self) -> RefIndexableMut { &mut self.observers } } From ce95f2dbaeef469d242013faf8e712dbf8027e0a Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 25 Apr 2024 15:48:59 +0200 Subject: [PATCH 05/31] whoops --- libafl_bolts/src/tuples.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index faae1e804f..8f6751f21a 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -4,6 +4,8 @@ use alloc::{borrow::Cow, vec::Vec}; #[rustversion::not(nightly)] use core::any::type_name; +#[cfg(feature = "alloc")] +use core::ops::{Deref, DerefMut}; use core::{ any::TypeId, marker::PhantomData, @@ -11,7 +13,6 @@ use core::{ ops::{Index, IndexMut}, ptr::{addr_of, addr_of_mut}, }; -use std::ops::{Deref, DerefMut}; pub use tuple_list::{tuple_list, tuple_list_type, TupleList}; From f575cc15ae610fd5f9d7e73dada5456779e1f95e Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 25 Apr 2024 15:53:10 +0200 Subject: [PATCH 06/31] docs, clippy --- libafl_bolts/src/tuples.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index 8f6751f21a..5a062e1b32 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -596,8 +596,10 @@ where } } +/// A wrapper type to enable the indexing of [`MatchName`] implementors with `[]`. #[cfg(feature = "alloc")] #[derive(Debug)] +#[repr(transparent)] pub struct RefIndexable<'a, M>(pub &'a M); impl<'a, M> From<&'a M> for RefIndexable<'a, M> @@ -609,8 +611,10 @@ where } } +/// A wrapper type to enable the mutable indexing of [`MatchName`] implementors with `[]`. #[cfg(feature = "alloc")] #[derive(Debug)] +#[repr(transparent)] pub struct RefIndexableMut<'a, M>(pub &'a mut M); impl<'a, M> From<&'a mut M> for RefIndexableMut<'a, M> @@ -626,20 +630,20 @@ impl<'a, M> Deref for RefIndexable<'a, M> { type Target = M; fn deref(&self) -> &Self::Target { - &self.0 + self.0 } } impl<'a, M> Deref for RefIndexableMut<'a, M> { type Target = M; fn deref(&self) -> &Self::Target { - &self.0 + self.0 } } impl<'a, M> DerefMut for RefIndexableMut<'a, M> { fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 + self.0 } } From 0b30f6c06e4f946039efa09ffdd69f92d812e26e Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 25 Apr 2024 15:56:51 +0200 Subject: [PATCH 07/31] some additional CI complaints --- libafl_frida/src/executor.rs | 1 + libafl_qemu/src/executor/stateful.rs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libafl_frida/src/executor.rs b/libafl_frida/src/executor.rs index 7ce60bc78b..2492401ac1 100644 --- a/libafl_frida/src/executor.rs +++ b/libafl_frida/src/executor.rs @@ -19,6 +19,7 @@ use libafl::{ state::{HasExecutions, State, UsesState}, Error, }; +use libafl_bolts::tuples::{RefIndexable, RefIndexableMut}; #[cfg(all(unix, not(test)))] use crate::asan::errors::AsanErrors; diff --git a/libafl_qemu/src/executor/stateful.rs b/libafl_qemu/src/executor/stateful.rs index 926684f2a7..aaff62538c 100644 --- a/libafl_qemu/src/executor/stateful.rs +++ b/libafl_qemu/src/executor/stateful.rs @@ -17,6 +17,7 @@ use libafl::{ state::{HasCorpus, HasExecutions, HasSolutions, State, UsesState}, Error, }; +use libafl_bolts::tuples::{RefIndexable, RefIndexableMut}; #[cfg(emulation_mode = "usermode")] use crate::executor::inproc_qemu_crash_handler; @@ -164,7 +165,7 @@ where .post_exec::( input, qemu, - self.inner.inner.observers_mut(), + &mut *self.inner.inner.observers_mut(), &mut exit_kind, ); Ok(exit_kind) From 8431d6a7d927afea89af0f960ebe86a9f3ff8ade Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 25 Apr 2024 16:03:20 +0200 Subject: [PATCH 08/31] other libafl_qemu fixes --- libafl_qemu/src/executor/mod.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libafl_qemu/src/executor/mod.rs b/libafl_qemu/src/executor/mod.rs index d01d48a835..9c52457731 100644 --- a/libafl_qemu/src/executor/mod.rs +++ b/libafl_qemu/src/executor/mod.rs @@ -22,9 +22,12 @@ use libafl::{ state::{HasCorpus, HasExecutions, HasSolutions, State, UsesState}, Error, HasMetadata, }; -use libafl_bolts::os::unix_signals::{siginfo_t, ucontext_t, Signal}; #[cfg(feature = "fork")] use libafl_bolts::shmem::ShMemProvider; +use libafl_bolts::{ + os::unix_signals::{siginfo_t, ucontext_t, Signal}, + tuples::{RefIndexable, RefIndexableMut}, +}; use crate::{helpers::QemuHelperTuple, hooks::QemuHooks, Qemu}; @@ -308,7 +311,7 @@ where self.state.post_exec::( input, qemu, - self.inner.observers_mut(), + &mut *self.inner.observers_mut(), &mut exit_kind, ); Ok(exit_kind) @@ -480,7 +483,7 @@ where self.state.hooks.helpers_mut().post_exec_all( qemu, input, - self.inner.observers_mut(), + &mut *self.inner.observers_mut(), &mut exit_kind, ); Ok(exit_kind) From 8ea16ed01c29819d933177e1e26214ba8fb7174e Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 25 Apr 2024 16:35:55 +0200 Subject: [PATCH 09/31] missed an alloc feature --- libafl_bolts/src/tuples.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index 5a062e1b32..d1076cd81c 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -602,6 +602,7 @@ where #[repr(transparent)] pub struct RefIndexable<'a, M>(pub &'a M); +#[cfg(feature = "alloc")] impl<'a, M> From<&'a M> for RefIndexable<'a, M> where M: MatchName, @@ -617,6 +618,7 @@ where #[repr(transparent)] pub struct RefIndexableMut<'a, M>(pub &'a mut M); +#[cfg(feature = "alloc")] impl<'a, M> From<&'a mut M> for RefIndexableMut<'a, M> where M: MatchName, @@ -626,6 +628,7 @@ where } } +#[cfg(feature = "alloc")] impl<'a, M> Deref for RefIndexable<'a, M> { type Target = M; @@ -633,6 +636,8 @@ impl<'a, M> Deref for RefIndexable<'a, M> { self.0 } } + +#[cfg(feature = "alloc")] impl<'a, M> Deref for RefIndexableMut<'a, M> { type Target = M; @@ -641,6 +646,7 @@ impl<'a, M> Deref for RefIndexableMut<'a, M> { } } +#[cfg(feature = "alloc")] impl<'a, M> DerefMut for RefIndexableMut<'a, M> { fn deref_mut(&mut self) -> &mut Self::Target { self.0 From c5708f8f7845727ec4b36975530946b591afcaeb Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 25 Apr 2024 16:38:22 +0200 Subject: [PATCH 10/31] a smattering of fixes --- libafl/src/corpus/minimizer.rs | 4 ++-- libafl_tinyinst/src/executor.rs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libafl/src/corpus/minimizer.rs b/libafl/src/corpus/minimizer.rs index 53f24224f9..a038f93cdb 100644 --- a/libafl/src/corpus/minimizer.rs +++ b/libafl/src/corpus/minimizer.rs @@ -160,8 +160,8 @@ where )?; let seed_expr = Bool::fresh_const(&ctx, "seed"); - let obs = executor - .observers() + let observers = executor.observers(); + let obs = observers .match_name::(&self.obs_name) .expect("Observer must be present.") .as_ref(); diff --git a/libafl_tinyinst/src/executor.rs b/libafl_tinyinst/src/executor.rs index 1fa99287be..e392e36fd1 100644 --- a/libafl_tinyinst/src/executor.rs +++ b/libafl_tinyinst/src/executor.rs @@ -11,6 +11,7 @@ use libafl::{ use libafl_bolts::{ fs::{InputFile, INPUTFILE_STD}, shmem::{ShMem, ShMemProvider, StdShMemProvider}, + tuples::{RefIndexable, RefIndexableMut}, AsSlice, AsSliceMut, }; use tinyinst::tinyinst::{litecov::RunResult, TinyInst}; From e52a68cbd035fd8441ccdb297c09271ef73b7859 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 25 Apr 2024 16:48:48 +0200 Subject: [PATCH 11/31] use from not direct construction --- libafl/src/executors/command.rs | 4 ++-- libafl/src/executors/differential.rs | 10 +++++----- libafl/src/executors/forkserver.rs | 4 ++-- libafl/src/executors/inprocess/inner.rs | 4 ++-- libafl/src/executors/inprocess_fork/inner.rs | 4 ++-- libafl/src/executors/with_observers.rs | 4 ++-- libafl_bolts/src/tuples.rs | 4 ++-- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/libafl/src/executors/command.rs b/libafl/src/executors/command.rs index b0799a4421..779a2ea480 100644 --- a/libafl/src/executors/command.rs +++ b/libafl/src/executors/command.rs @@ -398,11 +398,11 @@ where OT: ObserversTuple, { fn observers(&self) -> RefIndexable { - RefIndexable(&self.observers) + RefIndexable::from(&self.observers) } fn observers_mut(&mut self) -> RefIndexableMut { - RefIndexableMut(&mut self.observers) + RefIndexableMut::from(&mut self.observers) } } diff --git a/libafl/src/executors/differential.rs b/libafl/src/executors/differential.rs index ae35a0b6da..833bd2e623 100644 --- a/libafl/src/executors/differential.rs +++ b/libafl/src/executors/differential.rs @@ -247,8 +247,8 @@ where .get() .as_mut() .unwrap() - .set(self.primary.observers().0, self.secondary.observers().0); - RefIndexable(self.observers.get().as_ref().unwrap()) + .set(&*self.primary.observers(), &*self.secondary.observers()); + RefIndexable::from(self.observers.get().as_ref().unwrap()) } } @@ -256,10 +256,10 @@ where fn observers_mut(&mut self) -> RefIndexableMut> { unsafe { self.observers.get().as_mut().unwrap().set( - self.primary.observers_mut().0, - self.secondary.observers_mut().0, + &mut *self.primary.observers_mut(), + &mut *self.secondary.observers_mut(), ); - RefIndexableMut(self.observers.get().as_mut().unwrap()) + RefIndexableMut::from(self.observers.get().as_mut().unwrap()) } } } diff --git a/libafl/src/executors/forkserver.rs b/libafl/src/executors/forkserver.rs index f076b2d7b1..fbd22602d1 100644 --- a/libafl/src/executors/forkserver.rs +++ b/libafl/src/executors/forkserver.rs @@ -1212,12 +1212,12 @@ where { #[inline] fn observers(&self) -> RefIndexable { - RefIndexable(&self.observers) + RefIndexable::from(&self.observers) } #[inline] fn observers_mut(&mut self) -> RefIndexableMut { - RefIndexableMut(&mut self.observers) + RefIndexableMut::from(&mut self.observers) } } diff --git a/libafl/src/executors/inprocess/inner.rs b/libafl/src/executors/inprocess/inner.rs index 304bd768be..23648874e7 100644 --- a/libafl/src/executors/inprocess/inner.rs +++ b/libafl/src/executors/inprocess/inner.rs @@ -86,12 +86,12 @@ where { #[inline] fn observers(&self) -> RefIndexable { - RefIndexable(&self.observers) + RefIndexable::from(&self.observers) } #[inline] fn observers_mut(&mut self) -> RefIndexableMut { - RefIndexableMut(&mut self.observers) + RefIndexableMut::from(&mut self.observers) } } diff --git a/libafl/src/executors/inprocess_fork/inner.rs b/libafl/src/executors/inprocess_fork/inner.rs index 2424762db2..0217d337cf 100644 --- a/libafl/src/executors/inprocess_fork/inner.rs +++ b/libafl/src/executors/inprocess_fork/inner.rs @@ -340,11 +340,11 @@ where { #[inline] fn observers(&self) -> RefIndexable { - RefIndexable(&self.observers) + RefIndexable::from(&self.observers) } #[inline] fn observers_mut(&mut self) -> RefIndexableMut { - RefIndexableMut(&mut self.observers) + RefIndexableMut::from(&mut self.observers) } } diff --git a/libafl/src/executors/with_observers.rs b/libafl/src/executors/with_observers.rs index 7a7684a99c..5c962a3239 100644 --- a/libafl/src/executors/with_observers.rs +++ b/libafl/src/executors/with_observers.rs @@ -56,11 +56,11 @@ where OT: ObserversTuple, { fn observers(&self) -> RefIndexable { - RefIndexable(&self.observers) + RefIndexable::from(&self.observers) } fn observers_mut(&mut self) -> RefIndexableMut { - RefIndexableMut(&mut self.observers) + RefIndexableMut::from(&mut self.observers) } } diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index d1076cd81c..269525ec5b 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -600,7 +600,7 @@ where #[cfg(feature = "alloc")] #[derive(Debug)] #[repr(transparent)] -pub struct RefIndexable<'a, M>(pub &'a M); +pub struct RefIndexable<'a, M>(&'a M); #[cfg(feature = "alloc")] impl<'a, M> From<&'a M> for RefIndexable<'a, M> @@ -616,7 +616,7 @@ where #[cfg(feature = "alloc")] #[derive(Debug)] #[repr(transparent)] -pub struct RefIndexableMut<'a, M>(pub &'a mut M); +pub struct RefIndexableMut<'a, M>(&'a mut M); #[cfg(feature = "alloc")] impl<'a, M> From<&'a mut M> for RefIndexableMut<'a, M> From 0afa904b9e9a6a0ec993167c25c9a0299b8933d4 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 25 Apr 2024 16:55:49 +0200 Subject: [PATCH 12/31] tinyinst fix --- libafl_tinyinst/src/executor.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libafl_tinyinst/src/executor.rs b/libafl_tinyinst/src/executor.rs index e392e36fd1..0e6e7e4b26 100644 --- a/libafl_tinyinst/src/executor.rs +++ b/libafl_tinyinst/src/executor.rs @@ -302,11 +302,11 @@ where OT: ObserversTuple, { fn observers(&self) -> RefIndexable { - &self.observers + RefIndexable::from(&self.observers) } fn observers_mut(&mut self) -> RefIndexableMut { - &mut self.observers + RefIndexableMut::from(&mut self.observers) } } impl<'a, S, SP, OT> UsesState for TinyInstExecutor<'a, S, SP, OT> From 74a0ab02de87344bce9c33a55914933465154ce9 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 25 Apr 2024 16:58:33 +0200 Subject: [PATCH 13/31] horrible double-mutability things --- libafl/src/executors/differential.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libafl/src/executors/differential.rs b/libafl/src/executors/differential.rs index 833bd2e623..1104822d51 100644 --- a/libafl/src/executors/differential.rs +++ b/libafl/src/executors/differential.rs @@ -256,8 +256,8 @@ where fn observers_mut(&mut self) -> RefIndexableMut> { unsafe { self.observers.get().as_mut().unwrap().set( - &mut *self.primary.observers_mut(), - &mut *self.secondary.observers_mut(), + &*self.primary.observers_mut(), + &*self.secondary.observers_mut(), ); RefIndexableMut::from(self.observers.get().as_mut().unwrap()) } From 264911925aab1f8f26ba693a271a93ee69f929d6 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 25 Apr 2024 17:22:11 +0200 Subject: [PATCH 14/31] fixup nyx --- libafl_nyx/src/executor.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libafl_nyx/src/executor.rs b/libafl_nyx/src/executor.rs index 15106ff372..e7e993a485 100644 --- a/libafl_nyx/src/executor.rs +++ b/libafl_nyx/src/executor.rs @@ -11,7 +11,10 @@ use libafl::{ state::{HasExecutions, State, UsesState}, Error, }; -use libafl_bolts::AsSlice; +use libafl_bolts::{ + tuples::{RefIndexable, RefIndexableMut}, + AsSlice, +}; use libnyx::NyxReturnValue; use crate::helper::NyxHelper; @@ -147,10 +150,10 @@ where OT: ObserversTuple, { fn observers(&self) -> RefIndexable { - &self.observers + RefIndexable::from(&self.observers) } fn observers_mut(&mut self) -> RefIndexableMut { - &mut self.observers + RefIndexableMut::new(&mut self.observers) } } From 01b126bf0f222ef07b91b4b45ef05634ac2d54e2 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 25 Apr 2024 18:23:10 +0200 Subject: [PATCH 15/31] from not new --- fuzzers/forkserver_simple/src/main.rs | 7 +++---- libafl_nyx/src/executor.rs | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/fuzzers/forkserver_simple/src/main.rs b/fuzzers/forkserver_simple/src/main.rs index ff30bca52c..b59594be80 100644 --- a/fuzzers/forkserver_simple/src/main.rs +++ b/fuzzers/forkserver_simple/src/main.rs @@ -163,6 +163,8 @@ pub fn main() { // Create the executor for the forkserver let args = opt.arguments; + let observer_ref = edges_observer.type_ref(); + let mut tokens = Tokens::new(); let mut executor = ForkserverExecutor::builder() .program(opt.executable) @@ -177,10 +179,7 @@ pub fn main() { .unwrap(); if let Some(dynamic_map_size) = executor.coverage_map_size() { - executor - .observers_mut() - .match_name_mut::>, true, false>>("shared_mem") - .unwrap() + executor.observers_mut()[&observer_ref] .as_mut() .truncate(dynamic_map_size); } diff --git a/libafl_nyx/src/executor.rs b/libafl_nyx/src/executor.rs index e7e993a485..6527096837 100644 --- a/libafl_nyx/src/executor.rs +++ b/libafl_nyx/src/executor.rs @@ -154,6 +154,6 @@ where } fn observers_mut(&mut self) -> RefIndexableMut { - RefIndexableMut::new(&mut self.observers) + RefIndexableMut::from(&mut self.observers) } } From 32de86d06cc66b8d69147a6d85d7f47272a358f4 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 25 Apr 2024 21:22:15 +0200 Subject: [PATCH 16/31] forkserver_simple fixes --- fuzzers/forkserver_simple/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fuzzers/forkserver_simple/src/main.rs b/fuzzers/forkserver_simple/src/main.rs index b59594be80..b8af8085b9 100644 --- a/fuzzers/forkserver_simple/src/main.rs +++ b/fuzzers/forkserver_simple/src/main.rs @@ -12,7 +12,7 @@ use libafl::{ inputs::BytesInput, monitors::SimpleMonitor, mutators::{scheduled::havoc_mutations, tokens_mutations, StdScheduledMutator, Tokens}, - observers::{CanTrack, ExplicitTracking, HitcountsMapObserver, StdMapObserver, TimeObserver}, + observers::{CanTrack, HitcountsMapObserver, StdMapObserver, TimeObserver}, schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, stages::mutational::StdMutationalStage, state::{HasCorpus, StdState}, @@ -22,7 +22,7 @@ use libafl_bolts::{ current_nanos, rands::StdRand, shmem::{ShMem, ShMemProvider, UnixShMemProvider}, - tuples::{tuple_list, MatchName, Merge}, + tuples::{tuple_list, Merge, Referenceable}, AsSliceMut, Truncate, }; use nix::sys::signal::Signal; From 59e3a7757b790680f48794e4e305a8372e9a16e0 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 25 Apr 2024 23:03:54 +0200 Subject: [PATCH 17/31] dogfood: forkserver --- libafl/src/executors/differential.rs | 3 +++ libafl/src/executors/forkserver.rs | 21 ++++++++++++++++----- libafl_bolts/src/tuples.rs | 8 +++++++- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/libafl/src/executors/differential.rs b/libafl/src/executors/differential.rs index 1104822d51..93e6614a97 100644 --- a/libafl/src/executors/differential.rs +++ b/libafl/src/executors/differential.rs @@ -186,6 +186,7 @@ where B: MatchName, DOT: MatchName, { + #[allow(deprecated)] fn match_name(&self, name: &str) -> Option<&T> { if let Some(t) = self.primary.as_ref().match_name::(name) { Some(t) @@ -195,6 +196,8 @@ where self.differential.match_name::(name) } } + + #[allow(deprecated)] fn match_name_mut(&mut self, name: &str) -> Option<&mut T> { if let Some(t) = self.primary.as_mut().match_name_mut::(name) { Some(t) diff --git a/libafl/src/executors/forkserver.rs b/libafl/src/executors/forkserver.rs index fbd22602d1..cd79f8ae91 100644 --- a/libafl/src/executors/forkserver.rs +++ b/libafl/src/executors/forkserver.rs @@ -22,7 +22,7 @@ use libafl_bolts::{ fs::{get_unique_std_input_file, InputFile}, os::{dup2, pipes::Pipe}, shmem::{ShMem, ShMemProvider, UnixShMemProvider}, - tuples::{Prepend, RefIndexable, RefIndexableMut}, + tuples::{MatchNameRef, Prepend, RefIndexable, RefIndexableMut, Reference, Referenceable}, AsSlice, AsSliceMut, Truncate, }; use nix::{ @@ -497,6 +497,8 @@ where map: Option, phantom: PhantomData, map_size: Option, + #[cfg(feature = "regex")] + asan_obs: Reference, timeout: TimeSpec, } @@ -583,6 +585,8 @@ pub struct ForkserverExecutorBuilder<'a, SP> { real_map_size: i32, kill_signal: Option, timeout: Option, + #[cfg(feature = "regex")] + asan_obs: Option>, } impl<'a, SP> ForkserverExecutorBuilder<'a, SP> { @@ -631,6 +635,10 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> { phantom: PhantomData, map_size: self.map_size, timeout, + asan_obs: self + .asan_obs + .clone() + .unwrap_or(AsanBacktraceObserver::default().type_ref()), }) } @@ -688,6 +696,10 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> { phantom: PhantomData, map_size: self.map_size, timeout, + asan_obs: self + .asan_obs + .clone() + .unwrap_or(AsanBacktraceObserver::default().type_ref()), }) } @@ -1047,6 +1059,7 @@ impl<'a> ForkserverExecutorBuilder<'a, UnixShMemProvider> { max_input_size: MAX_INPUT_SIZE_DEFAULT, kill_signal: None, timeout: None, + asan_obs: None, } } @@ -1072,6 +1085,7 @@ impl<'a> ForkserverExecutorBuilder<'a, UnixShMemProvider> { max_input_size: MAX_INPUT_SIZE_DEFAULT, kill_signal: None, timeout: None, + asan_obs: None, } } } @@ -1160,10 +1174,7 @@ where if libc::WIFSIGNALED(self.forkserver().status()) { exit_kind = ExitKind::Crash; #[cfg(feature = "regex")] - if let Some(asan_observer) = self - .observers_mut() - .match_name_mut::("AsanBacktraceObserver") - { + if let Some(asan_observer) = self.observers.get_mut(&self.asan_obs) { asan_observer.parse_asan_output_from_asan_log_file(pid)?; } } diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index 269525ec5b..788019fbf2 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -459,8 +459,10 @@ where #[cfg(feature = "alloc")] pub trait MatchName { /// Match for a name and return the borrowed value + #[deprecated = "Use `.type_ref` and either `.get` (fallible access) or `[]` (infallible access) instead"] fn match_name(&self, name: &str) -> Option<&T>; /// Match for a name and return the mut borrowed value + #[deprecated = "Use `.type_ref` and either `.get` (fallible access) or `[]` (infallible access) instead"] fn match_name_mut(&mut self, name: &str) -> Option<&mut T>; } @@ -484,6 +486,7 @@ where if type_eq::() && name == self.0.name() { unsafe { (addr_of!(self.0) as *const T).as_ref() } } else { + #[allow(deprecated)] self.1.match_name::(name) } } @@ -492,6 +495,7 @@ where if type_eq::() && name == self.0.name() { unsafe { (addr_of_mut!(self.0) as *mut T).as_mut() } } else { + #[allow(deprecated)] self.1.match_name_mut::(name) } } @@ -558,7 +562,7 @@ pub trait Referenceable: Named { impl Referenceable for N where N: Named {} /// Object with the type T and the name associated with its concrete value -#[derive(Debug)] +#[derive(Clone, Debug)] #[cfg(feature = "alloc")] pub struct Reference { name: Cow<'static, str>, @@ -588,10 +592,12 @@ where M: MatchName, { fn get(&self, rf: &Reference) -> Option<&T> { + #[allow(deprecated)] self.match_name::(&rf.name) } fn get_mut(&mut self, rf: &Reference) -> Option<&mut T> { + #[allow(deprecated)] self.match_name_mut::(&rf.name) } } From 1909b12ed90bd5d6a10e5d8a413bafbbda325fcd Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 26 Apr 2024 00:37:08 +0200 Subject: [PATCH 18/31] mmmm yummy dogfood --- libafl/src/feedbacks/concolic.rs | 23 +++--- libafl/src/feedbacks/differential.rs | 46 ++++++----- libafl/src/feedbacks/list.rs | 27 +++---- libafl/src/feedbacks/map.rs | 54 +++++-------- libafl/src/feedbacks/mod.rs | 81 +++++++++---------- libafl/src/feedbacks/new_hash_feedback.rs | 25 +++--- libafl/src/feedbacks/stdio.rs | 44 ++++------- libafl/src/observers/list.rs | 7 +- libafl/src/observers/mod.rs | 9 --- libafl/src/schedulers/mod.rs | 9 ++- libafl/src/schedulers/powersched.rs | 24 +++--- libafl/src/schedulers/weighted.rs | 17 ++-- libafl/src/stages/calibrate.rs | 45 ++++------- libafl/src/stages/colorization.rs | 31 ++++---- libafl/src/stages/concolic.rs | 30 ++++--- libafl/src/stages/generalization.rs | 35 +++------ libafl/src/stages/tmin.rs | 62 ++++++++------- libafl_bolts/src/tuples.rs | 96 +++++++++-------------- 18 files changed, 296 insertions(+), 369 deletions(-) diff --git a/libafl/src/feedbacks/concolic.rs b/libafl/src/feedbacks/concolic.rs index 797e7ffe07..833e73d06f 100644 --- a/libafl/src/feedbacks/concolic.rs +++ b/libafl/src/feedbacks/concolic.rs @@ -6,7 +6,10 @@ use alloc::borrow::Cow; use core::{fmt::Debug, marker::PhantomData}; -use libafl_bolts::Named; +use libafl_bolts::{ + tuples::{MatchNameRef, Reference, Referenceable}, + Named, +}; use crate::{ corpus::Testcase, @@ -24,30 +27,30 @@ use crate::{ /// to be not interesting. /// Requires a [`ConcolicObserver`] to observe the concolic trace. #[derive(Debug)] -pub struct ConcolicFeedback { - name: Cow<'static, str>, +pub struct ConcolicFeedback<'map, S> { + obs_ref: Reference>, phantom: PhantomData, } -impl ConcolicFeedback { +impl<'map, S> ConcolicFeedback<'map, S> { /// Creates a concolic feedback from an observer #[allow(unused)] #[must_use] - pub fn from_observer(observer: &ConcolicObserver) -> Self { + pub fn from_observer(observer: &ConcolicObserver<'map>) -> Self { Self { - name: observer.name().clone(), + obs_ref: observer.type_ref(), phantom: PhantomData, } } } -impl Named for ConcolicFeedback { +impl Named for ConcolicFeedback<'_, S> { fn name(&self) -> &Cow<'static, str> { - &self.name + self.obs_ref.name() } } -impl Feedback for ConcolicFeedback +impl Feedback for ConcolicFeedback<'_, S> where S: State, { @@ -79,7 +82,7 @@ where EM: EventFirer, { if let Some(metadata) = observers - .match_name::(&self.name) + .get(&self.obs_ref) .map(ConcolicObserver::create_metadata_from_current_map) { testcase.metadata_map_mut().insert(metadata); diff --git a/libafl/src/feedbacks/differential.rs b/libafl/src/feedbacks/differential.rs index b8bca11f58..4770c3ebc9 100644 --- a/libafl/src/feedbacks/differential.rs +++ b/libafl/src/feedbacks/differential.rs @@ -7,7 +7,10 @@ use core::{ marker::PhantomData, }; -use libafl_bolts::{tuples::MatchName, Named}; +use libafl_bolts::{ + tuples::{MatchName, MatchNameRef, Reference, Referenceable}, + Named, +}; use serde::{Deserialize, Serialize}; use crate::{ @@ -55,12 +58,12 @@ where /// This feedback's name name: Cow<'static, str>, /// The first observer to compare against - o1_name: Cow<'static, str>, + o1_ref: Reference, /// The second observer to compare against - o2_name: Cow<'static, str>, + o2_ref: Reference, /// The function used to compare the two observers compare_fn: F, - phantomm: PhantomData<(O1, O2, I, S)>, + phantomm: PhantomData<(I, S)>, } impl DiffFeedback @@ -71,16 +74,17 @@ where { /// Create a new [`DiffFeedback`] using two observers and a test function. pub fn new(name: &'static str, o1: &O1, o2: &O2, compare_fn: F) -> Result { - let o1_name = o1.name().clone(); - let o2_name = o2.name().clone(); - if o1_name == o2_name { + let o1_ref = o1.type_ref(); + let o2_ref = o2.type_ref(); + if o1_ref.name() == o2_ref.name() { Err(Error::illegal_argument(format!( - "DiffFeedback: observer names must be different (both were {o1_name})" + "DiffFeedback: observer names must be different (both were {})", + o1_ref.name() ))) } else { Ok(Self { - o1_name, - o2_name, + o1_ref, + o2_ref, name: Cow::from(name), compare_fn, phantomm: PhantomData, @@ -101,8 +105,8 @@ where fn create_feedback(&self, _ctx: &T) -> DiffFeedback { Self { name: self.name.clone(), - o1_name: self.o1_name.clone(), - o2_name: self.o2_name.clone(), + o1_ref: self.o1_ref.clone(), + o2_ref: self.o2_ref.clone(), compare_fn: self.compare_fn.clone(), phantomm: self.phantomm, } @@ -127,11 +131,11 @@ where O2: Named, { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!( - f, - "DiffFeedback {{ name: {}, o1: {}, o2: {} }}", - self.name, self.o1_name, self.o2_name - ) + f.debug_struct("DiffFeedback") + .field("name", self.name()) + .field("o1", &self.o1_ref) + .field("o2", &self.o2_ref) + .finish_non_exhaustive() } } @@ -160,11 +164,11 @@ where Error::illegal_argument(format!("DiffFeedback: observer {name} not found")) } let o1: &O1 = observers - .match_name(&self.o1_name) - .ok_or_else(|| err(&self.o1_name))?; + .get(&self.o1_ref) + .ok_or_else(|| err(self.o1_ref.name()))?; let o2: &O2 = observers - .match_name(&self.o2_name) - .ok_or_else(|| err(&self.o2_name))?; + .get(&self.o2_ref) + .ok_or_else(|| err(self.o2_ref.name()))?; Ok((self.compare_fn)(o1, o2) == DiffResult::Diff) } diff --git a/libafl/src/feedbacks/list.rs b/libafl/src/feedbacks/list.rs index dad5c2fbb8..b77124f8fd 100644 --- a/libafl/src/feedbacks/list.rs +++ b/libafl/src/feedbacks/list.rs @@ -1,8 +1,11 @@ use alloc::borrow::Cow; -use core::{fmt::Debug, hash::Hash, marker::PhantomData}; +use core::{fmt::Debug, hash::Hash}; use hashbrown::HashSet; -use libafl_bolts::{Error, HasRefCnt, Named}; +use libafl_bolts::{ + tuples::{MatchNameRef, Reference, Referenceable}, + Error, HasRefCnt, Named, +}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use crate::{ @@ -70,10 +73,8 @@ pub struct ListFeedback where T: Hash + Eq, { - name: Cow<'static, str>, - observer_name: Cow<'static, str>, + obs_ref: Reference>, novelty: HashSet, - phantom: PhantomData, } libafl_bolts::impl_serdeany!( @@ -88,7 +89,7 @@ where { fn init_state(&mut self, state: &mut S) -> Result<(), Error> { // eprintln!("self.name {:#?}", &self.name); - state.add_named_metadata(&self.name, ListFeedbackMetadata::::default()); + state.add_named_metadata(self.name(), ListFeedbackMetadata::::default()); Ok(()) } #[allow(clippy::wrong_self_convention)] @@ -105,15 +106,13 @@ where OT: ObserversTuple, { // TODO Replace with match_name_type when stable - let observer = observers - .match_name::>(&self.observer_name) - .unwrap(); + let observer = observers.get(&self.obs_ref).unwrap(); // TODO register the list content in a testcase metadata self.novelty.clear(); // can't fail let history_set = state .named_metadata_map_mut() - .get_mut::>(&self.name) + .get_mut::>(self.name()) .unwrap(); for v in observer.list() { if !history_set.set.contains(v) { @@ -136,7 +135,7 @@ where { let history_set = state .named_metadata_map_mut() - .get_mut::>(&self.name) + .get_mut::>(self.name()) .unwrap(); for v in &self.novelty { @@ -152,7 +151,7 @@ where { #[inline] fn name(&self) -> &Cow<'static, str> { - &self.name + self.obs_ref.name() } } @@ -164,10 +163,8 @@ where #[must_use] pub fn new(observer: &ListObserver) -> Self { Self { - name: observer.name().clone(), - observer_name: observer.name().clone(), + obs_ref: observer.type_ref(), novelty: HashSet::::new(), - phantom: PhantomData, } } } diff --git a/libafl/src/feedbacks/map.rs b/libafl/src/feedbacks/map.rs index c0ead2010e..c7bf52cee2 100644 --- a/libafl/src/feedbacks/map.rs +++ b/libafl/src/feedbacks/map.rs @@ -9,7 +9,10 @@ use core::{ ops::{BitAnd, BitOr}, }; -use libafl_bolts::{AsIter, AsSlice, AsSliceMut, HasRefCnt, Named}; +use libafl_bolts::{ + tuples::{MatchNameRef, Reference, Referenceable}, + AsIter, AsSlice, AsSliceMut, HasRefCnt, Named, +}; use num_traits::PrimInt; use serde::{de::DeserializeOwned, Deserialize, Serialize}; @@ -17,10 +20,10 @@ use crate::{ corpus::Testcase, events::{Event, EventFirer}, executors::ExitKind, - feedbacks::{Feedback, HasObserverName}, + feedbacks::{Feedback, HasObserverReference}, inputs::UsesInput, monitors::{AggregatorOps, UserStats, UserStatsValue}, - observers::{CanTrack, MapObserver, Observer, ObserversTuple, UsesObserver}, + observers::{CanTrack, MapObserver, ObserversTuple}, state::State, Error, HasMetadata, HasNamedMetadata, }; @@ -386,21 +389,13 @@ pub struct MapFeedback { /// Name identifier of this instance name: Cow<'static, str>, /// Name identifier of the observer - observer_name: Cow<'static, str>, + map_ref: Reference, /// Name of the feedback as shown in the `UserStats` stats_name: Cow<'static, str>, /// Phantom Data of Reducer phantom: PhantomData<(C, N, O, R, S, T)>, } -impl UsesObserver for MapFeedback -where - S: UsesInput, - C: AsRef + Observer, -{ - type Observer = C; -} - impl Feedback for MapFeedback where N: IsNovel, @@ -408,7 +403,7 @@ where R: Reducer, S: State + HasNamedMetadata, T: Default + Copy + Serialize + for<'de> Deserialize<'de> + PartialEq + Debug + 'static, - C: CanTrack + AsRef, + C: CanTrack + AsRef + Named, { fn init_state(&mut self, state: &mut S) -> Result<(), Error> { // Initialize `MapFeedbackMetadata` with an empty vector and add it to the state. @@ -464,10 +459,7 @@ where let meta = MapNoveltiesMetadata::new(novelties); testcase.add_metadata(meta); } - let observer = observers - .match_name::(&self.observer_name) - .unwrap() - .as_ref(); + let observer = observers.get(&self.map_ref).unwrap().as_ref(); let initial = observer.initial(); let map_state = state .named_metadata_map_mut() @@ -551,7 +543,7 @@ where O: MapObserver + AsSlice, for<'it> O: AsIter<'it, Item = u8>, S: State + HasNamedMetadata, - C: CanTrack + AsRef, + C: CanTrack + AsRef + Named, { #[allow(clippy::wrong_self_convention)] #[allow(clippy::needless_range_loop)] @@ -572,10 +564,7 @@ where let mut interesting = false; // TODO Replace with match_name_type when stable - let observer = observers - .match_name::(&self.observer_name) - .unwrap() - .as_ref(); + let observer = observers.get(&self.map_ref).unwrap().as_ref(); let map_state = state .named_metadata_map_mut() @@ -673,14 +662,16 @@ impl Named for MapFeedback { } } -impl HasObserverName for MapFeedback +impl HasObserverReference for MapFeedback where O: Named, C: AsRef, { + type Observer = C; + #[inline] - fn observer_name(&self) -> &Cow<'static, str> { - &self.observer_name + fn observer_ref(&self) -> &Reference { + &self.map_ref } } @@ -701,16 +692,15 @@ where for<'it> O: AsIter<'it, Item = T>, N: IsNovel, S: UsesInput + HasNamedMetadata, - C: CanTrack + AsRef, + C: CanTrack + AsRef + Named, { /// Create new `MapFeedback` #[must_use] pub fn new(map_observer: &C) -> Self { - let map_observer = map_observer.as_ref(); Self { novelties: if C::NOVELTIES { Some(vec![]) } else { None }, name: map_observer.name().clone(), - observer_name: map_observer.name().clone(), + map_ref: map_observer.type_ref(), stats_name: create_stats_name(map_observer.name()), phantom: PhantomData, } @@ -722,10 +712,9 @@ where #[must_use] pub fn with_name(name: &'static str, map_observer: &C) -> Self { let name = Cow::from(name); - let map_observer = map_observer.as_ref(); Self { novelties: if C::NOVELTIES { Some(vec![]) } else { None }, - observer_name: map_observer.name().clone(), + map_ref: map_observer.type_ref(), stats_name: create_stats_name(&name), name, phantom: PhantomData, @@ -749,10 +738,7 @@ where { let mut interesting = false; // TODO Replace with match_name_type when stable - let observer = observers - .match_name::(&self.observer_name) - .unwrap() - .as_ref(); + let observer = observers.get(&self.map_ref).unwrap().as_ref(); let map_state = state .named_metadata_map_mut() diff --git a/libafl/src/feedbacks/mod.rs b/libafl/src/feedbacks/mod.rs index fb57a35083..16a5da5700 100644 --- a/libafl/src/feedbacks/mod.rs +++ b/libafl/src/feedbacks/mod.rs @@ -4,43 +4,27 @@ // TODO: make S of Feedback an associated type when specialisation + AT is stable -pub mod map; - use alloc::borrow::Cow; - -pub use map::*; - -pub mod differential; -pub use differential::DiffFeedback; -#[cfg(feature = "std")] -pub mod concolic; -#[cfg(feature = "std")] -pub use concolic::ConcolicFeedback; - -#[cfg(feature = "std")] -pub mod new_hash_feedback; -#[cfg(feature = "std")] -pub use new_hash_feedback::NewHashFeedback; -#[cfg(feature = "std")] -pub use new_hash_feedback::NewHashFeedbackMetadata; - -#[cfg(feature = "nautilus")] -pub mod nautilus; -#[cfg(feature = "std")] -pub mod stdio; -pub mod transferred; - -/// The module for list feedback -pub mod list; use core::{ fmt::{self, Debug, Formatter}, marker::PhantomData, }; -use libafl_bolts::Named; +#[cfg(feature = "std")] +pub use concolic::ConcolicFeedback; +pub use differential::DiffFeedback; +use libafl_bolts::{ + tuples::{MatchNameRef, Reference, Referenceable}, + Named, +}; pub use list::*; +pub use map::*; #[cfg(feature = "nautilus")] pub use nautilus::*; +#[cfg(feature = "std")] +pub use new_hash_feedback::NewHashFeedback; +#[cfg(feature = "std")] +pub use new_hash_feedback::NewHashFeedbackMetadata; use serde::{Deserialize, Serialize}; use crate::{ @@ -52,6 +36,22 @@ use crate::{ Error, }; +pub mod map; + +#[cfg(feature = "std")] +pub mod concolic; +pub mod differential; +#[cfg(feature = "nautilus")] +pub mod nautilus; +#[cfg(feature = "std")] +pub mod new_hash_feedback; +#[cfg(feature = "std")] +pub mod stdio; +pub mod transferred; + +/// The module for list feedback +pub mod list; + /// Feedbacks evaluate the observers. /// Basically, they reduce the information provided by an observer to a value, /// indicating the "interestingness" of the last run. @@ -138,9 +138,12 @@ where } /// Has an associated observer name (mostly used to retrieve the observer with `MatchName` from an `ObserverTuple`) -pub trait HasObserverName { +pub trait HasObserverReference { + /// The observer for which we hold a reference + type Observer: ?Sized; + /// The name associated with the observer - fn observer_name(&self) -> &Cow<'static, str>; + fn observer_ref(&self) -> &Reference; } /// A combined feedback consisting of multiple [`Feedback`]s @@ -931,7 +934,7 @@ pub type TimeoutFeedbackFactory = DefaultFeedbackFactory; /// It decides, if the given [`TimeObserver`] value of a run is interesting. #[derive(Serialize, Deserialize, Clone, Debug)] pub struct TimeFeedback { - name: Cow<'static, str>, + obs_ref: Reference, } impl Feedback for TimeFeedback @@ -968,7 +971,7 @@ where OT: ObserversTuple, EM: EventFirer, { - let observer = observers.match_name::(self.name()).unwrap(); + let observer = observers.get(&self.obs_ref).unwrap(); *testcase.exec_time_mut() = *observer.last_runtime(); Ok(()) } @@ -983,24 +986,16 @@ where impl Named for TimeFeedback { #[inline] fn name(&self) -> &Cow<'static, str> { - &self.name + self.obs_ref.name() } } impl TimeFeedback { - /// Creates a new [`TimeFeedback`], deciding if the value of a [`TimeObserver`] with the given `name` of a run is interesting. - #[must_use] - pub fn new(name: &'static str) -> Self { - Self { - name: Cow::from(name), - } - } - /// Creates a new [`TimeFeedback`], deciding if the given [`TimeObserver`] value of a run is interesting. #[must_use] - pub fn with_observer(observer: &TimeObserver) -> Self { + pub fn new(observer: &TimeObserver) -> Self { Self { - name: observer.name().clone(), + obs_ref: observer.type_ref(), } } } diff --git a/libafl/src/feedbacks/new_hash_feedback.rs b/libafl/src/feedbacks/new_hash_feedback.rs index 366e41ccc4..65a60f12e4 100644 --- a/libafl/src/feedbacks/new_hash_feedback.rs +++ b/libafl/src/feedbacks/new_hash_feedback.rs @@ -4,13 +4,16 @@ use alloc::{borrow::Cow, string::ToString}; use std::{fmt::Debug, marker::PhantomData}; use hashbrown::HashSet; -use libafl_bolts::Named; +use libafl_bolts::{ + tuples::{MatchNameRef, Reference, Referenceable}, + Named, +}; use serde::{Deserialize, Serialize}; use crate::{ events::EventFirer, executors::ExitKind, - feedbacks::{Feedback, HasObserverName}, + feedbacks::{Feedback, HasObserverReference}, inputs::UsesInput, observers::{ObserverWithHashField, ObserversTuple}, state::State, @@ -79,10 +82,10 @@ impl HashSetState for NewHashFeedbackMetadata { #[derive(Serialize, Deserialize, Clone, Debug)] pub struct NewHashFeedback { name: Cow<'static, str>, - observer_name: Cow<'static, str>, + o_ref: Reference, /// Initial capacity of hash set capacity: usize, - o_type: PhantomData<(O, S)>, + phantom: PhantomData, } impl Feedback for NewHashFeedback @@ -112,7 +115,7 @@ where OT: ObserversTuple, { let observer = observers - .match_name::(&self.observer_name) + .get(&self.o_ref) .expect("A NewHashFeedback needs a BacktraceObserver"); let backtrace_state = state @@ -142,10 +145,12 @@ impl Named for NewHashFeedback { } } -impl HasObserverName for NewHashFeedback { +impl HasObserverReference for NewHashFeedback { + type Observer = O; + #[inline] - fn observer_name(&self) -> &Cow<'static, str> { - &self.observer_name + fn observer_ref(&self) -> &Reference { + &self.o_ref } } @@ -171,9 +176,9 @@ where pub fn with_capacity(observer: &O, capacity: usize) -> Self { Self { name: Cow::from(NEWHASHFEEDBACK_PREFIX.to_string() + observer.name()), - observer_name: observer.name().clone(), + o_ref: observer.type_ref(), capacity, - o_type: PhantomData, + phantom: PhantomData, } } } diff --git a/libafl/src/feedbacks/stdio.rs b/libafl/src/feedbacks/stdio.rs index d79b41ac90..f073dd5696 100644 --- a/libafl/src/feedbacks/stdio.rs +++ b/libafl/src/feedbacks/stdio.rs @@ -2,7 +2,11 @@ use alloc::{borrow::Cow, string::String}; -use libafl_bolts::{impl_serdeany, Named}; +use libafl_bolts::{ + impl_serdeany, + tuples::{MatchNameRef, Reference, Referenceable}, + Named, +}; use serde::{Deserialize, Serialize}; use crate::{ @@ -28,7 +32,7 @@ impl_serdeany!(StdOutMetadata); /// is never interesting (use with an OR). #[derive(Serialize, Deserialize, Clone, Debug)] pub struct StdOutToMetadataFeedback { - name: Cow<'static, str>, + o_ref: Reference, } impl Feedback for StdOutToMetadataFeedback @@ -66,7 +70,7 @@ where EM: EventFirer, { let observer = observers - .match_name::(self.name()) + .get(&self.o_ref) .ok_or(Error::illegal_state("StdOutObserver is missing"))?; let buffer = observer .stdout @@ -91,25 +95,16 @@ where impl Named for StdOutToMetadataFeedback { #[inline] fn name(&self) -> &Cow<'static, str> { - &self.name + self.o_ref.name() } } impl StdOutToMetadataFeedback { - /// Creates a new [`StdOutToMetadataFeedback`]. The provided `name` is - /// used to look up the observer. - #[must_use] - pub fn new(name: &'static str) -> Self { - Self { - name: Cow::from(name), - } - } - /// Creates a new [`StdOutToMetadataFeedback`]. #[must_use] - pub fn with_observer(observer: &StdOutObserver) -> Self { + pub fn new(observer: &StdOutObserver) -> Self { Self { - name: observer.name().clone(), + o_ref: observer.type_ref(), } } } @@ -127,7 +122,7 @@ impl_serdeany!(StdErrMetadata); /// is never interesting (use with an OR). #[derive(Serialize, Deserialize, Clone, Debug)] pub struct StdErrToMetadataFeedback { - name: Cow<'static, str>, + o_ref: Reference, } impl Feedback for StdErrToMetadataFeedback @@ -165,7 +160,7 @@ where EM: EventFirer, { let observer = observers - .match_name::(self.name()) + .get(&self.o_ref) .ok_or(Error::illegal_state("StdErrObserver is missing"))?; let buffer = observer .stderr @@ -190,25 +185,16 @@ where impl Named for StdErrToMetadataFeedback { #[inline] fn name(&self) -> &Cow<'static, str> { - &self.name + self.o_ref.name() } } impl StdErrToMetadataFeedback { - /// Creates a new [`StdErrToMetadataFeedback`]. The provided `name` is - /// used to look up the observer. - #[must_use] - pub fn new(name: &'static str) -> Self { - Self { - name: Cow::from(name), - } - } - /// Creates a new [`StdErrToMetadataFeedback`]. #[must_use] - pub fn with_observer(observer: &StdErrObserver) -> Self { + pub fn new(observer: &StdErrObserver) -> Self { Self { - name: observer.name().clone(), + o_ref: observer.type_ref(), } } } diff --git a/libafl/src/observers/list.rs b/libafl/src/observers/list.rs index 84fc2caeb3..99a50e96f5 100644 --- a/libafl/src/observers/list.rs +++ b/libafl/src/observers/list.rs @@ -8,12 +8,9 @@ use crate::{inputs::UsesInput, observers::Observer}; /// A simple observer with a list of things. #[derive(Serialize, Deserialize, Debug)] -#[serde(bound = "T: serde::de::DeserializeOwned")] +#[serde(bound = "T: serde::de::DeserializeOwned + serde::Serialize")] #[allow(clippy::unsafe_derive_deserialize)] -pub struct ListObserver -where - T: Debug + Serialize, -{ +pub struct ListObserver { name: Cow<'static, str>, /// The list list: OwnedMutPtr>, diff --git a/libafl/src/observers/mod.rs b/libafl/src/observers/mod.rs index 63b3f2801c..5158a9a6b0 100644 --- a/libafl/src/observers/mod.rs +++ b/libafl/src/observers/mod.rs @@ -38,15 +38,6 @@ pub use value::*; use crate::{executors::ExitKind, inputs::UsesInput, state::UsesState, Error}; -/// Something that uses observer like mapfeedbacks -pub trait UsesObserver -where - S: UsesInput, -{ - /// The observer type used - type Observer: Observer; -} - /// Observers observe different information about the target. /// They can then be used by various sorts of feedback. pub trait Observer: Named diff --git a/libafl/src/schedulers/mod.rs b/libafl/src/schedulers/mod.rs index 8905f224af..ace507ad22 100644 --- a/libafl/src/schedulers/mod.rs +++ b/libafl/src/schedulers/mod.rs @@ -27,7 +27,10 @@ pub mod weighted; pub use weighted::{StdWeightedScheduler, WeightedScheduler}; pub mod tuneable; -use libafl_bolts::rands::Rand; +use libafl_bolts::{ + rands::Rand, + tuples::{MatchNameRef, Reference}, +}; pub use tuneable::*; use crate::{ @@ -79,7 +82,7 @@ where fn set_last_hash(&mut self, value: usize); /// Get the observer map observer name - fn map_observer_name(&self) -> &str; + fn map_observer_ref(&self) -> &Reference; /// Called when a [`Testcase`] is added to the corpus fn on_add_metadata(&self, state: &mut Self::State, idx: CorpusId) -> Result<(), Error> { @@ -118,7 +121,7 @@ where OT: ObserversTuple, { let observer = observers - .match_name::(self.map_observer_name()) + .get(self.map_observer_ref()) .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))? .as_ref(); diff --git a/libafl/src/schedulers/powersched.rs b/libafl/src/schedulers/powersched.rs index e0b8e18506..5d84e2713f 100644 --- a/libafl/src/schedulers/powersched.rs +++ b/libafl/src/schedulers/powersched.rs @@ -1,12 +1,12 @@ //! The queue corpus scheduler for power schedules. -use alloc::{ - string::{String, ToString}, - vec::Vec, -}; +use alloc::vec::Vec; use core::{marker::PhantomData, time::Duration}; -use libafl_bolts::Named; +use libafl_bolts::{ + tuples::{Reference, Referenceable}, + Named, +}; use serde::{Deserialize, Serialize}; use crate::{ @@ -173,9 +173,9 @@ pub enum PowerSchedule { #[derive(Clone, Debug)] pub struct PowerQueueScheduler { strat: PowerSchedule, - map_observer_name: String, + map_observer_ref: Reference, last_hash: usize, - phantom: PhantomData<(C, O, S)>, + phantom: PhantomData<(O, S)>, } impl UsesState for PowerQueueScheduler @@ -226,8 +226,8 @@ where self.last_hash = hash; } - fn map_observer_name(&self) -> &str { - &self.map_observer_name + fn map_observer_ref(&self) -> &Reference { + &self.map_observer_ref } } @@ -256,9 +256,9 @@ where fn next(&mut self, state: &mut Self::State) -> Result { if state.corpus().count() == 0 { - Err(Error::empty(String::from( + Err(Error::empty( "No entries in corpus. This often implies the target is not properly instrumented.", - ))) + )) } else { let id = match state.corpus().current() { Some(cur) => { @@ -305,7 +305,7 @@ where } PowerQueueScheduler { strat, - map_observer_name: map_observer.name().to_string(), + map_observer_ref: map_observer.type_ref(), last_hash: 0, phantom: PhantomData, } diff --git a/libafl/src/schedulers/weighted.rs b/libafl/src/schedulers/weighted.rs index c5b58ad818..78a7aa8999 100644 --- a/libafl/src/schedulers/weighted.rs +++ b/libafl/src/schedulers/weighted.rs @@ -1,11 +1,10 @@ //! The queue corpus scheduler with weighted queue item selection [from AFL++](https://github.com/AFLplusplus/AFLplusplus/blob/1d4f1e48797c064ee71441ba555b29fc3f467983/src/afl-fuzz-queue.c#L32). //! This queue corpus scheduler needs calibration stage. -use alloc::string::{String, ToString}; use core::marker::PhantomData; use hashbrown::HashMap; -use libafl_bolts::{rands::Rand, Named}; +use libafl_bolts::{bolts_prelude::Reference, rands::Rand, tuples::Referenceable, Named}; use serde::{Deserialize, Serialize}; use crate::{ @@ -95,9 +94,9 @@ libafl_bolts::impl_serdeany!(WeightedScheduleMetadata); pub struct WeightedScheduler { table_invalidated: bool, strat: Option, - map_observer_name: String, + map_observer_ref: Reference, last_hash: usize, - phantom: PhantomData<(C, F, O, S)>, + phantom: PhantomData<(F, O, S)>, } impl WeightedScheduler @@ -121,7 +120,7 @@ where Self { strat, - map_observer_name: map_observer.name().to_string(), + map_observer_ref: map_observer.type_ref(), last_hash: 0, table_invalidated: true, phantom: PhantomData, @@ -271,8 +270,8 @@ where self.last_hash = hash; } - fn map_observer_name(&self) -> &str { - &self.map_observer_name + fn map_observer_ref(&self) -> &Reference { + &self.map_observer_ref } } @@ -310,9 +309,9 @@ where } let corpus_counts = state.corpus().count(); if corpus_counts == 0 { - Err(Error::empty(String::from( + Err(Error::empty( "No entries in corpus. This often implies the target is not properly instrumented.", - ))) + )) } else { let s = random_corpus_id!(state.corpus(), state.rand_mut()); diff --git a/libafl/src/stages/calibrate.rs b/libafl/src/stages/calibrate.rs index 49a50a8392..5077a908bc 100644 --- a/libafl/src/stages/calibrate.rs +++ b/libafl/src/stages/calibrate.rs @@ -1,14 +1,10 @@ //! The calibration stage. The fuzzer measures the average exec time and the bitmap size. -use alloc::{ - borrow::Cow, - string::{String, ToString}, - vec::Vec, -}; +use alloc::{borrow::Cow, vec::Vec}; use core::{fmt::Debug, marker::PhantomData, time::Duration}; use hashbrown::HashSet; -use libafl_bolts::{current_time, impl_serdeany, AsIter, Named}; +use libafl_bolts::{current_time, impl_serdeany, tuples::Reference, AsIter, Named}; use num_traits::Bounded; use serde::{Deserialize, Serialize}; @@ -16,10 +12,10 @@ use crate::{ corpus::{Corpus, SchedulerTestcaseMetadata}, events::{Event, EventFirer, LogSeverity}, executors::{Executor, ExitKind, HasObservers}, - feedbacks::{map::MapFeedbackMetadata, HasObserverName}, + feedbacks::{map::MapFeedbackMetadata, HasObserverReference}, fuzzer::Evaluator, monitors::{AggregatorOps, UserStats, UserStatsValue}, - observers::{MapObserver, ObserversTuple, UsesObserver}, + observers::{MapObserver, ObserversTuple}, schedulers::powersched::SchedulerMetadata, stages::{ExecutionCountRestartHelper, Stage}, state::{HasCorpus, HasCurrentTestcase, HasExecutions, State, UsesState}, @@ -66,13 +62,13 @@ impl UnstableEntriesMetadata { /// The calibration stage will measure the average exec time and the target's stability for this input. #[derive(Clone, Debug)] pub struct CalibrationStage { - map_observer_name: String, - map_name: String, + map_observer_ref: Reference, + map_name: Cow<'static, str>, stage_max: usize, /// If we should track stability track_stability: bool, restart_helper: ExecutionCountRestartHelper, - phantom: PhantomData<(C, O, OT, S)>, + phantom: PhantomData<(O, OT, S)>, } const CAL_STAGE_START: usize = 4; // AFL++'s CAL_CYCLES_FAST + 1 @@ -147,10 +143,7 @@ where .observers_mut() .post_exec_all(state, &input, &exit_kind)?; - let map_first = &executor - .observers() - .match_name::(&self.map_observer_name) - .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))? + let map_first = &executor.observers()[&self.map_observer_ref] .as_ref() .to_vec(); @@ -191,10 +184,7 @@ where .post_exec_all(state, &input, &exit_kind)?; if self.track_stability { - let map = &executor - .observers() - .match_name::(&self.map_observer_name) - .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))? + let map = &executor.observers()[&self.map_observer_ref] .as_ref() .to_vec(); @@ -249,10 +239,7 @@ where // If weighted scheduler or powerscheduler is used, update it if state.has_metadata::() { let observers = executor.observers(); - let map = observers - .match_name::(&self.map_observer_name) - .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))? - .as_ref(); + let map = observers[&self.map_observer_ref].as_ref(); let mut bitmap_size = map.count_bytes(); assert!(bitmap_size != 0); @@ -351,13 +338,13 @@ where #[must_use] pub fn new(map_feedback: &F) -> Self where - F: HasObserverName + Named + UsesObserver, + F: HasObserverReference + Named, for<'it> O: AsIter<'it, Item = O::Entry>, C: AsRef, { Self { - map_observer_name: map_feedback.observer_name().to_string(), - map_name: map_feedback.name().to_string(), + map_observer_ref: map_feedback.observer_ref().clone(), + map_name: map_feedback.name().clone(), stage_max: CAL_STAGE_START, track_stability: true, restart_helper: ExecutionCountRestartHelper::default(), @@ -369,13 +356,13 @@ where #[must_use] pub fn ignore_stability(map_feedback: &F) -> Self where - F: HasObserverName + Named + UsesObserver, + F: HasObserverReference + Named, for<'it> O: AsIter<'it, Item = O::Entry>, C: AsRef, { Self { - map_observer_name: map_feedback.observer_name().to_string(), - map_name: map_feedback.name().to_string(), + map_observer_ref: map_feedback.observer_ref().clone(), + map_name: map_feedback.name().clone(), stage_max: CAL_STAGE_START, track_stability: false, restart_helper: ExecutionCountRestartHelper::default(), diff --git a/libafl/src/stages/colorization.rs b/libafl/src/stages/colorization.rs index a07e89a026..cc1f2e0b0a 100644 --- a/libafl/src/stages/colorization.rs +++ b/libafl/src/stages/colorization.rs @@ -1,8 +1,12 @@ //! The colorization stage from `colorization()` in afl++ -use alloc::{borrow::Cow, collections::binary_heap::BinaryHeap, string::ToString, vec::Vec}; +use alloc::{borrow::Cow, collections::binary_heap::BinaryHeap, vec::Vec}; use core::{cmp::Ordering, fmt::Debug, marker::PhantomData, ops::Range}; -use libafl_bolts::{rands::Rand, tuples::MatchName, Named}; +use libafl_bolts::{ + rands::Rand, + tuples::{Reference, Referenceable}, + Named, +}; use serde::{Deserialize, Serialize}; use crate::{ @@ -51,9 +55,9 @@ impl Ord for Earlier { /// The mutational stage using power schedules #[derive(Clone, Debug)] pub struct ColorizationStage { - map_observer_name: Cow<'static, str>, + map_observer_ref: Reference, #[allow(clippy::type_complexity)] - phantom: PhantomData<(C, E, EM, O, E, Z)>, + phantom: PhantomData<(E, EM, O, E, Z)>, } impl UsesState for ColorizationStage @@ -68,7 +72,7 @@ where E: UsesState, { fn name(&self) -> &Cow<'static, str> { - &self.map_observer_name + self.map_observer_ref.name() } } @@ -92,7 +96,7 @@ where manager: &mut EM, ) -> Result<(), Error> { // Run with the mutated input - Self::colorize(fuzzer, executor, state, manager, &self.map_observer_name)?; + Self::colorize(fuzzer, executor, state, manager, &self.map_observer_ref)?; Ok(()) } @@ -164,7 +168,7 @@ where executor: &mut E, state: &mut E::State, manager: &mut EM, - name: &str, + obs_ref: &Reference, ) -> Result { let mut input = state.current_input_cloned()?; // The backup of the input @@ -179,7 +183,7 @@ where // Idea: No need to do this every time let orig_hash = - Self::get_raw_map_hash_run(fuzzer, executor, state, manager, consumed_input, name)?; + Self::get_raw_map_hash_run(fuzzer, executor, state, manager, consumed_input, obs_ref)?; let changed_bytes = changed.bytes_mut(); let input_len = changed_bytes.len(); @@ -224,7 +228,7 @@ where state, manager, consumed_input, - name, + obs_ref, )?; if orig_hash == changed_hash { @@ -297,7 +301,7 @@ where /// Creates a new [`ColorizationStage`] pub fn new(map_observer: &C) -> Self { Self { - map_observer_name: map_observer.name().clone(), + map_observer_ref: map_observer.type_ref(), phantom: PhantomData, } } @@ -309,17 +313,14 @@ where state: &mut E::State, manager: &mut EM, input: E::Input, - name: &str, + obs_ref: &Reference, ) -> Result { executor.observers_mut().pre_exec_all(state, &input)?; let exit_kind = executor.run_target(fuzzer, state, manager, &input)?; let observers = executor.observers(); - let observer = observers - .match_name::(name) - .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))? - .as_ref(); + let observer = observers[obs_ref].as_ref(); let hash = observer.hash_simple() as usize; diff --git a/libafl/src/stages/concolic.rs b/libafl/src/stages/concolic.rs index f2d3a1245e..4367ebe208 100644 --- a/libafl/src/stages/concolic.rs +++ b/libafl/src/stages/concolic.rs @@ -2,13 +2,16 @@ //! and use the results for fuzzer input and mutations. //! -use alloc::{borrow::Cow, string::String}; +use alloc::borrow::Cow; #[cfg(feature = "concolic_mutation")] use alloc::{string::ToString, vec::Vec}; #[cfg(feature = "concolic_mutation")] use core::marker::PhantomData; -use libafl_bolts::{tuples::MatchName, Named}; +use libafl_bolts::{ + tuples::{MatchNameRef, Reference, Referenceable}, + Named, +}; #[cfg(all(feature = "concolic_mutation", feature = "introspection"))] use crate::monitors::PerfFeature; @@ -34,26 +37,26 @@ use crate::{ /// Wraps a [`TracingStage`] to add concolic observing. #[derive(Clone, Debug)] -pub struct ConcolicTracingStage { +pub struct ConcolicTracingStage<'a, EM, TE, Z> { inner: TracingStage, - observer_name: String, + obs_ref: Reference>, } -impl UsesState for ConcolicTracingStage +impl UsesState for ConcolicTracingStage<'_, EM, TE, Z> where TE: UsesState, { type State = TE::State; } -impl Named for ConcolicTracingStage { +impl Named for ConcolicTracingStage<'_, EM, TE, Z> { fn name(&self) -> &Cow<'static, str> { static NAME: Cow<'static, str> = Cow::Borrowed("ConcolicTracingStage"); &NAME } } -impl Stage for ConcolicTracingStage +impl Stage for ConcolicTracingStage<'_, EM, TE, Z> where E: UsesState, EM: UsesState, @@ -70,12 +73,7 @@ where manager: &mut EM, ) -> Result<(), Error> { self.inner.trace(fuzzer, state, manager)?; - if let Some(observer) = self - .inner - .executor() - .observers() - .match_name::(&self.observer_name) - { + if let Some(observer) = self.inner.executor().observers().get(&self.obs_ref) { let metadata = observer.create_metadata_from_current_map(); state .current_testcase_mut()? @@ -94,13 +92,13 @@ where } } -impl ConcolicTracingStage { +impl<'a, EM, TE, Z> ConcolicTracingStage<'a, EM, TE, Z> { /// Creates a new default tracing stage using the given [`Executor`], observing traces from a /// [`ConcolicObserver`] with the given name. - pub fn new(inner: TracingStage, observer_name: String) -> Self { + pub fn new(inner: TracingStage, observer: &ConcolicObserver<'a>) -> Self { Self { inner, - observer_name, + obs_ref: observer.type_ref(), } } } diff --git a/libafl/src/stages/generalization.rs b/libafl/src/stages/generalization.rs index 67554e7b9c..9cbd9df74c 100644 --- a/libafl/src/stages/generalization.rs +++ b/libafl/src/stages/generalization.rs @@ -1,13 +1,12 @@ //! The tracing stage can trace the target and enrich a [`crate::corpus::Testcase`] with metadata, for example for `CmpLog`. -use alloc::{ - borrow::Cow, - string::{String, ToString}, - vec::Vec, -}; +use alloc::{borrow::Cow, vec::Vec}; use core::{fmt::Debug, marker::PhantomData}; -use libafl_bolts::{AsSlice, Named}; +use libafl_bolts::{ + tuples::{Reference, Referenceable}, + AsSlice, Named, +}; use crate::{ corpus::{Corpus, HasCurrentCorpusIdx}, @@ -44,9 +43,9 @@ fn find_next_char(list: &[Option], mut idx: usize, ch: u8) -> usize { /// A stage that runs a tracer executor #[derive(Clone, Debug)] pub struct GeneralizationStage { - map_observer_name: String, + map_observer_ref: Reference, #[allow(clippy::type_complexity)] - phantom: PhantomData<(C, EM, O, OT, Z)>, + phantom: PhantomData<(EM, O, OT, Z)>, } impl Named for GeneralizationStage { @@ -67,7 +66,7 @@ where impl Stage for GeneralizationStage where O: MapObserver, - C: CanTrack + AsRef, + C: CanTrack + AsRef + Named, E: Executor + HasObservers, E::Observers: ObserversTuple, E::State: @@ -339,7 +338,7 @@ impl GeneralizationStage where EM: UsesState, O: MapObserver, - C: CanTrack + AsRef, + C: CanTrack + AsRef + Named, OT: ObserversTuple, EM::State: UsesInput + HasExecutions + HasMetadata + HasCorpus, { @@ -348,16 +347,7 @@ where pub fn new(map_observer: &C) -> Self { require_novelties_tracking!("GeneralizationStage", C); Self { - map_observer_name: map_observer.as_ref().name().to_string(), - phantom: PhantomData, - } - } - - /// Create a new [`GeneralizationStage`] from name - #[must_use] - pub fn from_name(map_observer_name: &str) -> Self { - Self { - map_observer_name: map_observer_name.to_string(), + map_observer_ref: map_observer.type_ref(), phantom: PhantomData, } } @@ -391,10 +381,7 @@ where .post_exec_all(state, input, &exit_kind)?; mark_feature_time!(state, PerfFeature::PostExecObservers); - let cnt = executor - .observers() - .match_name::(&self.map_observer_name) - .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))? + let cnt = executor.observers()[&self.map_observer_ref] .as_ref() .how_many_set(novelties); diff --git a/libafl/src/stages/tmin.rs b/libafl/src/stages/tmin.rs index 18e208f529..5ca77b6057 100644 --- a/libafl/src/stages/tmin.rs +++ b/libafl/src/stages/tmin.rs @@ -4,13 +4,16 @@ use alloc::borrow::Cow; use core::{borrow::BorrowMut, fmt::Debug, hash::Hash, marker::PhantomData}; use ahash::RandomState; -use libafl_bolts::{HasLen, Named}; +use libafl_bolts::{ + tuples::{MatchNameRef, Reference, Referenceable}, + HasLen, Named, +}; use crate::{ corpus::{Corpus, HasCurrentCorpusIdx, Testcase}, events::EventFirer, executors::{Executor, ExitKind, HasObservers}, - feedbacks::{Feedback, FeedbackFactory, HasObserverName}, + feedbacks::{Feedback, FeedbackFactory, HasObserverReference}, inputs::UsesInput, mark_feature_time, mutators::{MutationResult, Mutator}, @@ -348,28 +351,31 @@ where /// A feedback which checks if the hash of the currently observed map is equal to the original hash /// provided #[derive(Clone, Debug)] -pub struct MapEqualityFeedback { +pub struct MapEqualityFeedback { name: Cow<'static, str>, - obs_name: Cow<'static, str>, + map_ref: Reference, orig_hash: u64, phantom: PhantomData<(M, S)>, } -impl Named for MapEqualityFeedback { +impl Named for MapEqualityFeedback { fn name(&self) -> &Cow<'static, str> { &self.name } } -impl HasObserverName for MapEqualityFeedback { - fn observer_name(&self) -> &Cow<'static, str> { - &self.obs_name +impl HasObserverReference for MapEqualityFeedback { + type Observer = C; + + fn observer_ref(&self) -> &Reference { + &self.map_ref } } -impl Feedback for MapEqualityFeedback +impl Feedback for MapEqualityFeedback where M: MapObserver, + C: AsRef, S: State, { fn is_interesting( @@ -385,52 +391,52 @@ where OT: ObserversTuple, { let obs = observers - .match_name::(self.observer_name()) + .get(self.observer_ref()) .expect("Should have been provided valid observer name."); - Ok(obs.hash_simple() == self.orig_hash) + Ok(obs.as_ref().hash_simple() == self.orig_hash) } } /// A feedback factory for ensuring that the maps for minimized inputs are the same #[derive(Debug, Clone)] -pub struct MapEqualityFactory { - obs_name: Cow<'static, str>, - phantom: PhantomData<(M, S)>, +pub struct MapEqualityFactory { + map_ref: Reference, + phantom: PhantomData<(C, M, S)>, } -impl MapEqualityFactory +impl MapEqualityFactory where M: MapObserver, + C: AsRef + Referenceable, { /// Creates a new map equality feedback for the given observer - pub fn with_observer(obs: &M) -> Self { + pub fn with_observer(obs: &C) -> Self { Self { - obs_name: obs.name().clone(), + map_ref: obs.type_ref(), phantom: PhantomData, } } } -impl HasObserverName for MapEqualityFactory { - fn observer_name(&self) -> &Cow<'static, str> { - &self.obs_name +impl HasObserverReference for MapEqualityFactory { + type Observer = C; + + fn observer_ref(&self) -> &Reference { + &self.map_ref } } -impl FeedbackFactory, S, OT> for MapEqualityFactory +impl FeedbackFactory, S, C> for MapEqualityFactory where M: MapObserver, - OT: ObserversTuple, + C: AsRef + Referenceable, S: State + Debug, { - fn create_feedback(&self, observers: &OT) -> MapEqualityFeedback { - let obs = observers - .match_name::(self.observer_name()) - .expect("Should have been provided valid observer name."); + fn create_feedback(&self, obs: &C) -> MapEqualityFeedback { MapEqualityFeedback { name: Cow::from("MapEq"), - obs_name: self.obs_name.clone(), - orig_hash: obs.hash_simple(), + map_ref: obs.type_ref(), + orig_hash: obs.as_ref().hash_simple(), phantom: PhantomData, } } diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index 788019fbf2..1eb97b949e 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -8,12 +8,15 @@ use core::any::type_name; use core::ops::{Deref, DerefMut}; use core::{ any::TypeId, + fmt::{Debug, Formatter}, marker::PhantomData, mem::transmute, ops::{Index, IndexMut}, ptr::{addr_of, addr_of_mut}, }; +#[cfg(feature = "alloc")] +use serde::{Deserialize, Serialize}; pub use tuple_list::{tuple_list, tuple_list_type, TupleList}; #[cfg(any(feature = "xxh3", feature = "alloc"))] @@ -261,7 +264,7 @@ where /// Returns the first element with the given type (dereference mut version) pub trait ExtractFirstRefType { - /// Returns the first element with the given type as borrow, or [`Option::None`] + /// Returns the first element with the given type as borrow, or [`None`] fn take<'a, T: 'static>(self) -> (Option<&'a T>, Self); } @@ -308,7 +311,7 @@ where /// Returns the first element with the given type (dereference mut version) pub trait ExtractFirstRefMutType { - /// Returns the first element with the given type as borrow, or [`Option::None`] + /// Returns the first element with the given type as borrow, or [`None`] fn take<'a, T: 'static>(self) -> (Option<&'a mut T>, Self); } @@ -477,6 +480,7 @@ impl MatchName for () { } #[cfg(feature = "alloc")] +#[allow(deprecated)] impl MatchName for (Head, Tail) where Head: Named, @@ -486,7 +490,6 @@ where if type_eq::() && name == self.0.name() { unsafe { (addr_of!(self.0) as *const T).as_ref() } } else { - #[allow(deprecated)] self.1.match_name::(name) } } @@ -495,56 +498,11 @@ where if type_eq::() && name == self.0.name() { unsafe { (addr_of_mut!(self.0) as *mut T).as_mut() } } else { - #[allow(deprecated)] self.1.match_name_mut::(name) } } } -/// Finds an element of a `type` by the given `name`. -#[cfg(feature = "alloc")] -pub trait MatchNameAndType { - /// Finds an element of a `type` by the given `name`, and returns a borrow, or [`Option::None`]. - fn match_name_type(&self, name: &str) -> Option<&T>; - /// Finds an element of a `type` by the given `name`, and returns a mut borrow, or [`Option::None`]. - fn match_name_type_mut(&mut self, name: &str) -> Option<&mut T>; -} - -#[cfg(feature = "alloc")] -impl MatchNameAndType for () { - fn match_name_type(&self, _name: &str) -> Option<&T> { - None - } - fn match_name_type_mut(&mut self, _name: &str) -> Option<&mut T> { - None - } -} - -#[cfg(feature = "alloc")] -impl MatchNameAndType for (Head, Tail) -where - Head: 'static + Named, - Tail: MatchNameAndType, -{ - fn match_name_type(&self, name: &str) -> Option<&T> { - // Switch this check to https://stackoverflow.com/a/60138532/7658998 when in stable and remove 'static - if TypeId::of::() == TypeId::of::() && name == self.0.name() { - unsafe { (addr_of!(self.0) as *const T).as_ref() } - } else { - self.1.match_name_type::(name) - } - } - - fn match_name_type_mut(&mut self, name: &str) -> Option<&mut T> { - // Switch this check to https://stackoverflow.com/a/60138532/7658998 when in stable and remove 'static - if TypeId::of::() == TypeId::of::() && name == self.0.name() { - unsafe { (addr_of_mut!(self.0) as *mut T).as_mut() } - } else { - self.1.match_name_type_mut::(name) - } - } -} - /// Structs that has `Reference ` /// You should use this when you want to avoid specifying types using `match_name_type_mut` #[cfg(feature = "alloc")] @@ -562,20 +520,45 @@ pub trait Referenceable: Named { impl Referenceable for N where N: Named {} /// Object with the type T and the name associated with its concrete value -#[derive(Clone, Debug)] +#[derive(Serialize, Deserialize)] #[cfg(feature = "alloc")] pub struct Reference { name: Cow<'static, str>, + #[serde(skip)] phantom: PhantomData, } #[cfg(feature = "alloc")] -impl Named for Reference { - fn name(&self) -> &Cow<'static, str> { +impl Reference { + /// Fetch the name of the referenced instance. + /// + /// We explicitly do *not* implement [`Named`], as this could potentially lead to confusion + /// where we make a [`Reference`] of a [`Reference`] as [`Named`] is blanket implemented. + pub fn name(&self) -> &Cow<'static, str> { &self.name } } +#[cfg(feature = "alloc")] +impl Clone for Reference { + fn clone(&self) -> Self { + Self { + name: self.name.clone(), + phantom: PhantomData, + } + } +} + +#[cfg(feature = "alloc")] +impl Debug for Reference { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Reference") + .field("name", self.name()) + .field("type", &core::any::type_name::()) + .finish() + } +} + /// Search using `Reference ` #[cfg(feature = "alloc")] pub trait MatchNameRef { @@ -587,24 +570,23 @@ pub trait MatchNameRef { } #[cfg(feature = "alloc")] +#[allow(deprecated)] impl MatchNameRef for M where M: MatchName, { fn get(&self, rf: &Reference) -> Option<&T> { - #[allow(deprecated)] self.match_name::(&rf.name) } fn get_mut(&mut self, rf: &Reference) -> Option<&mut T> { - #[allow(deprecated)] self.match_name_mut::(&rf.name) } } /// A wrapper type to enable the indexing of [`MatchName`] implementors with `[]`. #[cfg(feature = "alloc")] -#[derive(Debug)] +#[derive(Copy, Clone, Debug)] #[repr(transparent)] pub struct RefIndexable<'a, M>(&'a M); @@ -668,7 +650,7 @@ where fn index(&self, index: &Reference) -> &Self::Output { let Some(e) = self.get(index) else { - panic!("{} not found in sequence", index.name) + panic!("Could not find entry matching {:?}", index) }; e } @@ -683,7 +665,7 @@ where fn index(&self, index: &Reference) -> &Self::Output { let Some(e) = self.get(index) else { - panic!("{} not found in sequence", index.name) + panic!("Could not find entry matching {:?}", index) }; e } @@ -696,7 +678,7 @@ where { fn index_mut(&mut self, index: &Reference) -> &mut Self::Output { let Some(e) = self.get_mut(index) else { - panic!("{} not found in sequence", index.name) + panic!("Could not find entry matching {:?}", index) }; e } From 00f76718133d2222d0103d4b6d7a30ccb2a62e6e Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 26 Apr 2024 00:46:14 +0200 Subject: [PATCH 19/31] round one CI fixes --- fuzzers/baby_fuzzer_minimizing/src/main.rs | 2 +- fuzzers/forkserver_libafl_cc/src/main.rs | 2 +- fuzzers/forkserver_simple/src/main.rs | 2 +- fuzzers/frida_executable_libpng/src/fuzzer.rs | 6 +++--- fuzzers/frida_gdiplus/src/fuzzer.rs | 6 +++--- fuzzers/frida_libpng/src/fuzzer.rs | 6 +++--- fuzzers/fuzzbench/src/lib.rs | 2 +- fuzzers/fuzzbench_ctx/src/lib.rs | 2 +- fuzzers/fuzzbench_fork_qemu/src/fuzzer.rs | 2 +- fuzzers/fuzzbench_forkserver/src/main.rs | 2 +- fuzzers/fuzzbench_forkserver_cmplog/src/main.rs | 2 +- fuzzers/fuzzbench_qemu/src/fuzzer.rs | 2 +- fuzzers/fuzzbench_text/src/lib.rs | 4 ++-- fuzzers/libafl_atheris/src/lib.rs | 2 +- fuzzers/libfuzzer_libpng/src/lib.rs | 2 +- fuzzers/libfuzzer_libpng_accounting/src/lib.rs | 2 +- fuzzers/libfuzzer_libpng_aflpp_ui/src/lib.rs | 2 +- fuzzers/libfuzzer_libpng_centralized/src/lib.rs | 2 +- fuzzers/libfuzzer_libpng_cmin/src/lib.rs | 2 +- fuzzers/libfuzzer_libpng_launcher/src/lib.rs | 2 +- fuzzers/libfuzzer_libpng_norestart/src/lib.rs | 2 +- fuzzers/libfuzzer_libpng_tcp_manager/src/lib.rs | 2 +- fuzzers/libfuzzer_stb_image/src/main.rs | 2 +- fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs | 2 +- fuzzers/libfuzzer_windows_asan/src/lib.rs | 2 +- fuzzers/qemu_launcher/src/instance.rs | 2 +- fuzzers/qemu_systemmode/src/fuzzer_breakpoint.rs | 2 +- fuzzers/qemu_systemmode/src/fuzzer_classic.rs | 2 +- fuzzers/qemu_systemmode/src/fuzzer_sync_exit.rs | 2 +- fuzzers/tutorial/src/lib.rs | 2 +- libafl/src/schedulers/weighted.rs | 6 +++++- libafl_bolts/src/tuples.rs | 6 ++---- libafl_libfuzzer/libafl_libfuzzer_runtime/src/lib.rs | 2 +- libafl_sugar/src/forkserver.rs | 2 +- libafl_sugar/src/inmemory.rs | 2 +- libafl_sugar/src/qemu.rs | 2 +- 36 files changed, 48 insertions(+), 46 deletions(-) diff --git a/fuzzers/baby_fuzzer_minimizing/src/main.rs b/fuzzers/baby_fuzzer_minimizing/src/main.rs index cf7baf17e1..8d5a0f8eaf 100644 --- a/fuzzers/baby_fuzzer_minimizing/src/main.rs +++ b/fuzzers/baby_fuzzer_minimizing/src/main.rs @@ -36,7 +36,7 @@ pub fn main() -> Result<(), Error> { // Create an observation channel using the signals map let observer = unsafe { StdMapObserver::from_mut_ptr("signals", SIGNALS_PTR, SIGNALS.len()) }; - let factory = MapEqualityFactory::with_observer(&observer); + let factory = MapEqualityFactory::new(&observer); // Feedback to rate the interestingness of an input let mut feedback = MaxMapFeedback::new(&observer); diff --git a/fuzzers/forkserver_libafl_cc/src/main.rs b/fuzzers/forkserver_libafl_cc/src/main.rs index 9c5c13b4c7..fb59d90cb0 100644 --- a/fuzzers/forkserver_libafl_cc/src/main.rs +++ b/fuzzers/forkserver_libafl_cc/src/main.rs @@ -116,7 +116,7 @@ pub fn main() { // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/forkserver_simple/src/main.rs b/fuzzers/forkserver_simple/src/main.rs index b8af8085b9..b2aec6f635 100644 --- a/fuzzers/forkserver_simple/src/main.rs +++ b/fuzzers/forkserver_simple/src/main.rs @@ -114,7 +114,7 @@ pub fn main() { // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/frida_executable_libpng/src/fuzzer.rs b/fuzzers/frida_executable_libpng/src/fuzzer.rs index 56130cd8df..796f52b408 100644 --- a/fuzzers/frida_executable_libpng/src/fuzzer.rs +++ b/fuzzers/frida_executable_libpng/src/fuzzer.rs @@ -130,7 +130,7 @@ unsafe fn fuzz( // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // Feedbacks to recognize an input as solution @@ -247,7 +247,7 @@ unsafe fn fuzz( // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); #[cfg(unix)] @@ -377,7 +377,7 @@ unsafe fn fuzz( // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); #[cfg(unix)] diff --git a/fuzzers/frida_gdiplus/src/fuzzer.rs b/fuzzers/frida_gdiplus/src/fuzzer.rs index 7bff6cd18e..7c8e6b9d8e 100644 --- a/fuzzers/frida_gdiplus/src/fuzzer.rs +++ b/fuzzers/frida_gdiplus/src/fuzzer.rs @@ -125,7 +125,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // Feedbacks to recognize an input as solution @@ -241,7 +241,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); #[cfg(unix)] @@ -372,7 +372,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); #[cfg(unix)] diff --git a/fuzzers/frida_libpng/src/fuzzer.rs b/fuzzers/frida_libpng/src/fuzzer.rs index 83687093d3..4886087170 100644 --- a/fuzzers/frida_libpng/src/fuzzer.rs +++ b/fuzzers/frida_libpng/src/fuzzer.rs @@ -120,7 +120,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // Feedbacks to recognize an input as solution @@ -238,7 +238,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); #[cfg(unix)] @@ -368,7 +368,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); #[cfg(unix)] diff --git a/fuzzers/fuzzbench/src/lib.rs b/fuzzers/fuzzbench/src/lib.rs index 0946984bbe..4c989e0f5f 100644 --- a/fuzzers/fuzzbench/src/lib.rs +++ b/fuzzers/fuzzbench/src/lib.rs @@ -260,7 +260,7 @@ fn fuzz( // New maximization map feedback linked to the edges observer and the feedback state map_feedback, // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/fuzzbench_ctx/src/lib.rs b/fuzzers/fuzzbench_ctx/src/lib.rs index 553a0478ce..c17b242a43 100644 --- a/fuzzers/fuzzbench_ctx/src/lib.rs +++ b/fuzzers/fuzzbench_ctx/src/lib.rs @@ -270,7 +270,7 @@ fn fuzz( // New maximization map feedback linked to the edges observer and the feedback state map_feedback, // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/fuzzbench_fork_qemu/src/fuzzer.rs b/fuzzers/fuzzbench_fork_qemu/src/fuzzer.rs index 4ffd6be305..182d68085f 100644 --- a/fuzzers/fuzzbench_fork_qemu/src/fuzzer.rs +++ b/fuzzers/fuzzbench_fork_qemu/src/fuzzer.rs @@ -258,7 +258,7 @@ fn fuzz( // New maximization map feedback linked to the edges observer and the feedback state map_feedback, // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/fuzzbench_forkserver/src/main.rs b/fuzzers/fuzzbench_forkserver/src/main.rs index 9b74e1947b..9869976742 100644 --- a/fuzzers/fuzzbench_forkserver/src/main.rs +++ b/fuzzers/fuzzbench_forkserver/src/main.rs @@ -267,7 +267,7 @@ fn fuzz( // New maximization map feedback linked to the edges observer and the feedback state map_feedback, // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs b/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs index ad882e5b67..b3f5ed6205 100644 --- a/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs +++ b/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs @@ -268,7 +268,7 @@ fn fuzz( // New maximization map feedback linked to the edges observer and the feedback state map_feedback, // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/fuzzbench_qemu/src/fuzzer.rs b/fuzzers/fuzzbench_qemu/src/fuzzer.rs index bbc4cd16a0..9df115ba08 100644 --- a/fuzzers/fuzzbench_qemu/src/fuzzer.rs +++ b/fuzzers/fuzzbench_qemu/src/fuzzer.rs @@ -279,7 +279,7 @@ fn fuzz( // New maximization map feedback linked to the edges observer and the feedback state map_feedback, // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/fuzzbench_text/src/lib.rs b/fuzzers/fuzzbench_text/src/lib.rs index ead2906460..4469e3a796 100644 --- a/fuzzers/fuzzbench_text/src/lib.rs +++ b/fuzzers/fuzzbench_text/src/lib.rs @@ -328,7 +328,7 @@ fn fuzz_binary( // New maximization map feedback linked to the edges observer and the feedback state map_feedback, // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not let mut objective = CrashFeedback::new(); @@ -539,7 +539,7 @@ fn fuzz_text( let mut feedback = feedback_or!( map_feedback, // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/libafl_atheris/src/lib.rs b/fuzzers/libafl_atheris/src/lib.rs index 95f2e92694..925fb32b18 100644 --- a/fuzzers/libafl_atheris/src/lib.rs +++ b/fuzzers/libafl_atheris/src/lib.rs @@ -151,7 +151,7 @@ pub extern "C" fn LLVMFuzzerRunDriver( // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/libfuzzer_libpng/src/lib.rs b/fuzzers/libfuzzer_libpng/src/lib.rs index 5fe52363d4..977fdc8daf 100644 --- a/fuzzers/libfuzzer_libpng/src/lib.rs +++ b/fuzzers/libfuzzer_libpng/src/lib.rs @@ -101,7 +101,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re // New maximization map feedback linked to the edges observer and the feedback state map_feedback, // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/libfuzzer_libpng_accounting/src/lib.rs b/fuzzers/libfuzzer_libpng_accounting/src/lib.rs index 750dd7b2de..2a7bd4f950 100644 --- a/fuzzers/libfuzzer_libpng_accounting/src/lib.rs +++ b/fuzzers/libfuzzer_libpng_accounting/src/lib.rs @@ -152,7 +152,7 @@ pub extern "C" fn libafl_main() { // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/libfuzzer_libpng_aflpp_ui/src/lib.rs b/fuzzers/libfuzzer_libpng_aflpp_ui/src/lib.rs index 4a8867f841..4241cb3ed7 100644 --- a/fuzzers/libfuzzer_libpng_aflpp_ui/src/lib.rs +++ b/fuzzers/libfuzzer_libpng_aflpp_ui/src/lib.rs @@ -115,7 +115,7 @@ fn fuzz( // New maximization map feedback linked to the edges observer and the feedback state map_feedback, // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/libfuzzer_libpng_centralized/src/lib.rs b/fuzzers/libfuzzer_libpng_centralized/src/lib.rs index ee3bafcff2..560d3c0cf9 100644 --- a/fuzzers/libfuzzer_libpng_centralized/src/lib.rs +++ b/fuzzers/libfuzzer_libpng_centralized/src/lib.rs @@ -150,7 +150,7 @@ pub extern "C" fn libafl_main() { // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/libfuzzer_libpng_cmin/src/lib.rs b/fuzzers/libfuzzer_libpng_cmin/src/lib.rs index 44b3356835..cc9e281360 100644 --- a/fuzzers/libfuzzer_libpng_cmin/src/lib.rs +++ b/fuzzers/libfuzzer_libpng_cmin/src/lib.rs @@ -100,7 +100,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re // New maximization map feedback linked to the edges observer and the feedback state map_feedback, // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/libfuzzer_libpng_launcher/src/lib.rs b/fuzzers/libfuzzer_libpng_launcher/src/lib.rs index d8d5009151..cc3abf7a9f 100644 --- a/fuzzers/libfuzzer_libpng_launcher/src/lib.rs +++ b/fuzzers/libfuzzer_libpng_launcher/src/lib.rs @@ -151,7 +151,7 @@ pub extern "C" fn libafl_main() { // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/libfuzzer_libpng_norestart/src/lib.rs b/fuzzers/libfuzzer_libpng_norestart/src/lib.rs index 2b041f514b..8de1e78c7e 100644 --- a/fuzzers/libfuzzer_libpng_norestart/src/lib.rs +++ b/fuzzers/libfuzzer_libpng_norestart/src/lib.rs @@ -176,7 +176,7 @@ pub extern "C" fn libafl_main() { // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/libfuzzer_libpng_tcp_manager/src/lib.rs b/fuzzers/libfuzzer_libpng_tcp_manager/src/lib.rs index e1a49198be..17a47cffed 100644 --- a/fuzzers/libfuzzer_libpng_tcp_manager/src/lib.rs +++ b/fuzzers/libfuzzer_libpng_tcp_manager/src/lib.rs @@ -99,7 +99,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re // New maximization map feedback linked to the edges observer and the feedback state map_feedback, // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/libfuzzer_stb_image/src/main.rs b/fuzzers/libfuzzer_stb_image/src/main.rs index 12866edb9e..1f316066d0 100644 --- a/fuzzers/libfuzzer_stb_image/src/main.rs +++ b/fuzzers/libfuzzer_stb_image/src/main.rs @@ -81,7 +81,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs b/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs index 8087ab81b4..9b795db1c8 100644 --- a/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs +++ b/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs @@ -119,7 +119,7 @@ fn fuzz( // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/libfuzzer_windows_asan/src/lib.rs b/fuzzers/libfuzzer_windows_asan/src/lib.rs index 9e84f19971..2307ac255e 100644 --- a/fuzzers/libfuzzer_windows_asan/src/lib.rs +++ b/fuzzers/libfuzzer_windows_asan/src/lib.rs @@ -77,7 +77,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re // New maximization map feedback linked to the edges observer and the feedback state map_feedback, // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/qemu_launcher/src/instance.rs b/fuzzers/qemu_launcher/src/instance.rs index 0ffbb16a03..379da0c9cd 100644 --- a/fuzzers/qemu_launcher/src/instance.rs +++ b/fuzzers/qemu_launcher/src/instance.rs @@ -97,7 +97,7 @@ impl<'a, M: Monitor> Instance<'a, M> { // New maximization map feedback linked to the edges observer and the feedback state map_feedback, // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/qemu_systemmode/src/fuzzer_breakpoint.rs b/fuzzers/qemu_systemmode/src/fuzzer_breakpoint.rs index b74c33387f..03143fd91f 100644 --- a/fuzzers/qemu_systemmode/src/fuzzer_breakpoint.rs +++ b/fuzzers/qemu_systemmode/src/fuzzer_breakpoint.rs @@ -169,7 +169,7 @@ pub fn fuzz() { // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/qemu_systemmode/src/fuzzer_classic.rs b/fuzzers/qemu_systemmode/src/fuzzer_classic.rs index 5ec687fc03..7276b9a606 100644 --- a/fuzzers/qemu_systemmode/src/fuzzer_classic.rs +++ b/fuzzers/qemu_systemmode/src/fuzzer_classic.rs @@ -176,7 +176,7 @@ pub fn fuzz() { // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/qemu_systemmode/src/fuzzer_sync_exit.rs b/fuzzers/qemu_systemmode/src/fuzzer_sync_exit.rs index 88ee2355e7..c792e8e29d 100644 --- a/fuzzers/qemu_systemmode/src/fuzzer_sync_exit.rs +++ b/fuzzers/qemu_systemmode/src/fuzzer_sync_exit.rs @@ -110,7 +110,7 @@ pub fn fuzz() { // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/fuzzers/tutorial/src/lib.rs b/fuzzers/tutorial/src/lib.rs index 1333bb9159..edc9d814e4 100644 --- a/fuzzers/tutorial/src/lib.rs +++ b/fuzzers/tutorial/src/lib.rs @@ -97,7 +97,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re // New maximization map feedback linked to the edges observer and the feedback state map_feedback, // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer), + TimeFeedback::new(&time_observer), PacketLenFeedback::new() ); diff --git a/libafl/src/schedulers/weighted.rs b/libafl/src/schedulers/weighted.rs index 78a7aa8999..96ed11c0f8 100644 --- a/libafl/src/schedulers/weighted.rs +++ b/libafl/src/schedulers/weighted.rs @@ -4,7 +4,11 @@ use core::marker::PhantomData; use hashbrown::HashMap; -use libafl_bolts::{bolts_prelude::Reference, rands::Rand, tuples::Referenceable, Named}; +use libafl_bolts::{ + rands::Rand, + tuples::{Reference, Referenceable}, + Named, +}; use serde::{Deserialize, Serialize}; use crate::{ diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index 1eb97b949e..ed676afa95 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -2,12 +2,10 @@ #[cfg(feature = "alloc")] use alloc::{borrow::Cow, vec::Vec}; -#[rustversion::not(nightly)] -use core::any::type_name; #[cfg(feature = "alloc")] use core::ops::{Deref, DerefMut}; use core::{ - any::TypeId, + any::{type_name, TypeId}, fmt::{Debug, Formatter}, marker::PhantomData, mem::transmute, @@ -554,7 +552,7 @@ impl Debug for Reference { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { f.debug_struct("Reference") .field("name", self.name()) - .field("type", &core::any::type_name::()) + .field("type", &type_name::()) .finish() } } diff --git a/libafl_libfuzzer/libafl_libfuzzer_runtime/src/lib.rs b/libafl_libfuzzer/libafl_libfuzzer_runtime/src/lib.rs index 294be68f67..2f282e794d 100644 --- a/libafl_libfuzzer/libafl_libfuzzer_runtime/src/lib.rs +++ b/libafl_libfuzzer/libafl_libfuzzer_runtime/src/lib.rs @@ -244,7 +244,7 @@ macro_rules! fuzz_with { map_feedback, feedback_and_fast!(ConstFeedback::new($options.shrink()), shrinking_map_feedback), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ) ); diff --git a/libafl_sugar/src/forkserver.rs b/libafl_sugar/src/forkserver.rs index cb3d04fcd6..8b7179d759 100644 --- a/libafl_sugar/src/forkserver.rs +++ b/libafl_sugar/src/forkserver.rs @@ -140,7 +140,7 @@ impl<'a> ForkserverBytesCoverageSugar<'a> { // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/libafl_sugar/src/inmemory.rs b/libafl_sugar/src/inmemory.rs index f0cdb43270..90ce2f0256 100644 --- a/libafl_sugar/src/inmemory.rs +++ b/libafl_sugar/src/inmemory.rs @@ -157,7 +157,7 @@ where // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not diff --git a/libafl_sugar/src/qemu.rs b/libafl_sugar/src/qemu.rs index 0e144549e9..0b1b5fbad2 100644 --- a/libafl_sugar/src/qemu.rs +++ b/libafl_sugar/src/qemu.rs @@ -171,7 +171,7 @@ where // New maximization map feedback linked to the edges observer and the feedback state MaxMapFeedback::new(&edges_observer), // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) ); // A feedback to choose if an input is a solution or not From 279e57c5aa268d1f9276867fefe9171a389359ac Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 26 Apr 2024 00:53:17 +0200 Subject: [PATCH 20/31] clippy appeasement --- libafl_bolts/src/cpu.rs | 1 + libafl_bolts/src/tuples.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/libafl_bolts/src/cpu.rs b/libafl_bolts/src/cpu.rs index d885d84ceb..318011c549 100644 --- a/libafl_bolts/src/cpu.rs +++ b/libafl_bolts/src/cpu.rs @@ -51,6 +51,7 @@ pub fn read_time_counter() -> u64 { v } +/// Read a timestamp for measurements #[cfg(target_arch = "arm")] #[must_use] pub fn read_time_counter() -> u64 { diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index ed676afa95..213d566952 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -532,6 +532,7 @@ impl Reference { /// /// We explicitly do *not* implement [`Named`], as this could potentially lead to confusion /// where we make a [`Reference`] of a [`Reference`] as [`Named`] is blanket implemented. + #[must_use] pub fn name(&self) -> &Cow<'static, str> { &self.name } From 883de68983aa419d15a755d87cf7732db3cd8b35 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 26 Apr 2024 01:13:59 +0200 Subject: [PATCH 21/31] deref generic impl to simplify usage --- libafl/src/executors/combined.rs | 6 +- libafl/src/executors/command.rs | 8 +-- libafl/src/executors/differential.rs | 8 +-- libafl/src/executors/forkserver.rs | 8 +-- libafl/src/executors/inprocess/inner.rs | 8 +-- libafl/src/executors/inprocess/mod.rs | 6 +- libafl/src/executors/inprocess/stateful.rs | 6 +- libafl/src/executors/inprocess_fork/inner.rs | 8 +-- libafl/src/executors/inprocess_fork/mod.rs | 6 +- .../src/executors/inprocess_fork/stateful.rs | 6 +- libafl/src/executors/mod.rs | 6 +- libafl/src/executors/shadow.rs | 6 +- libafl/src/executors/with_observers.rs | 8 +-- libafl_bolts/src/tuples.rs | 65 +++++-------------- libafl_frida/src/executor.rs | 6 +- libafl_nyx/src/executor.rs | 11 ++-- libafl_qemu/src/executor/mod.rs | 10 +-- libafl_qemu/src/executor/stateful.rs | 6 +- libafl_tinyinst/src/executor.rs | 8 +-- 19 files changed, 81 insertions(+), 115 deletions(-) diff --git a/libafl/src/executors/combined.rs b/libafl/src/executors/combined.rs index 244f8937eb..e48df9ec5c 100644 --- a/libafl/src/executors/combined.rs +++ b/libafl/src/executors/combined.rs @@ -3,7 +3,7 @@ use core::fmt::Debug; -use libafl_bolts::tuples::{RefIndexable, RefIndexableMut}; +use libafl_bolts::tuples::RefIndexable; use crate::{ executors::{Executor, ExitKind, HasObservers}, @@ -82,12 +82,12 @@ where A: HasObservers, { #[inline] - fn observers(&self) -> RefIndexable { + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { self.primary.observers() } #[inline] - fn observers_mut(&mut self) -> RefIndexableMut { + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> { self.primary.observers_mut() } } diff --git a/libafl/src/executors/command.rs b/libafl/src/executors/command.rs index 779a2ea480..18bd0cb259 100644 --- a/libafl/src/executors/command.rs +++ b/libafl/src/executors/command.rs @@ -18,7 +18,7 @@ use std::{ use libafl_bolts::{ fs::{get_unique_std_input_file, InputFile}, - tuples::{MatchName, RefIndexable, RefIndexableMut}, + tuples::{MatchName, RefIndexable}, AsSlice, }; @@ -397,12 +397,12 @@ where T: Debug, OT: ObserversTuple, { - fn observers(&self) -> RefIndexable { + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { RefIndexable::from(&self.observers) } - fn observers_mut(&mut self) -> RefIndexableMut { - RefIndexableMut::from(&mut self.observers) + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> { + RefIndexable::from(&mut self.observers) } } diff --git a/libafl/src/executors/differential.rs b/libafl/src/executors/differential.rs index 93e6614a97..c4e2620e97 100644 --- a/libafl/src/executors/differential.rs +++ b/libafl/src/executors/differential.rs @@ -6,7 +6,7 @@ use core::{cell::UnsafeCell, fmt::Debug, ptr}; use libafl_bolts::{ ownedref::OwnedMutPtr, - tuples::{MatchName, RefIndexable, RefIndexableMut}, + tuples::{MatchName, RefIndexable}, }; use serde::{Deserialize, Serialize}; @@ -244,7 +244,7 @@ where DOT: DifferentialObserversTuple, { #[inline] - fn observers(&self) -> RefIndexable> { + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { unsafe { self.observers .get() @@ -256,13 +256,13 @@ where } #[inline] - fn observers_mut(&mut self) -> RefIndexableMut> { + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> { unsafe { self.observers.get().as_mut().unwrap().set( &*self.primary.observers_mut(), &*self.secondary.observers_mut(), ); - RefIndexableMut::from(self.observers.get().as_mut().unwrap()) + RefIndexable::from(self.observers.get().as_mut().unwrap()) } } } diff --git a/libafl/src/executors/forkserver.rs b/libafl/src/executors/forkserver.rs index cd79f8ae91..1d20014f8a 100644 --- a/libafl/src/executors/forkserver.rs +++ b/libafl/src/executors/forkserver.rs @@ -22,7 +22,7 @@ use libafl_bolts::{ fs::{get_unique_std_input_file, InputFile}, os::{dup2, pipes::Pipe}, shmem::{ShMem, ShMemProvider, UnixShMemProvider}, - tuples::{MatchNameRef, Prepend, RefIndexable, RefIndexableMut, Reference, Referenceable}, + tuples::{MatchNameRef, Prepend, RefIndexable, Reference, Referenceable}, AsSlice, AsSliceMut, Truncate, }; use nix::{ @@ -1222,13 +1222,13 @@ where SP: ShMemProvider, { #[inline] - fn observers(&self) -> RefIndexable { + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { RefIndexable::from(&self.observers) } #[inline] - fn observers_mut(&mut self) -> RefIndexableMut { - RefIndexableMut::from(&mut self.observers) + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> { + RefIndexable::from(&mut self.observers) } } diff --git a/libafl/src/executors/inprocess/inner.rs b/libafl/src/executors/inprocess/inner.rs index 23648874e7..492e474dae 100644 --- a/libafl/src/executors/inprocess/inner.rs +++ b/libafl/src/executors/inprocess/inner.rs @@ -7,7 +7,7 @@ use core::{ time::Duration, }; -use libafl_bolts::tuples::{tuple_list, Merge, RefIndexable, RefIndexableMut}; +use libafl_bolts::tuples::{tuple_list, Merge, RefIndexable}; #[cfg(windows)] use windows::Win32::System::Threading::SetThreadStackGuarantee; @@ -85,13 +85,13 @@ where S: State, { #[inline] - fn observers(&self) -> RefIndexable { + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { RefIndexable::from(&self.observers) } #[inline] - fn observers_mut(&mut self) -> RefIndexableMut { - RefIndexableMut::from(&mut self.observers) + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> { + RefIndexable::from(&mut self.observers) } } diff --git a/libafl/src/executors/inprocess/mod.rs b/libafl/src/executors/inprocess/mod.rs index 42263ec681..bd8edb51fe 100644 --- a/libafl/src/executors/inprocess/mod.rs +++ b/libafl/src/executors/inprocess/mod.rs @@ -16,7 +16,7 @@ use core::{ time::Duration, }; -use libafl_bolts::tuples::{tuple_list, RefIndexable, RefIndexableMut}; +use libafl_bolts::tuples::{tuple_list, RefIndexable}; #[cfg(any(unix, feature = "std"))] use crate::executors::hooks::inprocess::GLOBAL_STATE; @@ -151,12 +151,12 @@ where S: State, { #[inline] - fn observers(&self) -> RefIndexable { + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { self.inner.observers() } #[inline] - fn observers_mut(&mut self) -> RefIndexableMut { + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> { self.inner.observers_mut() } } diff --git a/libafl/src/executors/inprocess/stateful.rs b/libafl/src/executors/inprocess/stateful.rs index 9ccc2b2c6b..b84a7e0793 100644 --- a/libafl/src/executors/inprocess/stateful.rs +++ b/libafl/src/executors/inprocess/stateful.rs @@ -8,7 +8,7 @@ use core::{ time::Duration, }; -use libafl_bolts::tuples::{tuple_list, RefIndexable, RefIndexableMut}; +use libafl_bolts::tuples::{tuple_list, RefIndexable}; use crate::{ events::{EventFirer, EventRestarter}, @@ -142,12 +142,12 @@ where S: State, { #[inline] - fn observers(&self) -> RefIndexable { + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { self.inner.observers() } #[inline] - fn observers_mut(&mut self) -> RefIndexableMut { + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> { self.inner.observers_mut() } } diff --git a/libafl/src/executors/inprocess_fork/inner.rs b/libafl/src/executors/inprocess_fork/inner.rs index 0217d337cf..103bba4401 100644 --- a/libafl/src/executors/inprocess_fork/inner.rs +++ b/libafl/src/executors/inprocess_fork/inner.rs @@ -10,7 +10,7 @@ use core::{ use libafl_bolts::{ os::unix_signals::Signal, shmem::ShMemProvider, - tuples::{tuple_list, Merge, RefIndexable, RefIndexableMut}, + tuples::{tuple_list, Merge, RefIndexable}, }; use nix::{ sys::wait::{waitpid, WaitStatus}, @@ -339,12 +339,12 @@ where Z: UsesState, { #[inline] - fn observers(&self) -> RefIndexable { + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { RefIndexable::from(&self.observers) } #[inline] - fn observers_mut(&mut self) -> RefIndexableMut { - RefIndexableMut::from(&mut self.observers) + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> { + RefIndexable::from(&mut self.observers) } } diff --git a/libafl/src/executors/inprocess_fork/mod.rs b/libafl/src/executors/inprocess_fork/mod.rs index d14697e29c..29959a4b48 100644 --- a/libafl/src/executors/inprocess_fork/mod.rs +++ b/libafl/src/executors/inprocess_fork/mod.rs @@ -7,7 +7,7 @@ use core::{ use libafl_bolts::{ os::unix_signals::{ucontext_t, Signal}, shmem::ShMemProvider, - tuples::{tuple_list, RefIndexable, RefIndexableMut}, + tuples::{tuple_list, RefIndexable}, }; use libc::siginfo_t; use nix::unistd::{fork, ForkResult}; @@ -255,12 +255,12 @@ where Z: UsesState, { #[inline] - fn observers(&self) -> RefIndexable { + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { self.inner.observers() } #[inline] - fn observers_mut(&mut self) -> RefIndexableMut { + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> { self.inner.observers_mut() } } diff --git a/libafl/src/executors/inprocess_fork/stateful.rs b/libafl/src/executors/inprocess_fork/stateful.rs index 49cadf6fe2..d2ae815f99 100644 --- a/libafl/src/executors/inprocess_fork/stateful.rs +++ b/libafl/src/executors/inprocess_fork/stateful.rs @@ -7,7 +7,7 @@ use core::{ use libafl_bolts::{ shmem::ShMemProvider, - tuples::{tuple_list, RefIndexable, RefIndexableMut}, + tuples::{tuple_list, RefIndexable}, }; use nix::unistd::{fork, ForkResult}; @@ -248,12 +248,12 @@ where Z: UsesState, { #[inline] - fn observers(&self) -> RefIndexable { + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { self.inner.observers() } #[inline] - fn observers_mut(&mut self) -> RefIndexableMut { + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> { self.inner.observers_mut() } } diff --git a/libafl/src/executors/mod.rs b/libafl/src/executors/mod.rs index fdc38ea3ae..5e9d462b36 100644 --- a/libafl/src/executors/mod.rs +++ b/libafl/src/executors/mod.rs @@ -15,7 +15,7 @@ pub use inprocess::InProcessExecutor; pub use inprocess_fork::InProcessForkExecutor; #[cfg(unix)] use libafl_bolts::os::unix_signals::Signal; -use libafl_bolts::tuples::{RefIndexable, RefIndexableMut}; +use libafl_bolts::tuples::RefIndexable; use serde::{Deserialize, Serialize}; pub use shadow::ShadowExecutor; pub use with_observers::WithObservers; @@ -111,10 +111,10 @@ libafl_bolts::impl_serdeany!(DiffExitKind); /// Holds a tuple of Observers pub trait HasObservers: UsesObservers { /// Get the linked observers - fn observers(&self) -> RefIndexable; + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers>; /// Get the linked observers (mutable) - fn observers_mut(&mut self) -> RefIndexableMut; + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers>; } /// An executor takes the given inputs, and runs the harness/target. diff --git a/libafl/src/executors/shadow.rs b/libafl/src/executors/shadow.rs index c2116b99f9..86ce75c994 100644 --- a/libafl/src/executors/shadow.rs +++ b/libafl/src/executors/shadow.rs @@ -2,7 +2,7 @@ use core::fmt::{self, Debug, Formatter}; -use libafl_bolts::tuples::{RefIndexable, RefIndexableMut}; +use libafl_bolts::tuples::RefIndexable; use crate::{ executors::{Executor, ExitKind, HasObservers}, @@ -96,12 +96,12 @@ where SOT: ObserversTuple, { #[inline] - fn observers(&self) -> RefIndexable { + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { self.executor.observers() } #[inline] - fn observers_mut(&mut self) -> RefIndexableMut { + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> { self.executor.observers_mut() } } diff --git a/libafl/src/executors/with_observers.rs b/libafl/src/executors/with_observers.rs index 5c962a3239..6924b9e401 100644 --- a/libafl/src/executors/with_observers.rs +++ b/libafl/src/executors/with_observers.rs @@ -2,7 +2,7 @@ use core::fmt::Debug; -use libafl_bolts::tuples::{RefIndexable, RefIndexableMut}; +use libafl_bolts::tuples::RefIndexable; use crate::{ executors::{Executor, ExitKind, HasObservers}, @@ -55,12 +55,12 @@ where E: UsesState, OT: ObserversTuple, { - fn observers(&self) -> RefIndexable { + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { RefIndexable::from(&self.observers) } - fn observers_mut(&mut self) -> RefIndexableMut { - RefIndexableMut::from(&mut self.observers) + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> { + RefIndexable::from(&mut self.observers) } } diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index 213d566952..a12c28d9c1 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -587,77 +587,45 @@ where #[cfg(feature = "alloc")] #[derive(Copy, Clone, Debug)] #[repr(transparent)] -pub struct RefIndexable<'a, M>(&'a M); +pub struct RefIndexable(RM, PhantomData); #[cfg(feature = "alloc")] -impl<'a, M> From<&'a M> for RefIndexable<'a, M> +impl From for RefIndexable where + RM: Deref, M: MatchName, { - fn from(value: &'a M) -> Self { - RefIndexable(value) + fn from(value: RM) -> Self { + RefIndexable(value, PhantomData) } } -/// A wrapper type to enable the mutable indexing of [`MatchName`] implementors with `[]`. #[cfg(feature = "alloc")] -#[derive(Debug)] -#[repr(transparent)] -pub struct RefIndexableMut<'a, M>(&'a mut M); - -#[cfg(feature = "alloc")] -impl<'a, M> From<&'a mut M> for RefIndexableMut<'a, M> +impl Deref for RefIndexable where - M: MatchName, + RM: Deref, { - fn from(value: &'a mut M) -> Self { - RefIndexableMut(value) - } -} - -#[cfg(feature = "alloc")] -impl<'a, M> Deref for RefIndexable<'a, M> { - type Target = M; - - fn deref(&self) -> &Self::Target { - self.0 - } -} - -#[cfg(feature = "alloc")] -impl<'a, M> Deref for RefIndexableMut<'a, M> { - type Target = M; + type Target = RM::Target; fn deref(&self) -> &Self::Target { - self.0 + self.0.deref() } } #[cfg(feature = "alloc")] -impl<'a, M> DerefMut for RefIndexableMut<'a, M> { - fn deref_mut(&mut self) -> &mut Self::Target { - self.0 - } -} - -#[cfg(feature = "alloc")] -impl<'a, T, M> Index<&Reference> for RefIndexable<'a, M> +impl DerefMut for RefIndexable where - M: MatchName, + RM: DerefMut, { - type Output = T; - - fn index(&self, index: &Reference) -> &Self::Output { - let Some(e) = self.get(index) else { - panic!("Could not find entry matching {:?}", index) - }; - e + fn deref_mut(&mut self) -> &mut Self::Target { + self.0.deref_mut() } } #[cfg(feature = "alloc")] -impl<'a, T, M> Index<&Reference> for RefIndexableMut<'a, M> +impl Index<&Reference> for RefIndexable where + RM: Deref, M: MatchName, { type Output = T; @@ -671,8 +639,9 @@ where } #[cfg(feature = "alloc")] -impl<'a, T, M> IndexMut<&Reference> for RefIndexableMut<'a, M> +impl IndexMut<&Reference> for RefIndexable where + RM: DerefMut, M: MatchName, { fn index_mut(&mut self, index: &Reference) -> &mut Self::Output { diff --git a/libafl_frida/src/executor.rs b/libafl_frida/src/executor.rs index 2492401ac1..7ede0b357a 100644 --- a/libafl_frida/src/executor.rs +++ b/libafl_frida/src/executor.rs @@ -19,7 +19,7 @@ use libafl::{ state::{HasExecutions, State, UsesState}, Error, }; -use libafl_bolts::tuples::{RefIndexable, RefIndexableMut}; +use libafl_bolts::tuples::RefIndexable; #[cfg(all(unix, not(test)))] use crate::asan::errors::AsanErrors; @@ -146,12 +146,12 @@ where OT: ObserversTuple, { #[inline] - fn observers(&self) -> RefIndexable { + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { self.base.observers() } #[inline] - fn observers_mut(&mut self) -> RefIndexableMut { + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> { self.base.observers_mut() } } diff --git a/libafl_nyx/src/executor.rs b/libafl_nyx/src/executor.rs index 6527096837..334082d131 100644 --- a/libafl_nyx/src/executor.rs +++ b/libafl_nyx/src/executor.rs @@ -11,10 +11,7 @@ use libafl::{ state::{HasExecutions, State, UsesState}, Error, }; -use libafl_bolts::{ - tuples::{RefIndexable, RefIndexableMut}, - AsSlice, -}; +use libafl_bolts::{tuples::RefIndexable, AsSlice}; use libnyx::NyxReturnValue; use crate::helper::NyxHelper; @@ -149,11 +146,11 @@ where S: State, OT: ObserversTuple, { - fn observers(&self) -> RefIndexable { + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { RefIndexable::from(&self.observers) } - fn observers_mut(&mut self) -> RefIndexableMut { - RefIndexableMut::from(&mut self.observers) + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> { + RefIndexable::from(&mut self.observers) } } diff --git a/libafl_qemu/src/executor/mod.rs b/libafl_qemu/src/executor/mod.rs index 9c52457731..d6cd36f76e 100644 --- a/libafl_qemu/src/executor/mod.rs +++ b/libafl_qemu/src/executor/mod.rs @@ -26,7 +26,7 @@ use libafl::{ use libafl_bolts::shmem::ShMemProvider; use libafl_bolts::{ os::unix_signals::{siginfo_t, ucontext_t, Signal}, - tuples::{RefIndexable, RefIndexableMut}, + tuples::RefIndexable, }; use crate::{helpers::QemuHelperTuple, hooks::QemuHooks, Qemu}; @@ -346,12 +346,12 @@ where QT: QemuHelperTuple, { #[inline] - fn observers(&self) -> RefIndexable { + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { self.inner.observers() } #[inline] - fn observers_mut(&mut self) -> RefIndexableMut { + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> { self.inner.observers_mut() } } @@ -530,12 +530,12 @@ where Z: UsesState, { #[inline] - fn observers(&self) -> RefIndexable { + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { self.inner.observers() } #[inline] - fn observers_mut(&mut self) -> RefIndexableMut { + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> { self.inner.observers_mut() } } diff --git a/libafl_qemu/src/executor/stateful.rs b/libafl_qemu/src/executor/stateful.rs index aaff62538c..145bb38576 100644 --- a/libafl_qemu/src/executor/stateful.rs +++ b/libafl_qemu/src/executor/stateful.rs @@ -17,7 +17,7 @@ use libafl::{ state::{HasCorpus, HasExecutions, HasSolutions, State, UsesState}, Error, }; -use libafl_bolts::tuples::{RefIndexable, RefIndexableMut}; +use libafl_bolts::tuples::RefIndexable; #[cfg(emulation_mode = "usermode")] use crate::executor::inproc_qemu_crash_handler; @@ -200,12 +200,12 @@ where QT: QemuHelperTuple, { #[inline] - fn observers(&self) -> RefIndexable { + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { self.inner.observers() } #[inline] - fn observers_mut(&mut self) -> RefIndexableMut { + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> { self.inner.observers_mut() } } diff --git a/libafl_tinyinst/src/executor.rs b/libafl_tinyinst/src/executor.rs index 0e6e7e4b26..d2a63c3715 100644 --- a/libafl_tinyinst/src/executor.rs +++ b/libafl_tinyinst/src/executor.rs @@ -11,7 +11,7 @@ use libafl::{ use libafl_bolts::{ fs::{InputFile, INPUTFILE_STD}, shmem::{ShMem, ShMemProvider, StdShMemProvider}, - tuples::{RefIndexable, RefIndexableMut}, + tuples::RefIndexable, AsSlice, AsSliceMut, }; use tinyinst::tinyinst::{litecov::RunResult, TinyInst}; @@ -301,12 +301,12 @@ where SP: ShMemProvider, OT: ObserversTuple, { - fn observers(&self) -> RefIndexable { + fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { RefIndexable::from(&self.observers) } - fn observers_mut(&mut self) -> RefIndexableMut { - RefIndexableMut::from(&mut self.observers) + fn observers_mut(&mut self) -> RefIndexable<&mut Self::Observers, Self::Observers> { + RefIndexable::from(&mut self.observers) } } impl<'a, S, SP, OT> UsesState for TinyInstExecutor<'a, S, SP, OT> From 7a8a2a3a6e384bf242ab6a3d0f32c778aebec98a Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 26 Apr 2024 02:27:54 +0200 Subject: [PATCH 22/31] adaptive serialization (ouch) --- libafl/src/corpus/minimizer.rs | 23 +- libafl/src/events/centralized.rs | 104 ++++++++- libafl/src/events/launcher.rs | 58 +++-- libafl/src/events/llmp.rs | 374 ++++++++++++++++++++++++------- libafl/src/events/mod.rs | 17 +- libafl/src/executors/shadow.rs | 8 +- libafl_bolts/src/tuples.rs | 8 +- 7 files changed, 469 insertions(+), 123 deletions(-) diff --git a/libafl/src/corpus/minimizer.rs b/libafl/src/corpus/minimizer.rs index a038f93cdb..ed8970c0b0 100644 --- a/libafl/src/corpus/minimizer.rs +++ b/libafl/src/corpus/minimizer.rs @@ -1,15 +1,15 @@ //! Whole corpus minimizers, for reducing the number of samples/the total size/the average runtime //! of your corpus. -use alloc::{ - borrow::Cow, - string::{String, ToString}, - vec::Vec, -}; +use alloc::{borrow::Cow, string::ToString, vec::Vec}; use core::{hash::Hash, marker::PhantomData}; use hashbrown::{HashMap, HashSet}; -use libafl_bolts::{current_time, tuples::MatchName, AsIter, Named}; +use libafl_bolts::{ + current_time, + tuples::{Reference, Referenceable}, + AsIter, Named, +}; use num_traits::ToPrimitive; use z3::{ast::Bool, Config, Context, Optimize}; @@ -51,8 +51,8 @@ where /// Algorithm based on WMOPT: #[derive(Debug)] pub struct MapCorpusMinimizer { - obs_name: String, - phantom: PhantomData<(C, E, O, T, TS)>, + obs_ref: Reference, + phantom: PhantomData<(E, O, T, TS)>, } /// Standard corpus minimizer, which weights inputs by length and time. @@ -70,7 +70,7 @@ where /// in the future to get observed maps from an executed input. pub fn new(obs: &C) -> Self { Self { - obs_name: obs.name().to_string(), + obs_ref: obs.type_ref(), phantom: PhantomData, } } @@ -161,10 +161,7 @@ where let seed_expr = Bool::fresh_const(&ctx, "seed"); let observers = executor.observers(); - let obs = observers - .match_name::(&self.obs_name) - .expect("Observer must be present.") - .as_ref(); + let obs = observers[&self.obs_ref].as_ref(); // Store coverage, mapping coverage map indices to hit counts (if present) and the // associated seeds for the map indices with those hit counts. diff --git a/libafl/src/events/centralized.rs b/libafl/src/events/centralized.rs index 7ce82ce8ac..e32a796875 100644 --- a/libafl/src/events/centralized.rs +++ b/libafl/src/events/centralized.rs @@ -10,6 +10,8 @@ use alloc::{boxed::Box, string::String, vec::Vec}; use core::{marker::PhantomData, num::NonZeroUsize, time::Duration}; +#[cfg(feature = "adaptive_serialization")] +use libafl_bolts::tuples::{Reference, Referenceable}; #[cfg(feature = "llmp_compression")] use libafl_bolts::{ compress::GzipCompressor, @@ -24,6 +26,8 @@ use serde::{Deserialize, Serialize}; #[cfg(feature = "llmp_compression")] use crate::events::llmp::COMPRESS_THRESHOLD; +#[cfg(feature = "adaptive_serialization")] +use crate::observers::TimeObserver; #[cfg(feature = "scalability_introspection")] use crate::state::HasScalabilityMonitor; use crate::{ @@ -221,6 +225,8 @@ where client: LlmpClient, #[cfg(feature = "llmp_compression")] compressor: GzipCompressor, + #[cfg(feature = "adaptive_serialization")] + time_ref: Reference, is_main: bool, } @@ -263,6 +269,10 @@ where fn should_serialize_cnt_mut(&mut self) -> &mut usize { self.inner.should_serialize_cnt_mut() } + + fn time_ref(&self) -> &Reference { + &self.time_ref + } } #[cfg(not(feature = "adaptive_serialization"))] @@ -275,7 +285,7 @@ where impl EventFirer for CentralizedEventManager where - EM: AdaptiveSerializer + EventFirer + HasEventManagerId + AdaptiveSerializer, + EM: AdaptiveSerializer + EventFirer + HasEventManagerId, SP: ShMemProvider + 'static, { fn fire( @@ -459,6 +469,7 @@ where SP: ShMemProvider + 'static, { /// Creates a new [`CentralizedEventManager`]. + #[cfg(not(feature = "adaptive_serialization"))] pub fn new(inner: EM, client: LlmpClient, is_main: bool) -> Result { Ok(Self { inner, @@ -469,11 +480,29 @@ where }) } + /// Creates a new [`CentralizedEventManager`]. + #[cfg(feature = "adaptive_serialization")] + pub fn new( + inner: EM, + client: LlmpClient, + is_main: bool, + time_obs: &TimeObserver, + ) -> Result { + Ok(Self { + inner, + client, + #[cfg(feature = "llmp_compression")] + compressor: GzipCompressor::new(COMPRESS_THRESHOLD), + time_ref: time_obs.type_ref(), + is_main, + }) + } + /// Create a centralized event manager on a port /// /// If the port is not yet bound, it will act as a broker; otherwise, it /// will act as a client. - #[cfg(feature = "std")] + #[cfg(all(feature = "std", not(feature = "adaptive_serialization")))] pub fn on_port(inner: EM, shmem_provider: SP, port: u16, is_main: bool) -> Result { let client = LlmpClient::create_attach_to_tcp(shmem_provider, port)?; Ok(Self { @@ -485,9 +514,32 @@ where }) } + /// Create a centralized event manager on a port + /// + /// If the port is not yet bound, it will act as a broker; otherwise, it + /// will act as a client. + #[cfg(all(feature = "std", feature = "adaptive_serialization"))] + pub fn on_port( + inner: EM, + shmem_provider: SP, + port: u16, + is_main: bool, + time_obs: &TimeObserver, + ) -> Result { + let client = LlmpClient::create_attach_to_tcp(shmem_provider, port)?; + Ok(Self { + inner, + client, + #[cfg(feature = "llmp_compression")] + compressor: GzipCompressor::new(COMPRESS_THRESHOLD), + time_ref: time_obs.type_ref(), + is_main, + }) + } + /// If a client respawns, it may reuse the existing connection, previously /// stored by [`LlmpClient::to_env()`]. - #[cfg(feature = "std")] + #[cfg(all(feature = "std", not(feature = "adaptive_serialization")))] pub fn existing_client_from_env( inner: EM, shmem_provider: SP, @@ -503,27 +555,67 @@ where }) } - /// Describe the client event manager's LLMP parts in a restorable fashion - pub fn describe(&self) -> Result { - self.client.describe() + /// If a client respawns, it may reuse the existing connection, previously + /// stored by [`LlmpClient::to_env()`]. + #[cfg(all(feature = "std", feature = "adaptive_serialization"))] + pub fn existing_client_from_env( + inner: EM, + shmem_provider: SP, + env_name: &str, + is_main: bool, + time_obs: &TimeObserver, + ) -> Result { + Ok(Self { + inner, + client: LlmpClient::on_existing_from_env(shmem_provider, env_name)?, + #[cfg(feature = "llmp_compression")] + compressor: GzipCompressor::new(COMPRESS_THRESHOLD), + time_ref: time_obs.type_ref(), + is_main, + }) + } + + /// Create an existing client from description + #[cfg(not(feature = "adaptive_serialization"))] + pub fn existing_client_from_description( + inner: EM, + shmem_provider: SP, + description: &LlmpClientDescription, + is_main: bool, + ) -> Result { + Ok(Self { + inner, + client: LlmpClient::existing_client_from_description(shmem_provider, description)?, + #[cfg(feature = "llmp_compression")] + compressor: GzipCompressor::new(COMPRESS_THRESHOLD), + is_main, + }) } /// Create an existing client from description + #[cfg(feature = "adaptive_serialization")] pub fn existing_client_from_description( inner: EM, shmem_provider: SP, description: &LlmpClientDescription, is_main: bool, + time_obs: &TimeObserver, ) -> Result { Ok(Self { inner, client: LlmpClient::existing_client_from_description(shmem_provider, description)?, #[cfg(feature = "llmp_compression")] compressor: GzipCompressor::new(COMPRESS_THRESHOLD), + time_ref: time_obs.type_ref(), is_main, }) } + /// Describe the client event manager's LLMP parts in a restorable fashion + pub fn describe(&self) -> Result { + self.client.describe() + } + /// Write the config for a client [`EventManager`] to env vars, a new /// client can reattach using [`CentralizedEventManager::existing_client_from_env()`]. #[cfg(feature = "std")] diff --git a/libafl/src/events/launcher.rs b/libafl/src/events/launcher.rs index bdc74e074e..a7d92d3f25 100644 --- a/libafl/src/events/launcher.rs +++ b/libafl/src/events/launcher.rs @@ -30,6 +30,8 @@ use std::{fs::File, os::unix::io::AsRawFd}; #[cfg(all(feature = "std", any(windows, not(feature = "fork"))))] use libafl_bolts::os::startable_self; +#[cfg(feature = "adaptive_serialization")] +use libafl_bolts::tuples::{Reference, Referenceable}; #[cfg(all(unix, feature = "std", feature = "fork"))] use libafl_bolts::{ core_affinity::get_core_ids, @@ -46,6 +48,8 @@ use typed_builder::TypedBuilder; use super::hooks::EventManagerHooksTuple; #[cfg(all(unix, feature = "std", feature = "fork"))] use crate::events::{CentralizedEventManager, CentralizedLlmpEventBroker}; +#[cfg(feature = "adaptive_serialization")] +use crate::observers::TimeObserver; #[cfg(feature = "std")] use crate::{ events::{ @@ -116,6 +120,8 @@ where /// clusters. #[builder(default = None)] remote_broker_addr: Option, + #[cfg(feature = "adaptive_serialization")] + time_ref: Reference, /// If this launcher should spawn a new `broker` on `[Self::broker_port]` (default). /// The reason you may not want this is, if you already have a [`Launcher`] /// with a different configuration (for the same target) running on this machine. @@ -250,7 +256,7 @@ where } // Fuzzer client. keeps retrying the connection to broker till the broker starts - let (state, mgr) = RestartingMgr::::builder() + let builder = RestartingMgr::::builder() .shmem_provider(self.shmem_provider.clone()) .broker_port(self.broker_port) .kind(ManagerKind::Client { @@ -258,9 +264,10 @@ where }) .configuration(self.configuration) .serialize_state(self.serialize_state) - .hooks(hooks) - .build() - .launch()?; + .hooks(hooks); + #[cfg(feature = "adaptive_serialization")] + let builder = builder.time_ref(self.time_ref.clone()); + let (state, mgr) = builder.build().launch()?; return (self.run_client.take().unwrap())(state, mgr, *bind_to); } @@ -273,7 +280,7 @@ where log::info!("I am broker!!."); // TODO we don't want always a broker here, think about using different laucher process to spawn different configurations - RestartingMgr::::builder() + let builder = RestartingMgr::::builder() .shmem_provider(self.shmem_provider.clone()) .monitor(Some(self.monitor.clone())) .broker_port(self.broker_port) @@ -282,9 +289,12 @@ where .exit_cleanly_after(Some(NonZeroUsize::try_from(self.cores.ids.len()).unwrap())) .configuration(self.configuration) .serialize_state(self.serialize_state) - .hooks(hooks) - .build() - .launch()?; + .hooks(hooks); + + #[cfg(feature = "adaptive_serialization")] + let builder = builder.time_ref(self.time_ref.clone()); + + builder.build().launch()?; // Broker exited. kill all clients. for handle in &handles { @@ -457,6 +467,9 @@ where /// The centralized broker port to use (or to attach to, in case [`Self::spawn_broker`] is `false`) #[builder(default = 1338_u16)] centralized_broker_port: u16, + /// The time observer by which to adaptively serialize + #[cfg(feature = "adaptive_serialization")] + time_obs: &'a TimeObserver, /// The list of cores to run on cores: &'a Cores, /// A file name to write all client output to @@ -617,7 +630,7 @@ where } // Fuzzer client. keeps retrying the connection to broker till the broker starts - let (state, mgr) = RestartingMgr::<(), MT, S, SP>::builder() + let builder = RestartingMgr::<(), MT, S, SP>::builder() .shmem_provider(self.shmem_provider.clone()) .broker_port(self.broker_port) .kind(ManagerKind::Client { @@ -625,15 +638,25 @@ where }) .configuration(self.configuration) .serialize_state(self.serialize_state) - .hooks(tuple_list!()) - .build() - .launch()?; + .hooks(tuple_list!()); + #[cfg(feature = "adaptive_serialization")] + let builder = builder.time_ref(self.time_obs.type_ref()); + let (state, mgr) = builder.build().launch()?; + #[cfg(not(feature = "adaptive_serialization"))] + let c_mgr = CentralizedEventManager::on_port( + mgr, + self.shmem_provider.clone(), + self.centralized_broker_port, + index == 1, + )?; + #[cfg(feature = "adaptive_serialization")] let c_mgr = CentralizedEventManager::on_port( mgr, self.shmem_provider.clone(), self.centralized_broker_port, index == 1, + self.time_obs, )?; return (self.run_client.take().unwrap())(state, c_mgr, *bind_to); @@ -646,7 +669,7 @@ where log::info!("I am broker!!."); // TODO we don't want always a broker here, think about using different laucher process to spawn different configurations - RestartingMgr::<(), MT, S, SP>::builder() + let builder = RestartingMgr::<(), MT, S, SP>::builder() .shmem_provider(self.shmem_provider.clone()) .monitor(Some(self.monitor.clone())) .broker_port(self.broker_port) @@ -655,9 +678,12 @@ where .exit_cleanly_after(Some(NonZeroUsize::try_from(self.cores.ids.len()).unwrap())) .configuration(self.configuration) .serialize_state(self.serialize_state) - .hooks(tuple_list!()) - .build() - .launch()?; + .hooks(tuple_list!()); + + #[cfg(feature = "adaptive_serialization")] + let builder = builder.time_ref(self.time_obs.type_ref()); + + builder.build().launch()?; // Broker exited. kill all clients. for handle in &handles { diff --git a/libafl/src/events/llmp.rs b/libafl/src/events/llmp.rs index c9daf2c96b..4fc92932b5 100644 --- a/libafl/src/events/llmp.rs +++ b/libafl/src/events/llmp.rs @@ -13,8 +13,6 @@ use std::net::TcpStream; #[cfg(feature = "std")] use std::net::{SocketAddr, ToSocketAddrs}; -#[cfg(feature = "adaptive_serialization")] -use libafl_bolts::current_time; #[cfg(all(feature = "std", any(windows, not(feature = "fork"))))] use libafl_bolts::os::startable_self; #[cfg(all(unix, feature = "std", not(miri)))] @@ -32,6 +30,11 @@ use libafl_bolts::{ llmp::{recv_tcp_msg, send_tcp_msg, TcpRequest, TcpResponse}, IP_LOCALHOST, }; +#[cfg(feature = "adaptive_serialization")] +use libafl_bolts::{ + current_time, + tuples::{Reference, Referenceable}, +}; #[cfg(feature = "std")] use libafl_bolts::{llmp::LlmpConnection, shmem::StdShMemProvider, staterestore::StateRestorer}; use libafl_bolts::{ @@ -49,6 +52,8 @@ use super::{hooks::EventManagerHooksTuple, CustomBufEventResult, CustomBufHandle use crate::events::AdaptiveSerializer; #[cfg(all(unix, feature = "std"))] use crate::events::EVENTMGR_SIGHANDLER_STATE; +#[cfg(feature = "adaptive_serialization")] +use crate::observers::TimeObserver; use crate::{ events::{ BrokerEventResult, Event, EventConfig, EventFirer, EventManager, EventManagerId, @@ -336,7 +341,7 @@ where } /// An [`EventManager`] that forwards all events to other attached fuzzers on shared maps or via tcp, -/// using low-level message passing, [`libafl_bolts::llmp`]. +/// using low-level message passing, [`llmp`]. pub struct LlmpEventManager where S: State, @@ -361,6 +366,8 @@ where serializations_cnt: usize, #[cfg(feature = "adaptive_serialization")] should_serialize_cnt: usize, + #[cfg(feature = "adaptive_serialization")] + time_ref: Reference, phantom: PhantomData, } @@ -395,6 +402,10 @@ where fn should_serialize_cnt_mut(&mut self) -> &mut usize { &mut self.should_serialize_cnt } + + fn time_ref(&self) -> &Reference { + &self.time_ref + } } impl core::fmt::Debug for LlmpEventManager @@ -432,6 +443,7 @@ where SP: ShMemProvider + 'static, { /// Create a manager from a raw LLMP client + #[cfg(not(feature = "adaptive_serialization"))] pub fn new(llmp: LlmpClient, configuration: EventConfig) -> Result { Ok(LlmpEventManager { hooks: tuple_list!(), @@ -439,14 +451,66 @@ where #[cfg(feature = "llmp_compression")] compressor: GzipCompressor::new(COMPRESS_THRESHOLD), configuration, - #[cfg(feature = "adaptive_serialization")] + phantom: PhantomData, + custom_buf_handlers: vec![], + }) + } + + /// Create an LLMP event manager on a port + /// + /// If the port is not yet bound, it will act as a broker; otherwise, it + /// will act as a client. + #[cfg(all(feature = "std", not(feature = "adaptive_serialization")))] + pub fn on_port( + shmem_provider: SP, + port: u16, + configuration: EventConfig, + ) -> Result, Error> { + let llmp = LlmpClient::create_attach_to_tcp(shmem_provider, port)?; + Self::new(llmp, configuration) + } + + /// If a client respawns, it may reuse the existing connection, previously + /// stored by [`LlmpClient::to_env()`]. + #[cfg(all(feature = "std", not(feature = "adaptive_serialization")))] + pub fn existing_client_from_env( + shmem_provider: SP, + env_name: &str, + configuration: EventConfig, + ) -> Result, Error> { + let llmp = LlmpClient::on_existing_from_env(shmem_provider, env_name)?; + Self::new(llmp, configuration) + } + + /// Create an existing client from description + #[cfg(not(feature = "adaptive_serialization"))] + pub fn existing_client_from_description( + shmem_provider: SP, + description: &LlmpClientDescription, + configuration: EventConfig, + ) -> Result, Error> { + let llmp = LlmpClient::existing_client_from_description(shmem_provider, description)?; + Self::new(llmp, configuration) + } + + /// Create a manager from a raw LLMP client + #[cfg(feature = "adaptive_serialization")] + pub fn new( + llmp: LlmpClient, + configuration: EventConfig, + time_ref: Reference, + ) -> Result { + Ok(LlmpEventManager { + hooks: tuple_list!(), + llmp, + #[cfg(feature = "llmp_compression")] + compressor: GzipCompressor::new(COMPRESS_THRESHOLD), + configuration, serialization_time: Duration::ZERO, - #[cfg(feature = "adaptive_serialization")] deserialization_time: Duration::ZERO, - #[cfg(feature = "adaptive_serialization")] serializations_cnt: 0, - #[cfg(feature = "adaptive_serialization")] should_serialize_cnt: 0, + time_ref, phantom: PhantomData, custom_buf_handlers: vec![], }) @@ -456,36 +520,40 @@ where /// /// If the port is not yet bound, it will act as a broker; otherwise, it /// will act as a client. - #[cfg(feature = "std")] + #[cfg(all(feature = "std", feature = "adaptive_serialization"))] pub fn on_port( shmem_provider: SP, port: u16, configuration: EventConfig, + time_ref: Reference, ) -> Result, Error> { let llmp = LlmpClient::create_attach_to_tcp(shmem_provider, port)?; - Self::new(llmp, configuration) + Self::new(llmp, configuration, time_ref) } /// If a client respawns, it may reuse the existing connection, previously /// stored by [`LlmpClient::to_env()`]. - #[cfg(feature = "std")] + #[cfg(all(feature = "std", feature = "adaptive_serialization"))] pub fn existing_client_from_env( shmem_provider: SP, env_name: &str, configuration: EventConfig, + time_ref: Reference, ) -> Result, Error> { let llmp = LlmpClient::on_existing_from_env(shmem_provider, env_name)?; - Self::new(llmp, configuration) + Self::new(llmp, configuration, time_ref) } /// Create an existing client from description + #[cfg(feature = "adaptive_serialization")] pub fn existing_client_from_description( shmem_provider: SP, description: &LlmpClientDescription, configuration: EventConfig, + time_ref: Reference, ) -> Result, Error> { let llmp = LlmpClient::existing_client_from_description(shmem_provider, description)?; - Self::new(llmp, configuration) + Self::new(llmp, configuration, time_ref) } } @@ -494,43 +562,73 @@ where S: State, SP: ShMemProvider + 'static, { - /// Calling this function will tell the llmp broker that this client is exiting - /// This should be called from the restarter not from the actual fuzzer client - /// This function serves the same roll as the `LlmpClient.send_exiting()` - /// However, from the the event restarter process it is forbidden to call `send_exiting()` - /// (You can call it and it compiles but you should never do so) - /// `send_exiting()` is exclusive to the fuzzer client. - #[cfg(feature = "std")] - pub fn detach_from_broker(&self, broker_port: u16) -> Result<(), Error> { - let client_id = self.llmp.sender().id(); - let Ok(mut stream) = TcpStream::connect((IP_LOCALHOST, broker_port)) else { - log::error!("Connection refused."); - return Ok(()); - }; - // The broker tells us hello we don't care we just tell it our client died - let TcpResponse::BrokerConnectHello { - broker_shmem_description: _, - hostname: _, - } = recv_tcp_msg(&mut stream)?.try_into()? - else { - return Err(Error::illegal_state( - "Received unexpected Broker Hello".to_string(), - )); - }; - let msg = TcpRequest::ClientQuit { client_id }; - // Send this mesasge off and we are leaving. - match send_tcp_msg(&mut stream, &msg) { - Ok(_) => (), - Err(e) => log::error!("Failed to send tcp message {:#?}", e), - } - log::info!("Asking he broker to be disconnected"); - Ok(()) + /// Create a manager from a raw LLMP client with hooks + #[cfg(not(feature = "adaptive_serialization"))] + pub fn with_hooks( + llmp: LlmpClient, + configuration: EventConfig, + hooks: EMH, + ) -> Result { + Ok(Self { + hooks, + llmp, + #[cfg(feature = "llmp_compression")] + compressor: GzipCompressor::new(COMPRESS_THRESHOLD), + configuration, + phantom: PhantomData, + custom_buf_handlers: vec![], + }) + } + + /// Create an LLMP event manager on a port with hook + /// + /// If the port is not yet bound, it will act as a broker; otherwise, it + /// will act as a client. + /// This will make a new connection to the broker so will return its new [`ClientId`], too + #[cfg(all(feature = "std", not(feature = "adaptive_serialization")))] + pub fn on_port_with_hooks( + shmem_provider: SP, + port: u16, + configuration: EventConfig, + hooks: EMH, + ) -> Result { + let llmp = LlmpClient::create_attach_to_tcp(shmem_provider, port)?; + Self::with_hooks(llmp, configuration, hooks) + } + + /// If a client respawns, it may reuse the existing connection, previously + /// stored by [`LlmpClient::to_env()`]. + /// create a event manager from env with hooks + #[cfg(all(feature = "std", not(feature = "adaptive_serialization")))] + pub fn existing_client_from_env_with_hooks( + shmem_provider: SP, + env_name: &str, + configuration: EventConfig, + hooks: EMH, + ) -> Result { + let llmp = LlmpClient::on_existing_from_env(shmem_provider, env_name)?; + Self::with_hooks(llmp, configuration, hooks) + } + + /// Create an existing client from description + #[cfg(not(feature = "adaptive_serialization"))] + pub fn existing_client_from_description_with_hooks( + shmem_provider: SP, + description: &LlmpClientDescription, + configuration: EventConfig, + hooks: EMH, + ) -> Result { + let llmp = LlmpClient::existing_client_from_description(shmem_provider, description)?; + Self::with_hooks(llmp, configuration, hooks) } + /// Create a manager from a raw LLMP client with hooks + #[cfg(feature = "adaptive_serialization")] pub fn with_hooks( llmp: LlmpClient, configuration: EventConfig, hooks: EMH, + time_ref: Reference, ) -> Result { Ok(Self { hooks, @@ -538,14 +636,11 @@ where #[cfg(feature = "llmp_compression")] compressor: GzipCompressor::new(COMPRESS_THRESHOLD), configuration, - #[cfg(feature = "adaptive_serialization")] serialization_time: Duration::ZERO, - #[cfg(feature = "adaptive_serialization")] deserialization_time: Duration::ZERO, - #[cfg(feature = "adaptive_serialization")] serializations_cnt: 0, - #[cfg(feature = "adaptive_serialization")] should_serialize_cnt: 0, + time_ref, phantom: PhantomData, custom_buf_handlers: vec![], }) @@ -556,45 +651,82 @@ where /// If the port is not yet bound, it will act as a broker; otherwise, it /// will act as a client. /// This will make a new connection to the broker so will return its new [`ClientId`], too - #[cfg(feature = "std")] + #[cfg(all(feature = "std", feature = "adaptive_serialization"))] pub fn on_port_with_hooks( shmem_provider: SP, port: u16, configuration: EventConfig, hooks: EMH, + time_ref: Reference, ) -> Result { let llmp = LlmpClient::create_attach_to_tcp(shmem_provider, port)?; - Self::with_hooks(llmp, configuration, hooks) + Self::with_hooks(llmp, configuration, hooks, time_ref) } /// If a client respawns, it may reuse the existing connection, previously /// stored by [`LlmpClient::to_env()`]. /// create a event manager from env with hooks - #[cfg(feature = "std")] + #[cfg(all(feature = "std", feature = "adaptive_serialization"))] pub fn existing_client_from_env_with_hooks( shmem_provider: SP, env_name: &str, configuration: EventConfig, hooks: EMH, + time_ref: Reference, ) -> Result { let llmp = LlmpClient::on_existing_from_env(shmem_provider, env_name)?; - Self::with_hooks(llmp, configuration, hooks) - } - - /// Describe the client event manager's LLMP parts in a restorable fashion - pub fn describe(&self) -> Result { - self.llmp.describe() + Self::with_hooks(llmp, configuration, hooks, time_ref) } /// Create an existing client from description + #[cfg(feature = "adaptive_serialization")] pub fn existing_client_from_description_with_hooks( shmem_provider: SP, description: &LlmpClientDescription, configuration: EventConfig, hooks: EMH, + time_ref: Reference, ) -> Result { let llmp = LlmpClient::existing_client_from_description(shmem_provider, description)?; - Self::with_hooks(llmp, configuration, hooks) + Self::with_hooks(llmp, configuration, hooks, time_ref) + } + + /// Calling this function will tell the llmp broker that this client is exiting + /// This should be called from the restarter not from the actual fuzzer client + /// This function serves the same roll as the `LlmpClient.send_exiting()` + /// However, from the the event restarter process it is forbidden to call `send_exiting()` + /// (You can call it and it compiles but you should never do so) + /// `send_exiting()` is exclusive to the fuzzer client. + #[cfg(feature = "std")] + pub fn detach_from_broker(&self, broker_port: u16) -> Result<(), Error> { + let client_id = self.llmp.sender().id(); + let Ok(mut stream) = TcpStream::connect((IP_LOCALHOST, broker_port)) else { + log::error!("Connection refused."); + return Ok(()); + }; + // The broker tells us hello we don't care we just tell it our client died + let TcpResponse::BrokerConnectHello { + broker_shmem_description: _, + hostname: _, + } = recv_tcp_msg(&mut stream)?.try_into()? + else { + return Err(Error::illegal_state( + "Received unexpected Broker Hello".to_string(), + )); + }; + let msg = TcpRequest::ClientQuit { client_id }; + // Send this mesasge off and we are leaving. + match send_tcp_msg(&mut stream, &msg) { + Ok(_) => (), + Err(e) => log::error!("Failed to send tcp message {:#?}", e), + } + log::info!("Asking he broker to be disconnected"); + Ok(()) + } + + /// Describe the client event manager's LLMP parts in a restorable fashion + pub fn describe(&self) -> Result { + self.llmp.describe() } /// Write the config for a client [`EventManager`] to env vars, a new @@ -958,6 +1090,10 @@ where fn should_serialize_cnt_mut(&mut self) -> &mut usize { self.llmp_mgr.should_serialize_cnt_mut() } + + fn time_ref(&self) -> &Reference { + &self.llmp_mgr.time_ref + } } #[cfg(all(feature = "std", not(feature = "adaptive_serialization")))] @@ -1172,7 +1308,7 @@ pub enum ManagerKind { /// Sets up a restarting fuzzer, using the [`StdShMemProvider`], and standard features. /// The restarting mgr is a combination of restarter and runner, that can be used on systems with and without `fork` support. /// The restarter will spawn a new process each time the child crashes or timeouts. -#[cfg(feature = "std")] +#[cfg(all(feature = "std", not(feature = "adaptive_serialization")))] #[allow(clippy::type_complexity)] pub fn setup_restarting_mgr_std( monitor: MT, @@ -1199,6 +1335,38 @@ where .launch() } +/// Sets up a restarting fuzzer, using the [`StdShMemProvider`], and standard features. +/// The restarting mgr is a combination of restarter and runner, that can be used on systems with and without `fork` support. +/// The restarter will spawn a new process each time the child crashes or timeouts. +#[cfg(all(feature = "std", feature = "adaptive_serialization"))] +#[allow(clippy::type_complexity)] +pub fn setup_restarting_mgr_std( + monitor: MT, + broker_port: u16, + configuration: EventConfig, + time_obs: &TimeObserver, +) -> Result< + ( + Option, + LlmpRestartingEventManager<(), S, StdShMemProvider>, + ), + Error, +> +where + MT: Monitor + Clone, + S: State + HasExecutions, +{ + RestartingMgr::builder() + .shmem_provider(StdShMemProvider::new()?) + .monitor(Some(monitor)) + .broker_port(broker_port) + .configuration(configuration) + .hooks(tuple_list!()) + .time_ref(time_obs.type_ref()) + .build() + .launch() +} + /// Provides a `builder` which can be used to build a [`RestartingMgr`], which is a combination of a /// `restarter` and `runner`, that can be used on systems both with and without `fork` support. The /// `restarter` will start a new process each time the child crashes or times out. @@ -1243,6 +1411,8 @@ where serialize_state: LlmpShouldSaveState, /// The hooks passed to event manager: hooks: EMH, + #[cfg(feature = "adaptive_serialization")] + time_ref: Reference, #[builder(setter(skip), default = PhantomData)] phantom_data: PhantomData<(EMH, S)>, } @@ -1310,11 +1480,19 @@ where return Err(Error::shutting_down()); } LlmpConnection::IsClient { client } => { + #[cfg(not(feature = "adaptive_serialization"))] let mgr = LlmpEventManager::::with_hooks( client, self.configuration, self.hooks, )?; + #[cfg(feature = "adaptive_serialization")] + let mgr = LlmpEventManager::::with_hooks( + client, + self.configuration, + self.hooks, + self.time_ref.clone(), + )?; (mgr, None) } } @@ -1331,12 +1509,21 @@ where } ManagerKind::Client { cpu_core } => { // We are a client + #[cfg(not(feature = "adaptive_serialization"))] let mgr = LlmpEventManager::::on_port_with_hooks( self.shmem_provider.clone(), self.broker_port, self.configuration, self.hooks, )?; + #[cfg(feature = "adaptive_serialization")] + let mgr = LlmpEventManager::::on_port_with_hooks( + self.shmem_provider.clone(), + self.broker_port, + self.configuration, + self.hooks, + self.time_ref.clone(), + )?; (mgr, cpu_core) } @@ -1449,15 +1636,25 @@ where // If we're restarting, deserialize the old state. let (state, mut mgr) = if let Some((state_opt, mgr_description)) = staterestorer.restore()? { + #[cfg(not(feature = "adaptive_serialization"))] + let llmp_mgr = LlmpEventManager::existing_client_from_description_with_hooks( + new_shmem_provider, + &mgr_description, + self.configuration, + self.hooks, + )?; + #[cfg(feature = "adaptive_serialization")] + let llmp_mgr = LlmpEventManager::existing_client_from_description_with_hooks( + new_shmem_provider, + &mgr_description, + self.configuration, + self.hooks, + self.time_ref.clone(), + )?; ( state_opt, LlmpRestartingEventManager::with_save_state( - LlmpEventManager::existing_client_from_description_with_hooks( - new_shmem_provider, - &mgr_description, - self.configuration, - self.hooks, - )?, + llmp_mgr, staterestorer, self.serialize_state, ), @@ -1465,11 +1662,20 @@ where } else { log::info!("First run. Let's set it all up"); // Mgr to send and receive msgs from/to all other fuzzer instances + #[cfg(not(feature = "adaptive_serialization"))] + let mgr = LlmpEventManager::::existing_client_from_env_with_hooks( + new_shmem_provider, + _ENV_FUZZER_BROKER_CLIENT_INITIAL, + self.configuration, + self.hooks, + )?; + #[cfg(feature = "adaptive_serialization")] let mgr = LlmpEventManager::::existing_client_from_env_with_hooks( new_shmem_provider, _ENV_FUZZER_BROKER_CLIENT_INITIAL, self.configuration, self.hooks, + self.time_ref.clone(), )?; ( @@ -1854,6 +2060,8 @@ where mod tests { use core::sync::atomic::{compiler_fence, Ordering}; + #[cfg(feature = "adaptive_serialization")] + use libafl_bolts::tuples::Referenceable; use libafl_bolts::{ llmp::{LlmpClient, LlmpSharedMap}, rands::StdRand, @@ -1872,6 +2080,7 @@ mod tests { fuzzer::Fuzzer, inputs::BytesInput, mutators::BitFlipMutator, + observers::TimeObserver, schedulers::RandScheduler, stages::StdMutationalStage, state::StdState, @@ -1884,6 +2093,10 @@ mod tests { fn test_mgr_state_restore() { let rand = StdRand::with_seed(0); + let time = TimeObserver::new("time"); + #[cfg(feature = "adaptive_serialization")] + let time_ref = time.type_ref(); + let mut corpus = InMemoryCorpus::::new(); let testcase = Testcase::new(vec![0; 4].into()); corpus.add(testcase).unwrap(); @@ -1910,7 +2123,11 @@ mod tests { llmp_client.mark_safe_to_unmap(); } + #[cfg(not(feature = "adaptive_serialization"))] let mut llmp_mgr = LlmpEventManager::new(llmp_client, "fuzzer".into()).unwrap(); + #[cfg(feature = "adaptive_serialization")] + let mut llmp_mgr = + LlmpEventManager::new(llmp_client, "fuzzer".into(), time_ref.clone()).unwrap(); let scheduler = RandScheduler::new(); @@ -1922,7 +2139,7 @@ mod tests { let mut harness = |_buf: &BytesInput| ExitKind::Ok; let mut executor = InProcessExecutor::new( &mut harness, - tuple_list!(), + tuple_list!(time), &mut fuzzer, &mut state, &mut llmp_mgr, @@ -1952,22 +2169,29 @@ mod tests { assert!(sc_cpy.has_content()); let (mut state_clone, mgr_description) = staterestorer.restore().unwrap().unwrap(); + #[cfg(not(feature = "adaptive_serialization"))] let mut llmp_clone = LlmpEventManager::existing_client_from_description( shmem_provider, &mgr_description, "fuzzer".into(), ) .unwrap(); + #[cfg(feature = "adaptive_serialization")] + let mut llmp_clone = LlmpEventManager::existing_client_from_description( + shmem_provider, + &mgr_description, + "fuzzer".into(), + time_ref, + ) + .unwrap(); - if false { - fuzzer - .fuzz_one( - &mut stages, - &mut executor, - &mut state_clone, - &mut llmp_clone, - ) - .unwrap(); - } + fuzzer + .fuzz_one( + &mut stages, + &mut executor, + &mut state_clone, + &mut llmp_clone, + ) + .unwrap(); } } diff --git a/libafl/src/events/mod.rs b/libafl/src/events/mod.rs index a5b9963ce7..ec90d44d0e 100644 --- a/libafl/src/events/mod.rs +++ b/libafl/src/events/mod.rs @@ -32,6 +32,8 @@ use ahash::RandomState; pub use launcher::*; #[cfg(all(unix, feature = "std"))] use libafl_bolts::os::unix_signals::{siginfo_t, ucontext_t, Handler, Signal}; +#[cfg(feature = "adaptive_serialization")] +use libafl_bolts::tuples::{MatchNameRef, Reference}; use libafl_bolts::{current_time, ClientId}; use serde::{Deserialize, Serialize}; #[cfg(feature = "std")] @@ -119,7 +121,7 @@ impl Handler for ShutdownSignalData { } /// A per-fuzzer unique `ID`, usually starting with `0` and increasing -/// by `1` in multiprocessed [`EventManager`]s, such as [`self::llmp::LlmpEventManager`]. +/// by `1` in multiprocessed [`EventManager`]s, such as [`LlmpEventManager`]. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pub struct EventManagerId( @@ -129,6 +131,8 @@ pub struct EventManagerId( #[cfg(feature = "introspection")] use crate::monitors::ClientPerfMonitor; +#[cfg(feature = "adaptive_serialization")] +use crate::observers::TimeObserver; use crate::{inputs::UsesInput, stages::HasCurrentStage, state::UsesState}; /// The log event severity @@ -415,7 +419,7 @@ where pub trait EventFirer: UsesState { /// Send off an [`Event`] to the broker /// - /// For multi-processed managers, such as [`llmp::LlmpEventManager`], + /// For multi-processed managers, such as [`LlmpEventManager`], /// this serializes the [`Event`] and commits it to the [`llmp`] page. /// In this case, if you `fire` faster than the broker can consume /// (for example for each [`Input`], on multiple cores) @@ -466,7 +470,7 @@ where { /// Given the last time, if `monitor_timeout` seconds passed, send off an info/monitor/heartbeat message to the broker. /// Returns the new `last` time (so the old one, unless `monitor_timeout` time has passed and monitor have been sent) - /// Will return an [`crate::Error`], if the stats could not be sent. + /// Will return an [`Error`], if the stats could not be sent. fn maybe_report_progress( &mut self, state: &mut Self::State, @@ -487,7 +491,7 @@ where } /// Send off an info/monitor/heartbeat message to the broker. - /// Will return an [`crate::Error`], if the stats could not be sent. + /// Will return an [`Error`], if the stats could not be sent. fn report_progress(&mut self, state: &mut Self::State) -> Result<(), Error> { let executions = *state.executions(); let cur = current_time(); @@ -875,6 +879,9 @@ pub trait AdaptiveSerializer { /// How many times shoukd have been serialized an observer (mut) fn should_serialize_cnt_mut(&mut self) -> &mut usize; + /// A [`Reference`] to the time observer to determine the `time_factor` + fn time_ref(&self) -> &Reference; + /// Serialize the observer using the `time_factor` and `percentage_threshold`. /// These parameters are unique to each of the different types of `EventManager` fn serialize_observers_adaptive( @@ -888,7 +895,7 @@ pub trait AdaptiveSerializer { S: UsesInput, { let exec_time = observers - .match_name::("time") + .get(self.time_ref()) .map(|o| o.last_runtime().unwrap_or(Duration::ZERO)) .unwrap(); diff --git a/libafl/src/executors/shadow.rs b/libafl/src/executors/shadow.rs index 86ce75c994..242fca8413 100644 --- a/libafl/src/executors/shadow.rs +++ b/libafl/src/executors/shadow.rs @@ -47,14 +47,14 @@ where /// The shadow observers are not considered by the feedbacks and the manager, mutable #[inline] - pub fn shadow_observers(&self) -> &SOT { - &self.shadow_observers + pub fn shadow_observers(&self) -> RefIndexable<&SOT, SOT> { + RefIndexable::from(&self.shadow_observers) } /// The shadow observers are not considered by the feedbacks and the manager, mutable #[inline] - pub fn shadow_observers_mut(&mut self) -> &mut SOT { - &mut self.shadow_observers + pub fn shadow_observers_mut(&mut self) -> RefIndexable<&mut SOT, SOT> { + RefIndexable::from(&mut self.shadow_observers) } } diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index a12c28d9c1..e3bcc901bb 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -608,7 +608,7 @@ where type Target = RM::Target; fn deref(&self) -> &Self::Target { - self.0.deref() + &self.0 } } @@ -618,7 +618,7 @@ where RM: DerefMut, { fn deref_mut(&mut self) -> &mut Self::Target { - self.0.deref_mut() + &mut self.0 } } @@ -632,7 +632,7 @@ where fn index(&self, index: &Reference) -> &Self::Output { let Some(e) = self.get(index) else { - panic!("Could not find entry matching {:?}", index) + panic!("Could not find entry matching {index:?}") }; e } @@ -646,7 +646,7 @@ where { fn index_mut(&mut self, index: &Reference) -> &mut Self::Output { let Some(e) = self.get_mut(index) else { - panic!("Could not find entry matching {:?}", index) + panic!("Could not find entry matching {index:?}") }; e } From b2f7c4962e837acb4300a2e363a90eb40a15fdd8 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 26 Apr 2024 03:07:06 +0200 Subject: [PATCH 23/31] remaining clippy items --- libafl_frida/src/asan/errors.rs | 23 ++++---- libafl_frida/src/lib.rs | 9 ++- libafl_qemu/src/helpers/calls.rs | 33 +++++------ libafl_sugar/Cargo.toml | 2 +- libafl_sugar/src/forkserver.rs | 14 +++-- libafl_sugar/src/inmemory.rs | 14 +++-- libafl_sugar/src/qemu.rs | 15 +++-- libafl_targets/src/cmps/observers/aflpp.rs | 19 ++----- .../src/cmps/stages/aflpptracing.rs | 56 ++++++++++--------- 9 files changed, 96 insertions(+), 89 deletions(-) diff --git a/libafl_frida/src/asan/errors.rs b/libafl_frida/src/asan/errors.rs index 100d63880b..a93712190e 100644 --- a/libafl_frida/src/asan/errors.rs +++ b/libafl_frida/src/asan/errors.rs @@ -22,7 +22,11 @@ use libafl::{ state::State, Error, HasMetadata, }; -use libafl_bolts::{ownedref::OwnedPtr, Named, SerdeAny}; +use libafl_bolts::{ + ownedref::OwnedPtr, + tuples::{MatchNameRef, Reference, Referenceable}, + Named, SerdeAny, +}; use serde::{Deserialize, Serialize}; use termcolor::{Color, ColorSpec, WriteColor}; #[cfg(target_arch = "aarch64")] @@ -39,8 +43,6 @@ use crate::{ alloc::AllocationMetadata, asan::asan_rt::ASAN_SAVE_REGISTER_COUNT, utils::disas_count, }; -static ASAN_ERRORS_NAME: Cow<'static, str> = Cow::Borrowed("AsanErrors"); - #[derive(Debug, Clone, Serialize, Deserialize)] pub(crate) struct AsanReadWriteError { pub registers: [usize; ASAN_SAVE_REGISTER_COUNT], @@ -591,6 +593,7 @@ where impl Named for AsanErrorsObserver { #[inline] fn name(&self) -> &Cow<'static, str> { + static ASAN_ERRORS_NAME: Cow<'static, str> = Cow::Borrowed("AsanErrors"); &ASAN_ERRORS_NAME } } @@ -643,6 +646,7 @@ impl AsanErrorsObserver { #[derive(Serialize, Deserialize, Clone, Debug)] pub struct AsanErrorsFeedback { errors: Option, + obs_ref: Reference, phantom: PhantomData, } @@ -665,7 +669,7 @@ where OT: ObserversTuple, { let observer = observers - .match_name::(&ASAN_ERRORS_NAME) + .get(&self.obs_ref) .expect("An AsanErrorsFeedback needs an AsanErrorsObserver"); let errors = observer.errors(); if errors.is_empty() { @@ -702,23 +706,18 @@ where impl Named for AsanErrorsFeedback { #[inline] fn name(&self) -> &Cow<'static, str> { - &ASAN_ERRORS_NAME + self.obs_ref.name() } } impl AsanErrorsFeedback { /// Create a new `AsanErrorsFeedback` #[must_use] - pub fn new() -> Self { + pub fn new(obs: &AsanErrorsObserver) -> Self { Self { errors: None, + obs_ref: obs.type_ref(), phantom: PhantomData, } } } - -impl Default for AsanErrorsFeedback { - fn default() -> Self { - Self::new() - } -} diff --git a/libafl_frida/src/lib.rs b/libafl_frida/src/lib.rs index f632c2f82a..54b50e0b83 100644 --- a/libafl_frida/src/lib.rs +++ b/libafl_frida/src/lib.rs @@ -416,10 +416,15 @@ mod tests { let mut feedback = ConstFeedback::new(false); + let asan_obs = AsanErrorsObserver::from_static_asan_errors(); + // Feedbacks to recognize an input as solution let mut objective = feedback_or_fast!( // true enables the AsanErrorFeedback - feedback_and_fast!(ConstFeedback::from(true), AsanErrorsFeedback::new()) + feedback_and_fast!( + ConstFeedback::from(true), + AsanErrorsFeedback::new(&asan_obs) + ) ); let mut state = StdState::new( @@ -436,7 +441,7 @@ mod tests { let mut fuzzer = StdFuzzer::new(StdScheduler::new(), feedback, objective); let observers = tuple_list!( - AsanErrorsObserver::from_static_asan_errors() //, + asan_obs //, ); { diff --git a/libafl_qemu/src/helpers/calls.rs b/libafl_qemu/src/helpers/calls.rs index b0fa7b1876..3cd974fa21 100644 --- a/libafl_qemu/src/helpers/calls.rs +++ b/libafl_qemu/src/helpers/calls.rs @@ -6,7 +6,7 @@ use libafl::{ inputs::{Input, UsesInput}, observers::{stacktrace::BacktraceObserver, ObserversTuple}, }; -use libafl_bolts::{tuples::MatchFirstType, Named}; +use libafl_bolts::tuples::{MatchFirstType, MatchNameRef, Reference, Referenceable}; use libafl_qemu_sys::GuestAddr; use thread_local::ThreadLocal; @@ -21,7 +21,7 @@ use crate::{ Qemu, }; -pub trait CallTraceCollector: 'static + Debug { +pub trait CallTraceCollector: 'static { fn on_call( &mut self, hooks: &mut QemuHooks, @@ -62,7 +62,7 @@ pub trait CallTraceCollector: 'static + Debug { } } -pub trait CallTraceCollectorTuple: 'static + MatchFirstType + Debug { +pub trait CallTraceCollectorTuple: 'static + MatchFirstType { fn on_call_all( &mut self, hooks: &mut QemuHooks, @@ -402,7 +402,7 @@ where impl QemuHelper for QemuCallTracerHelper where S: UsesInput, - T: CallTraceCollectorTuple, + T: CallTraceCollectorTuple + Debug, { fn init_hooks(&self, hooks: &QemuHooks) where @@ -437,25 +437,17 @@ where // TODO support multiple threads with thread local callstack #[derive(Debug)] -pub struct OnCrashBacktraceCollector { +pub struct OnCrashBacktraceCollector<'a> { callstack_hash: u64, - observer_name: String, + obs_ref: Reference>, } -impl OnCrashBacktraceCollector { +impl<'a> OnCrashBacktraceCollector<'a> { #[must_use] - pub fn new(observer: &BacktraceObserver<'_>) -> Self { + pub fn new(observer: &BacktraceObserver<'a>) -> Self { Self { callstack_hash: 0, - observer_name: observer.name().to_string(), - } - } - - #[must_use] - pub fn with_name(observer_name: String) -> Self { - Self { - callstack_hash: 0, - observer_name, + obs_ref: observer.type_ref(), } } @@ -469,7 +461,10 @@ impl OnCrashBacktraceCollector { } } -impl CallTraceCollector for OnCrashBacktraceCollector { +impl<'a> CallTraceCollector for OnCrashBacktraceCollector<'a> +where + 'a: 'static, +{ #[allow(clippy::unnecessary_cast)] fn on_call( &mut self, @@ -516,7 +511,7 @@ impl CallTraceCollector for OnCrashBacktraceCollector { S: UsesInput, { let observer = observers - .match_name_mut::>(&self.observer_name) + .get_mut(&self.obs_ref) .expect("A OnCrashBacktraceCollector needs a BacktraceObserver"); observer.fill_external(self.callstack_hash, exit_kind); } diff --git a/libafl_sugar/Cargo.toml b/libafl_sugar/Cargo.toml index 384adc3e29..8c14f7fece 100644 --- a/libafl_sugar/Cargo.toml +++ b/libafl_sugar/Cargo.toml @@ -17,7 +17,7 @@ all-features = true [features] python = ["pyo3", "libafl_qemu/python", "pyo3-build-config"] -default = [] +default = ["libafl/adaptive_serialization"] # for libafl_qemu # The following architecture features are mutually exclusive. diff --git a/libafl_sugar/src/forkserver.rs b/libafl_sugar/src/forkserver.rs index 8b7179d759..fd1efa9f48 100644 --- a/libafl_sugar/src/forkserver.rs +++ b/libafl_sugar/src/forkserver.rs @@ -26,7 +26,7 @@ use libafl_bolts::{ current_nanos, rands::StdRand, shmem::{ShMem, ShMemProvider, UnixShMemProvider}, - tuples::{tuple_list, Merge}, + tuples::{tuple_list, Merge, Referenceable}, AsSliceMut, }; use typed_builder::TypedBuilder; @@ -114,9 +114,15 @@ impl<'a> ForkserverBytesCoverageSugar<'a> { let monitor = MultiMonitor::new(|s| log::info!("{s}")); + // Create an observation channel to keep track of the execution time + let time_observer = TimeObserver::new("time"); + let time_ref = time_observer.type_ref(); + let mut run_client = |state: Option<_>, mut mgr: LlmpRestartingEventManager<_, _, _>, _core_id| { + let time_observer = time_observer.clone(); + // Coverage map shared between target and fuzzer let mut shmem = shmem_provider_client.new_shmem(MAP_SIZE).unwrap(); shmem.write_to_env("__AFL_SHM_ID").unwrap(); @@ -131,9 +137,6 @@ impl<'a> ForkserverBytesCoverageSugar<'a> { .track_indices() }; - // Create an observation channel to keep track of the execution time - let time_observer = TimeObserver::new("time"); - // Feedback to rate the interestingness of an input // This one is composed by two Feedbacks in OR let mut feedback = feedback_or!( @@ -292,7 +295,8 @@ impl<'a> ForkserverBytesCoverageSugar<'a> { .run_client(&mut run_client) .cores(self.cores) .broker_port(self.broker_port) - .remote_broker_addr(self.remote_broker_addr); + .remote_broker_addr(self.remote_broker_addr) + .time_ref(time_ref); #[cfg(unix)] let launcher = launcher.stdout_file(Some("/dev/null")); match launcher.build().launch() { diff --git a/libafl_sugar/src/inmemory.rs b/libafl_sugar/src/inmemory.rs index 90ce2f0256..d95020c9e9 100644 --- a/libafl_sugar/src/inmemory.rs +++ b/libafl_sugar/src/inmemory.rs @@ -29,7 +29,7 @@ use libafl_bolts::{ current_nanos, rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, - tuples::{tuple_list, Merge}, + tuples::{tuple_list, Merge, Referenceable}, AsSlice, }; use libafl_targets::{std_edges_map_observer, CmpLogObserver}; @@ -138,17 +138,20 @@ where let monitor = MultiMonitor::new(|s| println!("{s}")); + // Create an observation channel to keep track of the execution time + let time_observer = TimeObserver::new("time"); + let time_ref = time_observer.type_ref(); + let mut run_client = |state: Option<_>, mut mgr: LlmpRestartingEventManager<_, _, _>, _core_id| { + let time_observer = time_observer.clone(); + // Create an observation channel using the coverage map let edges_observer = HitcountsMapObserver::new(unsafe { std_edges_map_observer("edges") }) .track_indices(); - // Create an observation channel to keep track of the execution time - let time_observer = TimeObserver::new("time"); - let cmplog_observer = CmpLogObserver::new("cmplog", true); // Feedback to rate the interestingness of an input @@ -340,7 +343,8 @@ where .run_client(&mut run_client) .cores(self.cores) .broker_port(self.broker_port) - .remote_broker_addr(self.remote_broker_addr); + .remote_broker_addr(self.remote_broker_addr) + .time_ref(time_ref); #[cfg(unix)] let launcher = launcher.stdout_file(Some("/dev/null")); match launcher.build().launch() { diff --git a/libafl_sugar/src/qemu.rs b/libafl_sugar/src/qemu.rs index 0b1b5fbad2..66b2cbe5e8 100644 --- a/libafl_sugar/src/qemu.rs +++ b/libafl_sugar/src/qemu.rs @@ -32,7 +32,7 @@ use libafl_bolts::{ current_nanos, rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, - tuples::{tuple_list, Merge}, + tuples::{tuple_list, Merge, Referenceable}, AsSlice, }; pub use libafl_qemu::emu::Qemu; @@ -146,9 +146,15 @@ where let monitor = MultiMonitor::new(|s| log::info!("{s}")); + // Create an observation channel to keep track of the execution time + let time_observer = TimeObserver::new("time"); + let time_ref = time_observer.type_ref(); + let mut run_client = |state: Option<_>, mut mgr: LlmpRestartingEventManager<_, _, _>, _core_id| { + let time_observer = time_observer.clone(); + // Create an observation channel using the coverage map let edges_observer = unsafe { HitcountsMapObserver::new(VariableMapObserver::from_mut_slice( @@ -159,9 +165,6 @@ where .track_indices() }; - // Create an observation channel to keep track of the execution time - let time_observer = TimeObserver::new("time"); - // Keep tracks of CMPs let cmplog_observer = CmpLogObserver::new("cmplog", true); @@ -433,9 +436,11 @@ where .run_client(&mut run_client) .cores(self.cores) .broker_port(self.broker_port) - .remote_broker_addr(self.remote_broker_addr); + .remote_broker_addr(self.remote_broker_addr) + .time_ref(time_ref); #[cfg(unix)] let launcher = launcher.stdout_file(Some("/dev/null")); + launcher.build().launch().expect("Launcher failed"); } } diff --git a/libafl_targets/src/cmps/observers/aflpp.rs b/libafl_targets/src/cmps/observers/aflpp.rs index 41db1ecac4..4405072c3b 100644 --- a/libafl_targets/src/cmps/observers/aflpp.rs +++ b/libafl_targets/src/cmps/observers/aflpp.rs @@ -65,10 +65,7 @@ struct cmp_map { /// A [`CmpObserver`] observer for AFL++ redqueen #[derive(Serialize, Deserialize, Debug)] -pub struct AFLppCmpLogObserver<'a, S> -where - S: UsesInput + HasMetadata, -{ +pub struct AFLppCmpLogObserver<'a, S> { cmp_map: OwnedRefMut<'a, AFLppCmpLogMap>, size: Option>, name: Cow<'static, str>, @@ -80,7 +77,7 @@ where impl<'a, S> CmpObserver<'a, AFLppCmpLogMap, S, AFLppCmpValuesMetadata> for AFLppCmpLogObserver<'a, S> where - S: UsesInput + Debug + HasMetadata, + S: UsesInput + HasMetadata, { /// Get the number of usable cmps (all by default) fn usable_count(&self) -> usize { @@ -142,7 +139,7 @@ where impl<'a, S> Observer for AFLppCmpLogObserver<'a, S> where - S: UsesInput + Debug + HasMetadata, + S: UsesInput + HasMetadata, { fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> { #[cfg(feature = "cmplog_extended_instrumentation")] @@ -176,19 +173,13 @@ where } } -impl<'a, S> Named for AFLppCmpLogObserver<'a, S> -where - S: UsesInput + HasMetadata, -{ +impl<'a, S> Named for AFLppCmpLogObserver<'a, S> { fn name(&self) -> &Cow<'static, str> { &self.name } } -impl<'a, S> AFLppCmpLogObserver<'a, S> -where - S: UsesInput + HasMetadata, -{ +impl<'a, S> AFLppCmpLogObserver<'a, S> { /// Creates a new [`AFLppCmpLogObserver`] with the given name and map. #[must_use] pub fn new( diff --git a/libafl_targets/src/cmps/stages/aflpptracing.rs b/libafl_targets/src/cmps/stages/aflpptracing.rs index 3f9f5642a4..b6f78be0a8 100644 --- a/libafl_targets/src/cmps/stages/aflpptracing.rs +++ b/libafl_targets/src/cmps/stages/aflpptracing.rs @@ -1,7 +1,4 @@ -use alloc::{ - borrow::Cow, - string::{String, ToString}, -}; +use alloc::borrow::Cow; use core::marker::PhantomData; #[cfg(feature = "introspection")] @@ -14,34 +11,43 @@ use libafl::{ state::{HasCorpus, HasCurrentTestcase, HasExecutions, UsesState}, Error, HasMetadata, HasNamedMetadata, }; -use libafl_bolts::{tuples::MatchName, Named}; +use libafl_bolts::{ + tuples::{MatchNameRef, Reference, Referenceable}, + Named, +}; use crate::cmps::observers::AFLppCmpLogObserver; /// Trace with tainted input #[derive(Clone, Debug)] -pub struct AFLppCmplogTracingStage { +pub struct AFLppCmplogTracingStage<'a, EM, TE, Z> +where + TE: UsesState, +{ tracer_executor: TE, - cmplog_observer_name: Option, + cmplog_observer_ref: Option>>, #[allow(clippy::type_complexity)] phantom: PhantomData<(EM, TE, Z)>, } -impl UsesState for AFLppCmplogTracingStage +impl UsesState for AFLppCmplogTracingStage<'_, EM, TE, Z> where TE: UsesState, { type State = TE::State; } -impl Named for AFLppCmplogTracingStage { +impl Named for AFLppCmplogTracingStage<'_, EM, TE, Z> +where + TE: UsesState, +{ fn name(&self) -> &Cow<'static, str> { static NAME: Cow<'static, str> = Cow::Borrowed("AFLppCmplogTracingStage"); &NAME } } -impl Stage for AFLppCmplogTracingStage +impl Stage for AFLppCmplogTracingStage<'_, EM, TE, Z> where E: UsesState, TE: Executor + HasObservers, @@ -61,12 +67,8 @@ where // First run with the un-mutated input let unmutated_input = state.current_input_cloned()?; - if let Some(name) = &self.cmplog_observer_name { - if let Some(ob) = self - .tracer_executor - .observers_mut() - .match_name_mut::>(name) - { + if let Some(obs_ref) = &self.cmplog_observer_ref { + if let Some(ob) = self.tracer_executor.observers_mut().get_mut(obs_ref) { // This is not the original input, // Set it to false ob.set_original(true); @@ -95,12 +97,8 @@ where None => return Err(Error::unknown("No metadata found")), }; - if let Some(name) = &self.cmplog_observer_name { - if let Some(ob) = self - .tracer_executor - .observers_mut() - .match_name_mut::>(name) - { + if let Some(obs_ref) = &self.cmplog_observer_ref { + if let Some(ob) = self.tracer_executor.observers_mut().get_mut(obs_ref) { // This is not the original input, // Set it to false ob.set_original(false); @@ -137,20 +135,26 @@ where } } -impl AFLppCmplogTracingStage { +impl<'a, EM, TE, Z> AFLppCmplogTracingStage<'a, EM, TE, Z> +where + TE: UsesState, +{ /// Creates a new default stage pub fn new(tracer_executor: TE) -> Self { Self { - cmplog_observer_name: None, + cmplog_observer_ref: None, tracer_executor, phantom: PhantomData, } } /// With cmplog observer - pub fn with_cmplog_observer_name(tracer_executor: TE, name: &'static str) -> Self { + pub fn with_cmplog_observer( + tracer_executor: TE, + obs: &AFLppCmpLogObserver<'a, TE::State>, + ) -> Self { Self { - cmplog_observer_name: Some(name.to_string()), + cmplog_observer_ref: Some(obs.type_ref()), tracer_executor, phantom: PhantomData, } From 20df38406e52e3d9769d39963d838fe43a14d729 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 26 Apr 2024 03:08:48 +0200 Subject: [PATCH 24/31] I am tired --- libafl_sugar/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libafl_sugar/Cargo.toml b/libafl_sugar/Cargo.toml index 8c14f7fece..f11446fc50 100644 --- a/libafl_sugar/Cargo.toml +++ b/libafl_sugar/Cargo.toml @@ -17,7 +17,7 @@ all-features = true [features] python = ["pyo3", "libafl_qemu/python", "pyo3-build-config"] -default = ["libafl/adaptive_serialization"] +default = [] # for libafl_qemu # The following architecture features are mutually exclusive. @@ -33,7 +33,7 @@ hexagon = ["libafl_qemu/hexagon"] # build qemu for hexagon pyo3-build-config = { version = "0.18", optional = true } [dependencies] -libafl = { path = "../libafl", version = "0.12.0" } +libafl = { path = "../libafl", version = "0.12.0", features = ["adaptive_serialization"] } libafl_bolts = { path = "../libafl_bolts", version = "0.12.0" } libafl_targets = { path = "../libafl_targets", version = "0.12.0" } From 0eb7c18f8ed203234f8f3cfa91e933420d85376e Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 26 Apr 2024 03:21:06 +0200 Subject: [PATCH 25/31] new not with --- libafl/src/stages/tmin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libafl/src/stages/tmin.rs b/libafl/src/stages/tmin.rs index 5ca77b6057..9f56d63443 100644 --- a/libafl/src/stages/tmin.rs +++ b/libafl/src/stages/tmin.rs @@ -410,7 +410,7 @@ where C: AsRef + Referenceable, { /// Creates a new map equality feedback for the given observer - pub fn with_observer(obs: &C) -> Self { + pub fn new(obs: &C) -> Self { Self { map_ref: obs.type_ref(), phantom: PhantomData, From fe063b863844c5f7b20a7b1702a4dbed606783b9 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 26 Apr 2024 03:40:40 +0200 Subject: [PATCH 26/31] fixup: aflpp tracing was not actually constructable --- fuzzers/fuzzbench_forkserver_cmplog/src/main.rs | 5 +++-- libafl_targets/src/cmps/stages/aflpptracing.rs | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs b/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs index b3f5ed6205..146a964255 100644 --- a/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs +++ b/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs @@ -37,7 +37,7 @@ use libafl_bolts::{ ownedref::OwnedRefMut, rands::StdRand, shmem::{ShMem, ShMemProvider, UnixShMemProvider}, - tuples::{tuple_list, Merge}, + tuples::{tuple_list, Merge, Referenceable}, AsSliceMut, }; use libafl_targets::{ @@ -355,6 +355,7 @@ fn fuzz( let cmpmap = unsafe { OwnedRefMut::from_shmem(&mut cmplog_shmem) }; let cmplog_observer = AFLppCmpLogObserver::new("cmplog", cmpmap, true); + let cmplog_ref = cmplog_observer.type_ref(); let cmplog_executor = ForkserverExecutor::builder() .program(exec) @@ -367,7 +368,7 @@ fn fuzz( .build(tuple_list!(cmplog_observer)) .unwrap(); - let tracing = AFLppCmplogTracingStage::with_cmplog_observer_name(cmplog_executor, "cmplog"); + let tracing = AFLppCmplogTracingStage::with_cmplog_observer(cmplog_executor, cmplog_ref); // Setup a randomic Input2State stage let rq = MultiMutationalStage::new(AFLppRedQueen::with_cmplog_options(true, true)); diff --git a/libafl_targets/src/cmps/stages/aflpptracing.rs b/libafl_targets/src/cmps/stages/aflpptracing.rs index b6f78be0a8..6cd2ded66f 100644 --- a/libafl_targets/src/cmps/stages/aflpptracing.rs +++ b/libafl_targets/src/cmps/stages/aflpptracing.rs @@ -12,7 +12,7 @@ use libafl::{ Error, HasMetadata, HasNamedMetadata, }; use libafl_bolts::{ - tuples::{MatchNameRef, Reference, Referenceable}, + tuples::{MatchNameRef, Reference}, Named, }; @@ -151,10 +151,10 @@ where /// With cmplog observer pub fn with_cmplog_observer( tracer_executor: TE, - obs: &AFLppCmpLogObserver<'a, TE::State>, + obs_ref: Reference>, ) -> Self { Self { - cmplog_observer_ref: Some(obs.type_ref()), + cmplog_observer_ref: Some(obs_ref), tracer_executor, phantom: PhantomData, } From 8a3b236476d92c1d6517668240ec449a08ce5e0c Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 26 Apr 2024 04:00:10 +0200 Subject: [PATCH 27/31] fix tmin --- libafl/src/stages/tmin.rs | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/libafl/src/stages/tmin.rs b/libafl/src/stages/tmin.rs index 9f56d63443..409cd76284 100644 --- a/libafl/src/stages/tmin.rs +++ b/libafl/src/stages/tmin.rs @@ -248,6 +248,14 @@ where IP: MutatedTransformPost + Clone, I: MutatedTransform + Clone, { + fn restart_progress_should_run(&mut self, state: &mut Self::State) -> Result { + self.restart_helper.restart_progress_should_run(state) + } + + fn clear_restart_progress(&mut self, state: &mut Self::State) -> Result<(), Error> { + self.restart_helper.clear_restart_progress(state) + } + fn perform( &mut self, fuzzer: &mut Z, @@ -262,14 +270,6 @@ where Ok(()) } - - fn restart_progress_should_run(&mut self, state: &mut Self::State) -> Result { - self.restart_helper.restart_progress_should_run(state) - } - - fn clear_restart_progress(&mut self, state: &mut Self::State) -> Result<(), Error> { - self.restart_helper.clear_restart_progress(state) - } } impl FeedbackFactory @@ -426,13 +426,18 @@ impl HasObserverReference for MapEqualityFactory { } } -impl FeedbackFactory, S, C> for MapEqualityFactory +impl FeedbackFactory, S, OT> + for MapEqualityFactory where M: MapObserver, C: AsRef + Referenceable, + OT: ObserversTuple, S: State + Debug, { - fn create_feedback(&self, obs: &C) -> MapEqualityFeedback { + fn create_feedback(&self, observers: &OT) -> MapEqualityFeedback { + let obs = observers + .get(self.observer_ref()) + .expect("Should have been provided valid observer name."); MapEqualityFeedback { name: Cow::from("MapEq"), map_ref: obs.type_ref(), From 095f8e34e7dd4dc26967577d5291c1227a8e95b9 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 26 Apr 2024 15:45:24 +0200 Subject: [PATCH 28/31] reduce complexity of map feedback now that we do not need to constrain --- libafl/src/feedbacks/map.rs | 37 +++++++++---------- libafl/src/stages/calibrate.rs | 8 ++-- .../libafl_libfuzzer_runtime/src/feedbacks.rs | 2 +- 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/libafl/src/feedbacks/map.rs b/libafl/src/feedbacks/map.rs index c7bf52cee2..ae348d736c 100644 --- a/libafl/src/feedbacks/map.rs +++ b/libafl/src/feedbacks/map.rs @@ -23,29 +23,28 @@ use crate::{ feedbacks::{Feedback, HasObserverReference}, inputs::UsesInput, monitors::{AggregatorOps, UserStats, UserStatsValue}, - observers::{CanTrack, MapObserver, ObserversTuple}, + observers::{CanTrack, MapObserver, Observer, ObserversTuple}, state::State, Error, HasMetadata, HasNamedMetadata, }; /// A [`MapFeedback`] that implements the AFL algorithm using an [`OrReducer`] combining the bits for the history map and the bit from (`HitcountsMapObserver`)[`crate::observers::HitcountsMapObserver`]. -pub type AflMapFeedback = MapFeedback; +pub type AflMapFeedback = MapFeedback; /// A [`MapFeedback`] that strives to maximize the map contents. -pub type MaxMapFeedback = MapFeedback; +pub type MaxMapFeedback = MapFeedback; /// A [`MapFeedback`] that strives to minimize the map contents. -pub type MinMapFeedback = MapFeedback; +pub type MinMapFeedback = MapFeedback; /// A [`MapFeedback`] that always returns `true` for `is_interesting`. Useful for tracing all executions. -pub type AlwaysInterestingMapFeedback = MapFeedback; +pub type AlwaysInterestingMapFeedback = MapFeedback; /// A [`MapFeedback`] that strives to maximize the map contents, /// but only, if a value is larger than `pow2` of the previous. -pub type MaxMapPow2Feedback = MapFeedback; +pub type MaxMapPow2Feedback = MapFeedback; /// A [`MapFeedback`] that strives to maximize the map contents, /// but only, if a value is larger than `pow2` of the previous. -pub type MaxMapOneOrFilledFeedback = - MapFeedback; +pub type MaxMapOneOrFilledFeedback = MapFeedback; /// A `Reducer` function is used to aggregate values for the novelty search pub trait Reducer: 'static @@ -383,7 +382,7 @@ where /// The most common AFL-like feedback type #[derive(Clone, Debug)] -pub struct MapFeedback { +pub struct MapFeedback { /// New indexes observed in the last observation novelties: Option>, /// Name identifier of this instance @@ -393,17 +392,17 @@ pub struct MapFeedback { /// Name of the feedback as shown in the `UserStats` stats_name: Cow<'static, str>, /// Phantom Data of Reducer - phantom: PhantomData<(C, N, O, R, S, T)>, + phantom: PhantomData<(C, N, O, R, T)>, } -impl Feedback for MapFeedback +impl Feedback for MapFeedback where N: IsNovel, O: MapObserver + for<'it> AsIter<'it, Item = T>, R: Reducer, S: State + HasNamedMetadata, T: Default + Copy + Serialize + for<'de> Deserialize<'de> + PartialEq + Debug + 'static, - C: CanTrack + AsRef + Named, + C: CanTrack + AsRef + Observer, { fn init_state(&mut self, state: &mut S) -> Result<(), Error> { // Initialize `MapFeedbackMetadata` with an empty vector and add it to the state. @@ -538,12 +537,12 @@ where /// Specialize for the common coverage map size, maximization of u8s #[rustversion::nightly] -impl Feedback for MapFeedback +impl Feedback for MapFeedback where O: MapObserver + AsSlice, for<'it> O: AsIter<'it, Item = u8>, S: State + HasNamedMetadata, - C: CanTrack + AsRef + Named, + C: CanTrack + AsRef + Observer, { #[allow(clippy::wrong_self_convention)] #[allow(clippy::needless_range_loop)] @@ -655,14 +654,14 @@ where } } -impl Named for MapFeedback { +impl Named for MapFeedback { #[inline] fn name(&self) -> &Cow<'static, str> { &self.name } } -impl HasObserverReference for MapFeedback +impl HasObserverReference for MapFeedback where O: Named, C: AsRef, @@ -684,14 +683,13 @@ fn create_stats_name(name: &Cow<'static, str>) -> Cow<'static, str> { } } -impl MapFeedback +impl MapFeedback where T: PartialEq + Default + Copy + 'static + Serialize + DeserializeOwned + Debug, R: Reducer, O: MapObserver, for<'it> O: AsIter<'it, Item = T>, N: IsNovel, - S: UsesInput + HasNamedMetadata, C: CanTrack + AsRef + Named, { /// Create new `MapFeedback` @@ -724,7 +722,7 @@ where #[allow(clippy::wrong_self_convention)] #[allow(clippy::needless_range_loop)] #[allow(clippy::trivially_copy_pass_by_ref)] - fn is_interesting_default( + fn is_interesting_default( &mut self, state: &mut S, _manager: &mut EM, @@ -735,6 +733,7 @@ where where EM: EventFirer, OT: ObserversTuple, + S: UsesInput + HasNamedMetadata, { let mut interesting = false; // TODO Replace with match_name_type when stable diff --git a/libafl/src/stages/calibrate.rs b/libafl/src/stages/calibrate.rs index 5077a908bc..1bed1f577d 100644 --- a/libafl/src/stages/calibrate.rs +++ b/libafl/src/stages/calibrate.rs @@ -14,6 +14,7 @@ use crate::{ executors::{Executor, ExitKind, HasObservers}, feedbacks::{map::MapFeedbackMetadata, HasObserverReference}, fuzzer::Evaluator, + inputs::UsesInput, monitors::{AggregatorOps, UserStats, UserStatsValue}, observers::{MapObserver, ObserversTuple}, schedulers::powersched::SchedulerMetadata, @@ -330,17 +331,16 @@ where impl CalibrationStage where O: MapObserver, + for<'it> O: AsIter<'it, Item = O::Entry>, C: AsRef, OT: ObserversTuple, - S: HasCorpus + HasMetadata + HasNamedMetadata, + S: UsesInput + HasNamedMetadata, { /// Create a new [`CalibrationStage`]. #[must_use] pub fn new(map_feedback: &F) -> Self where F: HasObserverReference + Named, - for<'it> O: AsIter<'it, Item = O::Entry>, - C: AsRef, { Self { map_observer_ref: map_feedback.observer_ref().clone(), @@ -357,8 +357,6 @@ where pub fn ignore_stability(map_feedback: &F) -> Self where F: HasObserverReference + Named, - for<'it> O: AsIter<'it, Item = O::Entry>, - C: AsRef, { Self { map_observer_ref: map_feedback.observer_ref().clone(), diff --git a/libafl_libfuzzer/libafl_libfuzzer_runtime/src/feedbacks.rs b/libafl_libfuzzer/libafl_libfuzzer_runtime/src/feedbacks.rs index 4b4f3ad026..72ad044443 100644 --- a/libafl_libfuzzer/libafl_libfuzzer_runtime/src/feedbacks.rs +++ b/libafl_libfuzzer/libafl_libfuzzer_runtime/src/feedbacks.rs @@ -174,4 +174,4 @@ where } } -pub type ShrinkMapFeedback = MinMapFeedback, S, usize>; +pub type ShrinkMapFeedback = MinMapFeedback, usize>; From 06b74a2df31fd082c0179e07f5b0021b09e005b4 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 26 Apr 2024 16:12:57 +0200 Subject: [PATCH 29/31] frida fixes --- fuzzers/frida_executable_libpng/src/fuzzer.rs | 39 +++++++++++------- fuzzers/frida_gdiplus/src/fuzzer.rs | 39 +++++++++++------- fuzzers/frida_libpng/src/fuzzer.rs | 41 +++++++++++-------- 3 files changed, 73 insertions(+), 46 deletions(-) diff --git a/fuzzers/frida_executable_libpng/src/fuzzer.rs b/fuzzers/frida_executable_libpng/src/fuzzer.rs index 796f52b408..2d945b34f9 100644 --- a/fuzzers/frida_executable_libpng/src/fuzzer.rs +++ b/fuzzers/frida_executable_libpng/src/fuzzer.rs @@ -35,7 +35,7 @@ use libafl_bolts::{ #[cfg(unix)] use libafl_frida::asan::{ asan_rt::AsanRuntime, - errors::{AsanErrorsFeedback, AsanErrorsObserver, ASAN_ERRORS}, + errors::{AsanErrorsFeedback, AsanErrorsObserver}, }; use libafl_frida::{ cmplog_rt::CmpLogRuntime, @@ -123,6 +123,8 @@ unsafe fn fuzz( // Create an observation channel to keep track of the execution time let time_observer = TimeObserver::new("time"); + #[cfg(unix)] + let asan_observer = AsanErrorsObserver::from_static_asan_errors(); // Feedback to rate the interestingness of an input // This one is composed by two Feedbacks in OR @@ -139,7 +141,10 @@ unsafe fn fuzz( CrashFeedback::new(), TimeoutFeedback::new(), // true enables the AsanErrorFeedback - feedback_and_fast!(ConstFeedback::from(true), AsanErrorsFeedback::new()) + feedback_and_fast!( + ConstFeedback::from(true), + AsanErrorsFeedback::new(&asan_observer) + ) ); #[cfg(windows)] let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); @@ -185,9 +190,7 @@ unsafe fn fuzz( let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); #[cfg(unix)] - let observers = tuple_list!(edges_observer, time_observer, unsafe { - AsanErrorsObserver::from_static_asan_errors() - }); + let observers = tuple_list!(edges_observer, time_observer, asan_observer); #[cfg(windows)] let observers = tuple_list!(edges_observer, time_observer); @@ -240,6 +243,8 @@ unsafe fn fuzz( // Create an observation channel to keep track of the execution time let time_observer = TimeObserver::new("time"); + #[cfg(unix)] + let asan_observer = AsanErrorsObserver::from_static_asan_errors(); // Feedback to rate the interestingness of an input // This one is composed by two Feedbacks in OR @@ -254,7 +259,10 @@ unsafe fn fuzz( let mut objective = feedback_or_fast!( CrashFeedback::new(), TimeoutFeedback::new(), - feedback_and_fast!(ConstFeedback::from(false), AsanErrorsFeedback::new()) + feedback_and_fast!( + ConstFeedback::from(false), + AsanErrorsFeedback::new(&asan_observer) + ) ); #[cfg(windows)] let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); @@ -300,11 +308,9 @@ unsafe fn fuzz( let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); #[cfg(unix)] - let observers = tuple_list!(edges_observer, time_observer, unsafe { - AsanErrorsObserver::from_static_asan_errors() - }); + let observers = tuple_list!(edges_observer, time_observer, asan_observer); #[cfg(windows)] - let observers = tuple_list!(edges_observer, time_observer,); + let observers = tuple_list!(edges_observer, time_observer); // Create the executor for an in-process function with just one observer for edge coverage let mut executor = FridaInProcessExecutor::new( @@ -370,6 +376,8 @@ unsafe fn fuzz( // Create an observation channel to keep track of the execution time let time_observer = TimeObserver::new("time"); + #[cfg(unix)] + let asan_observer = AsanErrorsObserver::from_static_asan_errors(); // Feedback to rate the interestingness of an input // This one is composed by two Feedbacks in OR @@ -384,7 +392,10 @@ unsafe fn fuzz( let mut objective = feedback_or_fast!( CrashFeedback::new(), TimeoutFeedback::new(), - feedback_and_fast!(ConstFeedback::from(false), AsanErrorsFeedback::new()) + feedback_and_fast!( + ConstFeedback::from(false), + AsanErrorsFeedback::new(&asan_observer) + ) ); #[cfg(windows)] let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); @@ -430,11 +441,9 @@ unsafe fn fuzz( let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); #[cfg(unix)] - let observers = tuple_list!(edges_observer, time_observer, unsafe { - AsanErrorsObserver::from_static_asan_errors() - }); + let observers = tuple_list!(edges_observer, time_observer, asan_observer); #[cfg(windows)] - let observers = tuple_list!(edges_observer, time_observer,); + let observers = tuple_list!(edges_observer, time_observer); // Create the executor for an in-process function with just one observer for edge coverage let mut executor = FridaInProcessExecutor::new( diff --git a/fuzzers/frida_gdiplus/src/fuzzer.rs b/fuzzers/frida_gdiplus/src/fuzzer.rs index 7c8e6b9d8e..c633cc0964 100644 --- a/fuzzers/frida_gdiplus/src/fuzzer.rs +++ b/fuzzers/frida_gdiplus/src/fuzzer.rs @@ -99,7 +99,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { let coverage = CoverageRuntime::new(); #[cfg(unix)] - let asan = AsanRuntime::new(&options); + let asan = AsanRuntime::new(options); #[cfg(unix)] let mut frida_helper = @@ -119,6 +119,9 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { // Create an observation channel to keep track of the execution time let time_observer = TimeObserver::new("time"); + #[cfg(unix)] + let asan_observer = AsanErrorsObserver::from_static_asan_errors(); + // Feedback to rate the interestingness of an input // This one is composed by two Feedbacks in OR let mut feedback = feedback_or!( @@ -134,7 +137,10 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { CrashFeedback::new(), TimeoutFeedback::new(), // true enables the AsanErrorFeedback - feedback_and_fast!(ConstFeedback::from(true), AsanErrorsFeedback::new()) + feedback_and_fast!( + ConstFeedback::from(true), + AsanErrorsFeedback::new(&asan_observer) + ) ); #[cfg(windows)] let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); @@ -179,9 +185,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); #[cfg(unix)] - let observers = tuple_list!(edges_observer, time_observer, unsafe { - AsanErrorsObserver::from_static_asan_errors() - }); + let observers = tuple_list!(edges_observer, time_observer, asan_observer); #[cfg(windows)] let observers = tuple_list!(edges_observer, time_observer); @@ -234,6 +238,8 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { // Create an observation channel to keep track of the execution time let time_observer = TimeObserver::new("time"); + #[cfg(unix)] + let asan_observer = AsanErrorsObserver::from_static_asan_errors(); // Feedback to rate the interestingness of an input // This one is composed by two Feedbacks in OR @@ -248,7 +254,10 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { let mut objective = feedback_or_fast!( CrashFeedback::new(), TimeoutFeedback::new(), - feedback_and_fast!(ConstFeedback::from(false), AsanErrorsFeedback::new()) + feedback_and_fast!( + ConstFeedback::from(false), + AsanErrorsFeedback::new(&asan_observer) + ) ); #[cfg(windows)] let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); @@ -294,9 +303,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); #[cfg(unix)] - let observers = tuple_list!(edges_observer, time_observer, unsafe { - AsanErrorsObserver::from_static_asan_errors() - }); + let observers = tuple_list!(edges_observer, time_observer, asan_observer); #[cfg(windows)] let observers = tuple_list!(edges_observer, time_observer,); @@ -366,6 +373,9 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { // Create an observation channel to keep track of the execution time let time_observer = TimeObserver::new("time"); + #[cfg(unix)] + let asan_observer = AsanErrorsObserver::from_static_asan_errors(); + // Feedback to rate the interestingness of an input // This one is composed by two Feedbacks in OR let mut feedback = feedback_or!( @@ -379,7 +389,10 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { let mut objective = feedback_or_fast!( CrashFeedback::new(), TimeoutFeedback::new(), - feedback_and_fast!(ConstFeedback::from(false), AsanErrorsFeedback::new()) + feedback_and_fast!( + ConstFeedback::from(false), + AsanErrorsFeedback::new(&asan_observer) + ) ); #[cfg(windows)] let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); @@ -425,11 +438,9 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); #[cfg(unix)] - let observers = tuple_list!(edges_observer, time_observer, unsafe { - AsanErrorsObserver::from_static_asan_errors() - }); + let observers = tuple_list!(edges_observer, time_observer, asan_observer); #[cfg(windows)] - let observers = tuple_list!(edges_observer, time_observer,); + let observers = tuple_list!(edges_observer, time_observer); // Create the executor for an in-process function with just one observer for edge coverage let mut executor = FridaInProcessExecutor::new( diff --git a/fuzzers/frida_libpng/src/fuzzer.rs b/fuzzers/frida_libpng/src/fuzzer.rs index 4886087170..2451c75a81 100644 --- a/fuzzers/frida_libpng/src/fuzzer.rs +++ b/fuzzers/frida_libpng/src/fuzzer.rs @@ -35,7 +35,7 @@ use libafl_bolts::{ #[cfg(unix)] use libafl_frida::asan::{ asan_rt::AsanRuntime, - errors::{AsanErrorsFeedback, AsanErrorsObserver, ASAN_ERRORS}, + errors::{AsanErrorsFeedback, AsanErrorsObserver}, }; use libafl_frida::{ cmplog_rt::CmpLogRuntime, @@ -113,6 +113,8 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { // Create an observation channel to keep track of the execution time let time_observer = TimeObserver::new("time"); + #[cfg(unix)] + let asan_observer = AsanErrorsObserver::from_static_asan_errors(); // Feedback to rate the interestingness of an input // This one is composed by two Feedbacks in OR @@ -129,7 +131,10 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { CrashFeedback::new(), TimeoutFeedback::new(), // true enables the AsanErrorFeedback - feedback_and_fast!(ConstFeedback::from(true), AsanErrorsFeedback::new()) + feedback_and_fast!( + ConstFeedback::from(true), + AsanErrorsFeedback::new(&asan_observer) + ) ); #[cfg(windows)] let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); @@ -175,9 +180,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); #[cfg(unix)] - let observers = tuple_list!(edges_observer, time_observer, unsafe { - AsanErrorsObserver::from_static_asan_errors() - }); + let observers = tuple_list!(edges_observer, time_observer, asan_observer); #[cfg(windows)] let observers = tuple_list!(edges_observer, time_observer); @@ -231,6 +234,8 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { // Create an observation channel to keep track of the execution time let time_observer = TimeObserver::new("time"); + #[cfg(unix)] + let asan_observer = AsanErrorsObserver::from_static_asan_errors(); // Feedback to rate the interestingness of an input // This one is composed by two Feedbacks in OR @@ -245,7 +250,10 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { let mut objective = feedback_or_fast!( CrashFeedback::new(), TimeoutFeedback::new(), - feedback_and_fast!(ConstFeedback::from(false), AsanErrorsFeedback::new()) + feedback_and_fast!( + ConstFeedback::from(false), + AsanErrorsFeedback::new(&asan_observer) + ) ); #[cfg(windows)] let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); @@ -291,11 +299,9 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); #[cfg(unix)] - let observers = tuple_list!(edges_observer, time_observer, unsafe { - AsanErrorsObserver::from_static_asan_errors() - }); + let observers = tuple_list!(edges_observer, time_observer, asan_observer); #[cfg(windows)] - let observers = tuple_list!(edges_observer, time_observer,); + let observers = tuple_list!(edges_observer, time_observer); // Create the executor for an in-process function with just one observer for edge coverage let mut executor = FridaInProcessExecutor::new( @@ -361,6 +367,8 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { // Create an observation channel to keep track of the execution time let time_observer = TimeObserver::new("time"); + #[cfg(unix)] + let asan_observer = AsanErrorsObserver::from_static_asan_errors(); // Feedback to rate the interestingness of an input // This one is composed by two Feedbacks in OR @@ -375,7 +383,10 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { let mut objective = feedback_or_fast!( CrashFeedback::new(), TimeoutFeedback::new(), - feedback_and_fast!(ConstFeedback::from(false), AsanErrorsFeedback::new()) + feedback_and_fast!( + ConstFeedback::from(false), + AsanErrorsFeedback::new(&asan_observer) + ) ); #[cfg(windows)] let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); @@ -421,13 +432,9 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); #[cfg(unix)] - let observers = tuple_list!( - edges_observer, - time_observer, - AsanErrorsObserver::from_static_asan_errors() - ); + let observers = tuple_list!(edges_observer, time_observer, asan_observer); #[cfg(windows)] - let observers = tuple_list!(edges_observer, time_observer,); + let observers = tuple_list!(edges_observer, time_observer); // Create the executor for an in-process function with just one observer for edge coverage let mut executor = FridaInProcessExecutor::new( From 46788a90b5c5dbde7cab54e3ea7536551ba7f350 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Fri, 26 Apr 2024 17:28:18 +0200 Subject: [PATCH 30/31] fix concolic --- fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs | 9 ++++----- libafl/src/stages/concolic.rs | 9 +++------ 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs b/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs index 9b795db1c8..47eecdc22c 100644 --- a/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs +++ b/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs @@ -42,8 +42,8 @@ use libafl_bolts::{ current_nanos, rands::StdRand, shmem::{ShMem, ShMemProvider, StdShMemProvider}, - tuples::tuple_list, - AsSliceMut, AsSlice, Named, + tuples::{tuple_list, Referenceable}, + AsSliceMut, AsSlice }; use libafl_targets::{ libfuzzer_initialize, libfuzzer_test_one_input, std_edges_map_observer, CmpLogObserver, @@ -207,8 +207,7 @@ fn fuzz( // The concolic observer observers the concolic shared memory map. let concolic_observer = ConcolicObserver::new("concolic", concolic_shmem.as_slice_mut()); - - let concolic_observer_name = concolic_observer.name().to_string(); + let concolic_ref = concolic_observer.type_ref(); // The order of the stages matter! let mut stages = tuple_list!( @@ -217,7 +216,7 @@ fn fuzz( TracingStage::new( MyCommandConfigurator.into_executor(tuple_list!(concolic_observer)) ), - concolic_observer_name, + concolic_ref, ), // Use the concolic trace for z3-based solving SimpleConcolicMutationalStage::default(), diff --git a/libafl/src/stages/concolic.rs b/libafl/src/stages/concolic.rs index 4367ebe208..d9d503bbd3 100644 --- a/libafl/src/stages/concolic.rs +++ b/libafl/src/stages/concolic.rs @@ -9,7 +9,7 @@ use alloc::{string::ToString, vec::Vec}; use core::marker::PhantomData; use libafl_bolts::{ - tuples::{MatchNameRef, Reference, Referenceable}, + tuples::{MatchNameRef, Reference}, Named, }; @@ -95,11 +95,8 @@ where impl<'a, EM, TE, Z> ConcolicTracingStage<'a, EM, TE, Z> { /// Creates a new default tracing stage using the given [`Executor`], observing traces from a /// [`ConcolicObserver`] with the given name. - pub fn new(inner: TracingStage, observer: &ConcolicObserver<'a>) -> Self { - Self { - inner, - obs_ref: observer.type_ref(), - } + pub fn new(inner: TracingStage, obs_ref: Reference>) -> Self { + Self { inner, obs_ref } } } From 92a4d67ece982e746c21c932d38dff65961d89c6 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Sat, 27 Apr 2024 17:07:31 +0200 Subject: [PATCH 31/31] type_ref => reference --- fuzzers/forkserver_libafl_cc/src/main.rs | 2 +- fuzzers/forkserver_simple/src/main.rs | 2 +- fuzzers/fuzzbench_forkserver_cmplog/src/main.rs | 2 +- fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs | 2 +- libafl/src/corpus/minimizer.rs | 2 +- libafl/src/events/centralized.rs | 8 ++++---- libafl/src/events/launcher.rs | 4 ++-- libafl/src/events/llmp.rs | 4 ++-- libafl/src/executors/forkserver.rs | 4 ++-- libafl/src/feedbacks/concolic.rs | 2 +- libafl/src/feedbacks/differential.rs | 4 ++-- libafl/src/feedbacks/list.rs | 2 +- libafl/src/feedbacks/map.rs | 4 ++-- libafl/src/feedbacks/mod.rs | 2 +- libafl/src/feedbacks/new_hash_feedback.rs | 2 +- libafl/src/feedbacks/stdio.rs | 4 ++-- libafl/src/schedulers/powersched.rs | 2 +- libafl/src/schedulers/weighted.rs | 2 +- libafl/src/stages/colorization.rs | 2 +- libafl/src/stages/generalization.rs | 2 +- libafl/src/stages/tmin.rs | 4 ++-- libafl_bolts/src/tuples.rs | 6 +++--- libafl_frida/src/asan/errors.rs | 2 +- libafl_qemu/src/helpers/calls.rs | 2 +- libafl_sugar/src/forkserver.rs | 2 +- libafl_sugar/src/inmemory.rs | 2 +- libafl_sugar/src/qemu.rs | 2 +- 27 files changed, 39 insertions(+), 39 deletions(-) diff --git a/fuzzers/forkserver_libafl_cc/src/main.rs b/fuzzers/forkserver_libafl_cc/src/main.rs index fb59d90cb0..350978feaa 100644 --- a/fuzzers/forkserver_libafl_cc/src/main.rs +++ b/fuzzers/forkserver_libafl_cc/src/main.rs @@ -167,7 +167,7 @@ pub fn main() { // Create the executor for the forkserver let args = opt.arguments; - let observer_ref = edges_observer.type_ref(); + let observer_ref = edges_observer.reference(); let mut tokens = Tokens::new(); let mut executor = ForkserverExecutor::builder() diff --git a/fuzzers/forkserver_simple/src/main.rs b/fuzzers/forkserver_simple/src/main.rs index b2aec6f635..922ee64fba 100644 --- a/fuzzers/forkserver_simple/src/main.rs +++ b/fuzzers/forkserver_simple/src/main.rs @@ -163,7 +163,7 @@ pub fn main() { // Create the executor for the forkserver let args = opt.arguments; - let observer_ref = edges_observer.type_ref(); + let observer_ref = edges_observer.reference(); let mut tokens = Tokens::new(); let mut executor = ForkserverExecutor::builder() diff --git a/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs b/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs index 146a964255..a382668bf9 100644 --- a/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs +++ b/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs @@ -355,7 +355,7 @@ fn fuzz( let cmpmap = unsafe { OwnedRefMut::from_shmem(&mut cmplog_shmem) }; let cmplog_observer = AFLppCmpLogObserver::new("cmplog", cmpmap, true); - let cmplog_ref = cmplog_observer.type_ref(); + let cmplog_ref = cmplog_observer.reference(); let cmplog_executor = ForkserverExecutor::builder() .program(exec) diff --git a/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs b/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs index 47eecdc22c..a0171bf0f6 100644 --- a/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs +++ b/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs @@ -207,7 +207,7 @@ fn fuzz( // The concolic observer observers the concolic shared memory map. let concolic_observer = ConcolicObserver::new("concolic", concolic_shmem.as_slice_mut()); - let concolic_ref = concolic_observer.type_ref(); + let concolic_ref = concolic_observer.reference(); // The order of the stages matter! let mut stages = tuple_list!( diff --git a/libafl/src/corpus/minimizer.rs b/libafl/src/corpus/minimizer.rs index ed8970c0b0..8793455f27 100644 --- a/libafl/src/corpus/minimizer.rs +++ b/libafl/src/corpus/minimizer.rs @@ -70,7 +70,7 @@ where /// in the future to get observed maps from an executed input. pub fn new(obs: &C) -> Self { Self { - obs_ref: obs.type_ref(), + obs_ref: obs.reference(), phantom: PhantomData, } } diff --git a/libafl/src/events/centralized.rs b/libafl/src/events/centralized.rs index e32a796875..784911c7c7 100644 --- a/libafl/src/events/centralized.rs +++ b/libafl/src/events/centralized.rs @@ -493,7 +493,7 @@ where client, #[cfg(feature = "llmp_compression")] compressor: GzipCompressor::new(COMPRESS_THRESHOLD), - time_ref: time_obs.type_ref(), + time_ref: time_obs.reference(), is_main, }) } @@ -532,7 +532,7 @@ where client, #[cfg(feature = "llmp_compression")] compressor: GzipCompressor::new(COMPRESS_THRESHOLD), - time_ref: time_obs.type_ref(), + time_ref: time_obs.reference(), is_main, }) } @@ -570,7 +570,7 @@ where client: LlmpClient::on_existing_from_env(shmem_provider, env_name)?, #[cfg(feature = "llmp_compression")] compressor: GzipCompressor::new(COMPRESS_THRESHOLD), - time_ref: time_obs.type_ref(), + time_ref: time_obs.reference(), is_main, }) } @@ -606,7 +606,7 @@ where client: LlmpClient::existing_client_from_description(shmem_provider, description)?, #[cfg(feature = "llmp_compression")] compressor: GzipCompressor::new(COMPRESS_THRESHOLD), - time_ref: time_obs.type_ref(), + time_ref: time_obs.reference(), is_main, }) } diff --git a/libafl/src/events/launcher.rs b/libafl/src/events/launcher.rs index a7d92d3f25..a0264ea7d3 100644 --- a/libafl/src/events/launcher.rs +++ b/libafl/src/events/launcher.rs @@ -640,7 +640,7 @@ where .serialize_state(self.serialize_state) .hooks(tuple_list!()); #[cfg(feature = "adaptive_serialization")] - let builder = builder.time_ref(self.time_obs.type_ref()); + let builder = builder.time_ref(self.time_obs.reference()); let (state, mgr) = builder.build().launch()?; #[cfg(not(feature = "adaptive_serialization"))] @@ -681,7 +681,7 @@ where .hooks(tuple_list!()); #[cfg(feature = "adaptive_serialization")] - let builder = builder.time_ref(self.time_obs.type_ref()); + let builder = builder.time_ref(self.time_obs.reference()); builder.build().launch()?; diff --git a/libafl/src/events/llmp.rs b/libafl/src/events/llmp.rs index 4fc92932b5..f80404f1fe 100644 --- a/libafl/src/events/llmp.rs +++ b/libafl/src/events/llmp.rs @@ -1362,7 +1362,7 @@ where .broker_port(broker_port) .configuration(configuration) .hooks(tuple_list!()) - .time_ref(time_obs.type_ref()) + .time_ref(time_obs.reference()) .build() .launch() } @@ -2095,7 +2095,7 @@ mod tests { let time = TimeObserver::new("time"); #[cfg(feature = "adaptive_serialization")] - let time_ref = time.type_ref(); + let time_ref = time.reference(); let mut corpus = InMemoryCorpus::::new(); let testcase = Testcase::new(vec![0; 4].into()); diff --git a/libafl/src/executors/forkserver.rs b/libafl/src/executors/forkserver.rs index bfae39286d..d0485437dc 100644 --- a/libafl/src/executors/forkserver.rs +++ b/libafl/src/executors/forkserver.rs @@ -640,7 +640,7 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> { asan_obs: self .asan_obs .clone() - .unwrap_or(AsanBacktraceObserver::default().type_ref()), + .unwrap_or(AsanBacktraceObserver::default().reference()), crash_exitcode: self.crash_exitcode, }) } @@ -702,7 +702,7 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> { asan_obs: self .asan_obs .clone() - .unwrap_or(AsanBacktraceObserver::default().type_ref()), + .unwrap_or(AsanBacktraceObserver::default().reference()), crash_exitcode: self.crash_exitcode, }) } diff --git a/libafl/src/feedbacks/concolic.rs b/libafl/src/feedbacks/concolic.rs index 833e73d06f..5f93e78f85 100644 --- a/libafl/src/feedbacks/concolic.rs +++ b/libafl/src/feedbacks/concolic.rs @@ -38,7 +38,7 @@ impl<'map, S> ConcolicFeedback<'map, S> { #[must_use] pub fn from_observer(observer: &ConcolicObserver<'map>) -> Self { Self { - obs_ref: observer.type_ref(), + obs_ref: observer.reference(), phantom: PhantomData, } } diff --git a/libafl/src/feedbacks/differential.rs b/libafl/src/feedbacks/differential.rs index 4770c3ebc9..1f559833f3 100644 --- a/libafl/src/feedbacks/differential.rs +++ b/libafl/src/feedbacks/differential.rs @@ -74,8 +74,8 @@ where { /// Create a new [`DiffFeedback`] using two observers and a test function. pub fn new(name: &'static str, o1: &O1, o2: &O2, compare_fn: F) -> Result { - let o1_ref = o1.type_ref(); - let o2_ref = o2.type_ref(); + let o1_ref = o1.reference(); + let o2_ref = o2.reference(); if o1_ref.name() == o2_ref.name() { Err(Error::illegal_argument(format!( "DiffFeedback: observer names must be different (both were {})", diff --git a/libafl/src/feedbacks/list.rs b/libafl/src/feedbacks/list.rs index b77124f8fd..b4977a9671 100644 --- a/libafl/src/feedbacks/list.rs +++ b/libafl/src/feedbacks/list.rs @@ -163,7 +163,7 @@ where #[must_use] pub fn new(observer: &ListObserver) -> Self { Self { - obs_ref: observer.type_ref(), + obs_ref: observer.reference(), novelty: HashSet::::new(), } } diff --git a/libafl/src/feedbacks/map.rs b/libafl/src/feedbacks/map.rs index ae348d736c..98d9af8d1f 100644 --- a/libafl/src/feedbacks/map.rs +++ b/libafl/src/feedbacks/map.rs @@ -698,7 +698,7 @@ where Self { novelties: if C::NOVELTIES { Some(vec![]) } else { None }, name: map_observer.name().clone(), - map_ref: map_observer.type_ref(), + map_ref: map_observer.reference(), stats_name: create_stats_name(map_observer.name()), phantom: PhantomData, } @@ -712,7 +712,7 @@ where let name = Cow::from(name); Self { novelties: if C::NOVELTIES { Some(vec![]) } else { None }, - map_ref: map_observer.type_ref(), + map_ref: map_observer.reference(), stats_name: create_stats_name(&name), name, phantom: PhantomData, diff --git a/libafl/src/feedbacks/mod.rs b/libafl/src/feedbacks/mod.rs index 16a5da5700..d68ba14438 100644 --- a/libafl/src/feedbacks/mod.rs +++ b/libafl/src/feedbacks/mod.rs @@ -995,7 +995,7 @@ impl TimeFeedback { #[must_use] pub fn new(observer: &TimeObserver) -> Self { Self { - obs_ref: observer.type_ref(), + obs_ref: observer.reference(), } } } diff --git a/libafl/src/feedbacks/new_hash_feedback.rs b/libafl/src/feedbacks/new_hash_feedback.rs index 65a60f12e4..61065a0e51 100644 --- a/libafl/src/feedbacks/new_hash_feedback.rs +++ b/libafl/src/feedbacks/new_hash_feedback.rs @@ -176,7 +176,7 @@ where pub fn with_capacity(observer: &O, capacity: usize) -> Self { Self { name: Cow::from(NEWHASHFEEDBACK_PREFIX.to_string() + observer.name()), - o_ref: observer.type_ref(), + o_ref: observer.reference(), capacity, phantom: PhantomData, } diff --git a/libafl/src/feedbacks/stdio.rs b/libafl/src/feedbacks/stdio.rs index f073dd5696..719acf706e 100644 --- a/libafl/src/feedbacks/stdio.rs +++ b/libafl/src/feedbacks/stdio.rs @@ -104,7 +104,7 @@ impl StdOutToMetadataFeedback { #[must_use] pub fn new(observer: &StdOutObserver) -> Self { Self { - o_ref: observer.type_ref(), + o_ref: observer.reference(), } } } @@ -194,7 +194,7 @@ impl StdErrToMetadataFeedback { #[must_use] pub fn new(observer: &StdErrObserver) -> Self { Self { - o_ref: observer.type_ref(), + o_ref: observer.reference(), } } } diff --git a/libafl/src/schedulers/powersched.rs b/libafl/src/schedulers/powersched.rs index 5d84e2713f..f0117165a3 100644 --- a/libafl/src/schedulers/powersched.rs +++ b/libafl/src/schedulers/powersched.rs @@ -305,7 +305,7 @@ where } PowerQueueScheduler { strat, - map_observer_ref: map_observer.type_ref(), + map_observer_ref: map_observer.reference(), last_hash: 0, phantom: PhantomData, } diff --git a/libafl/src/schedulers/weighted.rs b/libafl/src/schedulers/weighted.rs index 96ed11c0f8..dff1b0791e 100644 --- a/libafl/src/schedulers/weighted.rs +++ b/libafl/src/schedulers/weighted.rs @@ -124,7 +124,7 @@ where Self { strat, - map_observer_ref: map_observer.type_ref(), + map_observer_ref: map_observer.reference(), last_hash: 0, table_invalidated: true, phantom: PhantomData, diff --git a/libafl/src/stages/colorization.rs b/libafl/src/stages/colorization.rs index cc1f2e0b0a..47252ca1be 100644 --- a/libafl/src/stages/colorization.rs +++ b/libafl/src/stages/colorization.rs @@ -301,7 +301,7 @@ where /// Creates a new [`ColorizationStage`] pub fn new(map_observer: &C) -> Self { Self { - map_observer_ref: map_observer.type_ref(), + map_observer_ref: map_observer.reference(), phantom: PhantomData, } } diff --git a/libafl/src/stages/generalization.rs b/libafl/src/stages/generalization.rs index 9cbd9df74c..813a8d7814 100644 --- a/libafl/src/stages/generalization.rs +++ b/libafl/src/stages/generalization.rs @@ -347,7 +347,7 @@ where pub fn new(map_observer: &C) -> Self { require_novelties_tracking!("GeneralizationStage", C); Self { - map_observer_ref: map_observer.type_ref(), + map_observer_ref: map_observer.reference(), phantom: PhantomData, } } diff --git a/libafl/src/stages/tmin.rs b/libafl/src/stages/tmin.rs index 409cd76284..57372e7126 100644 --- a/libafl/src/stages/tmin.rs +++ b/libafl/src/stages/tmin.rs @@ -412,7 +412,7 @@ where /// Creates a new map equality feedback for the given observer pub fn new(obs: &C) -> Self { Self { - map_ref: obs.type_ref(), + map_ref: obs.reference(), phantom: PhantomData, } } @@ -440,7 +440,7 @@ where .expect("Should have been provided valid observer name."); MapEqualityFeedback { name: Cow::from("MapEq"), - map_ref: obs.type_ref(), + map_ref: obs.reference(), orig_hash: obs.as_ref().hash_simple(), phantom: PhantomData, } diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index e3bcc901bb..7fd0b97e23 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -460,10 +460,10 @@ where #[cfg(feature = "alloc")] pub trait MatchName { /// Match for a name and return the borrowed value - #[deprecated = "Use `.type_ref` and either `.get` (fallible access) or `[]` (infallible access) instead"] + #[deprecated = "Use `.reference` and either `.get` (fallible access) or `[]` (infallible access) instead"] fn match_name(&self, name: &str) -> Option<&T>; /// Match for a name and return the mut borrowed value - #[deprecated = "Use `.type_ref` and either `.get` (fallible access) or `[]` (infallible access) instead"] + #[deprecated = "Use `.reference` and either `.get` (fallible access) or `[]` (infallible access) instead"] fn match_name_mut(&mut self, name: &str) -> Option<&mut T>; } @@ -506,7 +506,7 @@ where #[cfg(feature = "alloc")] pub trait Referenceable: Named { /// Return the `Reference ` - fn type_ref(&self) -> Reference { + fn reference(&self) -> Reference { Reference { name: Named::name(self).clone(), phantom: PhantomData, diff --git a/libafl_frida/src/asan/errors.rs b/libafl_frida/src/asan/errors.rs index a93712190e..3be1f460c5 100644 --- a/libafl_frida/src/asan/errors.rs +++ b/libafl_frida/src/asan/errors.rs @@ -716,7 +716,7 @@ impl AsanErrorsFeedback { pub fn new(obs: &AsanErrorsObserver) -> Self { Self { errors: None, - obs_ref: obs.type_ref(), + obs_ref: obs.reference(), phantom: PhantomData, } } diff --git a/libafl_qemu/src/helpers/calls.rs b/libafl_qemu/src/helpers/calls.rs index 3cd974fa21..79de7b1597 100644 --- a/libafl_qemu/src/helpers/calls.rs +++ b/libafl_qemu/src/helpers/calls.rs @@ -447,7 +447,7 @@ impl<'a> OnCrashBacktraceCollector<'a> { pub fn new(observer: &BacktraceObserver<'a>) -> Self { Self { callstack_hash: 0, - obs_ref: observer.type_ref(), + obs_ref: observer.reference(), } } diff --git a/libafl_sugar/src/forkserver.rs b/libafl_sugar/src/forkserver.rs index fd1efa9f48..ffb7616842 100644 --- a/libafl_sugar/src/forkserver.rs +++ b/libafl_sugar/src/forkserver.rs @@ -116,7 +116,7 @@ impl<'a> ForkserverBytesCoverageSugar<'a> { // Create an observation channel to keep track of the execution time let time_observer = TimeObserver::new("time"); - let time_ref = time_observer.type_ref(); + let time_ref = time_observer.reference(); let mut run_client = |state: Option<_>, mut mgr: LlmpRestartingEventManager<_, _, _>, diff --git a/libafl_sugar/src/inmemory.rs b/libafl_sugar/src/inmemory.rs index d95020c9e9..d89e77f7f2 100644 --- a/libafl_sugar/src/inmemory.rs +++ b/libafl_sugar/src/inmemory.rs @@ -140,7 +140,7 @@ where // Create an observation channel to keep track of the execution time let time_observer = TimeObserver::new("time"); - let time_ref = time_observer.type_ref(); + let time_ref = time_observer.reference(); let mut run_client = |state: Option<_>, mut mgr: LlmpRestartingEventManager<_, _, _>, diff --git a/libafl_sugar/src/qemu.rs b/libafl_sugar/src/qemu.rs index 66b2cbe5e8..56063d9622 100644 --- a/libafl_sugar/src/qemu.rs +++ b/libafl_sugar/src/qemu.rs @@ -148,7 +148,7 @@ where // Create an observation channel to keep track of the execution time let time_observer = TimeObserver::new("time"); - let time_ref = time_observer.type_ref(); + let time_ref = time_observer.reference(); let mut run_client = |state: Option<_>, mut mgr: LlmpRestartingEventManager<_, _, _>,