From 176659821a47fb0546f396e1f11ac9b317acba7f Mon Sep 17 00:00:00 2001 From: "Dongjia \"toka\" Zhang" Date: Tue, 23 Apr 2024 19:03:30 +0200 Subject: [PATCH] Add TypeRefCreator trait (#2065) * poc * ai suggestion * rename this * aaaa * fmt * simplify * delete blob * ignore * fixup? * some progress on cow-ification * some more * clippy fixes, finalise tests * whoops, missed a spot * no std compat * api change: Named now requires alloc feature * doc fix * missed a spot * additional fixes * libfuzzer fixes * fix tutorial * fix * add * aa * fix tutorial * fix * Rename * fix * aa * fmt * aa --------- Co-authored-by: Addison Crump --- .gitignore | 7 + docs/src/core_concepts/executor.md | 4 +- .../baby_fuzzer_with_forkexecutor/src/main.rs | 4 +- .../command_executor/src/main.rs | 4 +- .../forkserver_executor/src/main.rs | 4 +- .../rust_code_with_fork_executor/src/main.rs | 4 +- fuzzers/forkserver_libafl_cc/src/main.rs | 16 +- fuzzers/forkserver_simple/src/main.rs | 4 +- fuzzers/fuzzbench_fork_qemu/src/fuzzer.rs | 6 +- fuzzers/fuzzbench_forkserver/src/main.rs | 4 +- .../fuzzbench_forkserver_cmplog/src/main.rs | 4 +- .../fuzzer/src/main.rs | 7 +- fuzzers/qemu_cmin/src/fuzzer.rs | 4 +- fuzzers/tutorial/src/metadata.rs | 7 +- fuzzers/tutorial/src/mutator.rs | 7 +- libafl/src/corpus/minimizer.rs | 3 +- libafl/src/events/mod.rs | 8 +- libafl/src/executors/forkserver.rs | 12 +- libafl/src/feedbacks/concolic.rs | 8 +- libafl/src/feedbacks/differential.rs | 28 +-- libafl/src/feedbacks/list.rs | 14 +- libafl/src/feedbacks/map.rs | 57 +++--- libafl/src/feedbacks/mod.rs | 50 +++--- libafl/src/feedbacks/nautilus.rs | 7 +- libafl/src/feedbacks/new_hash_feedback.rs | 26 +-- libafl/src/feedbacks/stdio.rs | 26 +-- libafl/src/feedbacks/transferred.rs | 9 +- libafl/src/monitors/mod.rs | 12 +- libafl/src/monitors/prometheus.rs | 16 +- libafl/src/monitors/tui/mod.rs | 4 +- libafl/src/mutators/encoded_mutations.rs | 47 +++-- libafl/src/mutators/gramatron.rs | 17 +- libafl/src/mutators/grimoire.rs | 22 ++- libafl/src/mutators/mod.rs | 4 +- libafl/src/mutators/mopt_mutator.rs | 11 +- libafl/src/mutators/mutations.rs | 105 ++++++----- libafl/src/mutators/nautilus.rs | 16 +- libafl/src/mutators/scheduled.rs | 44 +++-- libafl/src/mutators/string.rs | 22 ++- libafl/src/mutators/token_mutations.rs | 22 ++- libafl/src/mutators/tuneable.rs | 8 +- libafl/src/observers/cmp.rs | 25 ++- libafl/src/observers/concolic/observer.rs | 13 +- libafl/src/observers/list.rs | 11 +- libafl/src/observers/map.rs | 169 +++++++++--------- libafl/src/observers/mod.rs | 10 +- libafl/src/observers/stacktrace.rs | 59 +++--- libafl/src/observers/stdio.rs | 24 ++- libafl/src/observers/value.rs | 17 +- libafl/src/schedulers/accounting.rs | 8 +- libafl/src/stages/calibrate.rs | 3 +- libafl/src/stages/colorization.rs | 12 +- libafl/src/stages/concolic.rs | 7 +- libafl/src/stages/generalization.rs | 6 +- libafl/src/stages/mod.rs | 15 +- libafl/src/stages/mutational.rs | 8 +- libafl/src/stages/stats.rs | 6 +- libafl/src/stages/sync.rs | 6 +- libafl/src/stages/tmin.rs | 31 +--- libafl/src/stages/tracing.rs | 11 +- libafl_bolts/src/lib.rs | 21 +-- libafl_bolts/src/llmp.rs | 2 +- libafl_bolts/src/os/unix_shmem_server.rs | 8 +- libafl_bolts/src/ownedref.rs | 10 +- libafl_bolts/src/shmem.rs | 40 ++--- libafl_bolts/src/tuples.rs | 76 +++++++- .../symcc_runtime/src/filter/coverage.rs | 2 +- libafl_frida/src/asan/errors.rs | 13 +- .../libafl_libfuzzer_runtime/src/feedbacks.rs | 11 +- .../libafl_libfuzzer_runtime/src/observers.rs | 19 +- .../src/x86_64_stub_bindings.rs | 2 +- libafl_sugar/src/forkserver.rs | 4 +- libafl_targets/src/cmps/observers/aflpp.rs | 13 +- libafl_targets/src/cmps/observers/cmplog.rs | 8 +- .../src/cmps/stages/aflpptracing.rs | 10 +- libafl_targets/src/coverage.rs | 30 ++-- libafl_targets/src/libfuzzer/mutators.rs | 15 +- libafl_targets/src/libfuzzer/observers/oom.rs | 12 +- libafl_targets/src/sancov_8bit.rs | 29 ++- libafl_tinyinst/src/executor.rs | 8 +- 80 files changed, 810 insertions(+), 648 deletions(-) diff --git a/.gitignore b/.gitignore index 4ea9818e41..c1b1522943 100644 --- a/.gitignore +++ b/.gitignore @@ -68,3 +68,10 @@ libafl_nyx/packer *.ll *.tar.gz + +# common harness names +harness +program +fuzzer +fuzzer_libpng* +forkserver_simple diff --git a/docs/src/core_concepts/executor.md b/docs/src/core_concepts/executor.md index 009dc1cab0..6f2146d3eb 100644 --- a/docs/src/core_concepts/executor.md +++ b/docs/src/core_concepts/executor.md @@ -31,7 +31,7 @@ As you can see from the forkserver example, let mut shmem = StdShMemProvider::new().unwrap().new_shmem(MAP_SIZE).unwrap(); //let the forkserver know the shmid shmem.write_to_env("__AFL_SHM_ID").unwrap(); -let mut shmem_buf = shmem.as_mut_slice(); +let mut shmem_buf = shmem.as_slice_mut(); ``` Here we make a shared memory region; `shmem`, and write this to environmental variable `__AFL_SHM_ID`. Then the instrumented binary, or the forkserver, finds this shared memory region (from the aforementioned env var) to record its coverage. On your fuzzer side, you can pass this shmem map to your `Observer` to obtain coverage feedbacks combined with any `Feedback`. @@ -59,7 +59,7 @@ let mut shmem; unsafe{ shmem = StdShMemProvider::new().unwrap().new_shmem(MAX_EDGES_NUM).unwrap(); } -let shmem_buf = shmem.as_mut_slice(); +let shmem_buf = shmem.as_slice_mut(); unsafe{ EDGES_PTR = shmem_buf.as_ptr(); } diff --git a/fuzzers/baby_fuzzer_with_forkexecutor/src/main.rs b/fuzzers/baby_fuzzer_with_forkexecutor/src/main.rs index 8a93771657..ca33d39edb 100644 --- a/fuzzers/baby_fuzzer_with_forkexecutor/src/main.rs +++ b/fuzzers/baby_fuzzer_with_forkexecutor/src/main.rs @@ -22,7 +22,7 @@ use libafl_bolts::{ rands::StdRand, shmem::{unix_shmem, ShMemProvider}, tuples::tuple_list, - AsMutSlice, AsSlice, + AsSlice, AsSliceMut, }; #[allow(clippy::similar_names)] @@ -30,7 +30,7 @@ pub fn main() { let mut shmem_provider = unix_shmem::UnixShMemProvider::new().unwrap(); let mut signals = shmem_provider.new_shmem(16).unwrap(); let signals_len = signals.as_slice().len(); - let signals_ptr = signals.as_mut_slice().as_mut_ptr(); + let signals_ptr = signals.as_slice_mut().as_mut_ptr(); let signals_set = |idx: usize| { unsafe { write(signals_ptr.add(idx), 1) }; diff --git a/fuzzers/backtrace_baby_fuzzers/command_executor/src/main.rs b/fuzzers/backtrace_baby_fuzzers/command_executor/src/main.rs index f2a894ad1b..ccda9c5690 100644 --- a/fuzzers/backtrace_baby_fuzzers/command_executor/src/main.rs +++ b/fuzzers/backtrace_baby_fuzzers/command_executor/src/main.rs @@ -29,7 +29,7 @@ use libafl_bolts::{ rands::StdRand, shmem::{unix_shmem, ShMem, ShMemId, ShMemProvider}, tuples::tuple_list, - AsMutSlice, AsSlice, + AsSlice, AsSliceMut, }; #[allow(clippy::similar_names)] @@ -39,7 +39,7 @@ pub fn main() { let shmem_id = signals.id(); // Create an observation channel using the signals map - let observer = unsafe { StdMapObserver::new("signals", signals.as_mut_slice()) }; + let observer = unsafe { StdMapObserver::new("signals", signals.as_slice_mut()) }; // Create a stacktrace observer let bt_observer = AsanBacktraceObserver::new("AsanBacktraceObserver"); diff --git a/fuzzers/backtrace_baby_fuzzers/forkserver_executor/src/main.rs b/fuzzers/backtrace_baby_fuzzers/forkserver_executor/src/main.rs index a71912c38e..670c8ccb02 100644 --- a/fuzzers/backtrace_baby_fuzzers/forkserver_executor/src/main.rs +++ b/fuzzers/backtrace_baby_fuzzers/forkserver_executor/src/main.rs @@ -25,7 +25,7 @@ use libafl_bolts::{ rands::StdRand, shmem::{ShMem, ShMemProvider}, tuples::tuple_list, - AsMutSlice, + AsSliceMut, }; #[allow(clippy::similar_names)] @@ -42,7 +42,7 @@ pub fn main() { let mut shmem = shmem_provider.new_shmem(MAP_SIZE).unwrap(); //let the forkserver know the shmid shmem.write_to_env("__AFL_SHM_ID").unwrap(); - let shmem_map = shmem.as_mut_slice(); + let shmem_map = shmem.as_slice_mut(); // Create an observation channel using the signals map let edges_observer = HitcountsMapObserver::new(ConstMapObserver::<_, MAP_SIZE>::new( diff --git a/fuzzers/backtrace_baby_fuzzers/rust_code_with_fork_executor/src/main.rs b/fuzzers/backtrace_baby_fuzzers/rust_code_with_fork_executor/src/main.rs index a83aa1359b..38b26f6c07 100644 --- a/fuzzers/backtrace_baby_fuzzers/rust_code_with_fork_executor/src/main.rs +++ b/fuzzers/backtrace_baby_fuzzers/rust_code_with_fork_executor/src/main.rs @@ -24,7 +24,7 @@ use libafl_bolts::{ rands::StdRand, shmem::{unix_shmem, ShMem, ShMemProvider}, tuples::tuple_list, - AsMutSlice, AsSlice, + AsSlice, AsSliceMut, }; #[allow(clippy::similar_names)] @@ -32,7 +32,7 @@ pub fn main() { let mut shmem_provider = unix_shmem::UnixShMemProvider::new().unwrap(); let mut signals = shmem_provider.new_shmem(16).unwrap(); let signals_len = signals.len(); - let signals_ptr = signals.as_mut_slice().as_mut_ptr(); + let signals_ptr = signals.as_slice_mut().as_mut_ptr(); let mut bt = shmem_provider.new_on_shmem::>(None).unwrap(); let signals_set = |idx: usize| { diff --git a/fuzzers/forkserver_libafl_cc/src/main.rs b/fuzzers/forkserver_libafl_cc/src/main.rs index 899da87462..25ef3c26b5 100644 --- a/fuzzers/forkserver_libafl_cc/src/main.rs +++ b/fuzzers/forkserver_libafl_cc/src/main.rs @@ -1,7 +1,7 @@ use core::time::Duration; use std::path::PathBuf; -use clap::{self, Parser}; +use clap::Parser; use libafl::{ corpus::{Corpus, InMemoryCorpus, OnDiskCorpus}, events::SimpleEventManager, @@ -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,10 +22,10 @@ use libafl_bolts::{ current_nanos, rands::StdRand, shmem::{ShMem, ShMemProvider, UnixShMemProvider}, - tuples::{tuple_list, MatchName, Merge}, - AsMutSlice, Truncate, + tuples::{tuple_list, MatchNameRef, Merge, Referenceable}, + AsSliceMut, Truncate, }; -use libafl_targets::{EDGES_MAP_PTR, EDGES_MAP_SIZE_IN_USE}; +use libafl_targets::EDGES_MAP_SIZE_IN_USE; use nix::sys::signal::Signal; /// The commandline args this fuzzer accepts @@ -98,7 +98,7 @@ pub fn main() { let mut shmem = shmem_provider.new_shmem(MAP_SIZE).unwrap(); // let the forkserver know the shmid shmem.write_to_env("__AFL_SHM_ID").unwrap(); - let shmem_buf = shmem.as_mut_slice(); + let shmem_buf = shmem.as_slice_mut(); // the next line is not needed // unsafe { EDGES_MAP_PTR = shmem_buf.as_mut_ptr() }; @@ -167,6 +167,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) @@ -183,7 +185,7 @@ pub fn main() { if let Some(dynamic_map_size) = executor.coverage_map_size() { executor .observers_mut() - .match_name_mut::>, true, false>>("shared_mem") + .match_by_ref_mut(observer_ref) .unwrap() .as_mut() .truncate(dynamic_map_size); diff --git a/fuzzers/forkserver_simple/src/main.rs b/fuzzers/forkserver_simple/src/main.rs index e1f3739d34..ff30bca52c 100644 --- a/fuzzers/forkserver_simple/src/main.rs +++ b/fuzzers/forkserver_simple/src/main.rs @@ -23,7 +23,7 @@ use libafl_bolts::{ rands::StdRand, shmem::{ShMem, ShMemProvider, UnixShMemProvider}, tuples::{tuple_list, MatchName, Merge}, - AsMutSlice, Truncate, + AsSliceMut, Truncate, }; use nix::sys::signal::Signal; @@ -98,7 +98,7 @@ pub fn main() { let mut shmem = shmem_provider.new_shmem(MAP_SIZE).unwrap(); // let the forkserver know the shmid shmem.write_to_env("__AFL_SHM_ID").unwrap(); - let shmem_buf = shmem.as_mut_slice(); + let shmem_buf = shmem.as_slice_mut(); // Create an observation channel using the signals map let edges_observer = unsafe { diff --git a/fuzzers/fuzzbench_fork_qemu/src/fuzzer.rs b/fuzzers/fuzzbench_fork_qemu/src/fuzzer.rs index f69c45c24d..4ffd6be305 100644 --- a/fuzzers/fuzzbench_fork_qemu/src/fuzzer.rs +++ b/fuzzers/fuzzbench_fork_qemu/src/fuzzer.rs @@ -43,7 +43,7 @@ use libafl_bolts::{ rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::{tuple_list, Merge}, - AsMutSlice, AsSlice, + AsSlice, AsSliceMut, }; use libafl_qemu::{ cmplog::{CmpLogMap, CmpLogObserver, QemuCmpLogChildHelper}, @@ -209,11 +209,11 @@ fn fuzz( let mut shmem_provider = StdShMemProvider::new()?; let mut edges_shmem = shmem_provider.new_shmem(EDGES_MAP_SIZE_IN_USE).unwrap(); - let edges = edges_shmem.as_mut_slice(); + let edges = edges_shmem.as_slice_mut(); unsafe { EDGES_MAP_PTR = edges.as_mut_ptr() }; let mut cmp_shmem = shmem_provider.uninit_on_shmem::().unwrap(); - let cmplog = cmp_shmem.as_mut_slice(); + let cmplog = cmp_shmem.as_slice_mut(); // Beginning of a page should be properly aligned. #[allow(clippy::cast_ptr_alignment)] diff --git a/fuzzers/fuzzbench_forkserver/src/main.rs b/fuzzers/fuzzbench_forkserver/src/main.rs index e8216e8b9d..9b74e1947b 100644 --- a/fuzzers/fuzzbench_forkserver/src/main.rs +++ b/fuzzers/fuzzbench_forkserver/src/main.rs @@ -40,7 +40,7 @@ use libafl_bolts::{ rands::StdRand, shmem::{ShMem, ShMemProvider, UnixShMemProvider}, tuples::{tuple_list, Merge}, - AsMutSlice, + AsSliceMut, }; use libafl_targets::cmps::AFLppCmpLogMap; use nix::sys::signal::Signal; @@ -245,7 +245,7 @@ fn fuzz( let mut shmem = shmem_provider.new_shmem(MAP_SIZE).unwrap(); // let the forkserver know the shmid shmem.write_to_env("__AFL_SHM_ID").unwrap(); - let shmem_buf = shmem.as_mut_slice(); + let shmem_buf = shmem.as_slice_mut(); // To let know the AFL++ binary that we have a big map std::env::set_var("AFL_MAP_SIZE", format!("{}", MAP_SIZE)); diff --git a/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs b/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs index 736085cb20..ad882e5b67 100644 --- a/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs +++ b/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs @@ -38,7 +38,7 @@ use libafl_bolts::{ rands::StdRand, shmem::{ShMem, ShMemProvider, UnixShMemProvider}, tuples::{tuple_list, Merge}, - AsMutSlice, + AsSliceMut, }; use libafl_targets::{ cmps::{observers::AFLppCmpLogObserver, stages::AFLppCmplogTracingStage}, @@ -246,7 +246,7 @@ fn fuzz( let mut shmem = shmem_provider.new_shmem(MAP_SIZE).unwrap(); // let the forkserver know the shmid shmem.write_to_env("__AFL_SHM_ID").unwrap(); - let shmem_buf = shmem.as_mut_slice(); + let shmem_buf = shmem.as_slice_mut(); // To let know the AFL++ binary that we have a big map std::env::set_var("AFL_MAP_SIZE", format!("{MAP_SIZE}")); diff --git a/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs b/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs index 5b712c4c42..8087ab81b4 100644 --- a/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs +++ b/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs @@ -28,7 +28,7 @@ use libafl::{ serialization_format::{DEFAULT_ENV_NAME, DEFAULT_SIZE}, ConcolicObserver, }, - TimeObserver, CanTrack, + CanTrack, TimeObserver, }, schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, stages::{ @@ -43,7 +43,7 @@ use libafl_bolts::{ rands::StdRand, shmem::{ShMem, ShMemProvider, StdShMemProvider}, tuples::tuple_list, - AsMutSlice, AsSlice, Named, + AsSliceMut, AsSlice, Named, }; use libafl_targets::{ libfuzzer_initialize, libfuzzer_test_one_input, std_edges_map_observer, CmpLogObserver, @@ -206,8 +206,7 @@ fn fuzz( concolic_shmem.write_to_env(DEFAULT_ENV_NAME).unwrap(); // The concolic observer observers the concolic shared memory map. - let concolic_observer = - ConcolicObserver::new("concolic".to_string(), concolic_shmem.as_mut_slice()); + let concolic_observer = ConcolicObserver::new("concolic", concolic_shmem.as_slice_mut()); let concolic_observer_name = concolic_observer.name().to_string(); diff --git a/fuzzers/qemu_cmin/src/fuzzer.rs b/fuzzers/qemu_cmin/src/fuzzer.rs index 6ccb40c1cb..c0878ce034 100644 --- a/fuzzers/qemu_cmin/src/fuzzer.rs +++ b/fuzzers/qemu_cmin/src/fuzzer.rs @@ -25,7 +25,7 @@ use libafl_bolts::{ rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::tuple_list, - AsMutSlice, AsSlice, + AsSlice, AsSliceMut, }; use libafl_qemu::{ edges::{QemuEdgeCoverageChildHelper, EDGES_MAP_PTR, EDGES_MAP_SIZE_IN_USE}, @@ -159,7 +159,7 @@ pub fn fuzz() -> Result<(), Error> { }; let mut edges_shmem = shmem_provider.new_shmem(EDGES_MAP_SIZE_IN_USE).unwrap(); - let edges = edges_shmem.as_mut_slice(); + let edges = edges_shmem.as_slice_mut(); unsafe { EDGES_MAP_PTR = edges.as_mut_ptr() }; let edges_observer = unsafe { diff --git a/fuzzers/tutorial/src/metadata.rs b/fuzzers/tutorial/src/metadata.rs index 192241fb34..2115cdd0b9 100644 --- a/fuzzers/tutorial/src/metadata.rs +++ b/fuzzers/tutorial/src/metadata.rs @@ -1,3 +1,5 @@ +use std::borrow::Cow; + use libafl::{ corpus::Testcase, events::EventFirer, @@ -78,8 +80,9 @@ where impl Named for PacketLenFeedback { #[inline] - fn name(&self) -> &str { - "PacketLenFeedback" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("PacketLenFeedback"); + &NAME } } diff --git a/fuzzers/tutorial/src/mutator.rs b/fuzzers/tutorial/src/mutator.rs index 09ebbb3454..46bc7a7248 100644 --- a/fuzzers/tutorial/src/mutator.rs +++ b/fuzzers/tutorial/src/mutator.rs @@ -1,3 +1,5 @@ +use std::borrow::Cow; + use lain::traits::Mutatable; use libafl::{ mutators::{MutationResult, Mutator}, @@ -28,8 +30,9 @@ where } impl Named for LainMutator { - fn name(&self) -> &str { - "LainMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("LainMutator"); + &NAME } } diff --git a/libafl/src/corpus/minimizer.rs b/libafl/src/corpus/minimizer.rs index 456a3acf61..53f24224f9 100644 --- a/libafl/src/corpus/minimizer.rs +++ b/libafl/src/corpus/minimizer.rs @@ -2,6 +2,7 @@ //! of your corpus. use alloc::{ + borrow::Cow, string::{String, ToString}, vec::Vec, }; @@ -143,7 +144,7 @@ where manager.fire( state, Event::UpdateUserStats { - name: "minimisation exec pass".to_string(), + name: Cow::from("minimisation exec pass"), value: UserStats::new(UserStatsValue::Ratio(curr, total), AggregatorOps::None), phantom: PhantomData, }, diff --git a/libafl/src/events/mod.rs b/libafl/src/events/mod.rs index f751e2839b..a5b9963ce7 100644 --- a/libafl/src/events/mod.rs +++ b/libafl/src/events/mod.rs @@ -19,9 +19,7 @@ pub use llmp::*; #[cfg(feature = "tcp_manager")] #[allow(clippy::ignored_unit_patterns)] pub mod tcp; -#[cfg(feature = "scalability_introspection")] -use alloc::string::ToString; -use alloc::{boxed::Box, string::String, vec::Vec}; +use alloc::{borrow::Cow, boxed::Box, string::String, vec::Vec}; use core::{ fmt, hash::{BuildHasher, Hasher}, @@ -315,7 +313,7 @@ where /// New user stats event to monitor. UpdateUserStats { /// Custom user monitor name - name: String, + name: Cow<'static, str>, /// Custom user monitor value value: UserStats, /// [`PhantomData`] @@ -534,7 +532,7 @@ where self.fire( state, Event::UpdateUserStats { - name: "total imported".to_string(), + name: Cow::from("total imported"), value: UserStats::new( UserStatsValue::Number( (imported_with_observer + imported_without_observer) as u64, diff --git a/libafl/src/executors/forkserver.rs b/libafl/src/executors/forkserver.rs index db66b8255c..a14e83bacf 100644 --- a/libafl/src/executors/forkserver.rs +++ b/libafl/src/executors/forkserver.rs @@ -23,7 +23,7 @@ use libafl_bolts::{ os::{dup2, pipes::Pipe}, shmem::{ShMem, ShMemProvider, UnixShMemProvider}, tuples::Prepend, - AsMutSlice, AsSlice, Truncate, + AsSlice, AsSliceMut, Truncate, }; use nix::{ sys::{ @@ -714,7 +714,7 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> { shmem.write_to_env("__AFL_SHM_FUZZ_ID")?; let size_in_bytes = (self.max_input_size + SHMEM_FUZZ_HDR_SIZE).to_ne_bytes(); - shmem.as_mut_slice()[..4].clone_from_slice(&size_in_bytes[..4]); + shmem.as_slice_mut()[..4].clone_from_slice(&size_in_bytes[..4]); Some(shmem) } }; @@ -1122,9 +1122,9 @@ where } let size_in_bytes = size.to_ne_bytes(); // The first four bytes tells the size of the shmem. - map.as_mut_slice()[..SHMEM_FUZZ_HDR_SIZE] + map.as_slice_mut()[..SHMEM_FUZZ_HDR_SIZE] .copy_from_slice(&size_in_bytes[..SHMEM_FUZZ_HDR_SIZE]); - map.as_mut_slice()[SHMEM_FUZZ_HDR_SIZE..(SHMEM_FUZZ_HDR_SIZE + size)] + map.as_slice_mut()[SHMEM_FUZZ_HDR_SIZE..(SHMEM_FUZZ_HDR_SIZE + size)] .copy_from_slice(&target_bytes.as_slice()[..size]); } else { self.input_file.write_buf(input.target_bytes().as_slice())?; @@ -1228,7 +1228,7 @@ mod tests { use libafl_bolts::{ shmem::{ShMem, ShMemProvider, UnixShMemProvider}, tuples::tuple_list, - AsMutSlice, + AsSliceMut, }; use serial_test::serial; @@ -1250,7 +1250,7 @@ mod tests { let mut shmem = shmem_provider.new_shmem(MAP_SIZE).unwrap(); shmem.write_to_env("__AFL_SHM_ID").unwrap(); - let shmem_buf = shmem.as_mut_slice(); + let shmem_buf = shmem.as_slice_mut(); let edges_observer = HitcountsMapObserver::new(ConstMapObserver::<_, MAP_SIZE>::new( "shared_mem", diff --git a/libafl/src/feedbacks/concolic.rs b/libafl/src/feedbacks/concolic.rs index 061b74c3d9..797e7ffe07 100644 --- a/libafl/src/feedbacks/concolic.rs +++ b/libafl/src/feedbacks/concolic.rs @@ -3,7 +3,7 @@ //! This feedback should be used in combination with another feedback as this feedback always considers testcases //! to be not interesting. //! Requires a [`ConcolicObserver`] to observe the concolic trace. -use alloc::{borrow::ToOwned, string::String}; +use alloc::borrow::Cow; use core::{fmt::Debug, marker::PhantomData}; use libafl_bolts::Named; @@ -25,7 +25,7 @@ use crate::{ /// Requires a [`ConcolicObserver`] to observe the concolic trace. #[derive(Debug)] pub struct ConcolicFeedback { - name: String, + name: Cow<'static, str>, phantom: PhantomData, } @@ -35,14 +35,14 @@ impl ConcolicFeedback { #[must_use] pub fn from_observer(observer: &ConcolicObserver) -> Self { Self { - name: observer.name().to_owned(), + name: observer.name().clone(), phantom: PhantomData, } } } impl Named for ConcolicFeedback { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } diff --git a/libafl/src/feedbacks/differential.rs b/libafl/src/feedbacks/differential.rs index fd32b31edf..b8bca11f58 100644 --- a/libafl/src/feedbacks/differential.rs +++ b/libafl/src/feedbacks/differential.rs @@ -1,7 +1,7 @@ //! Diff Feedback, comparing the content of two observers of the same type. //! -use alloc::string::{String, ToString}; +use alloc::borrow::Cow; use core::{ fmt::{self, Debug, Formatter}, marker::PhantomData, @@ -53,11 +53,11 @@ where F: FnMut(&O1, &O2) -> DiffResult, { /// This feedback's name - name: String, + name: Cow<'static, str>, /// The first observer to compare against - o1_name: String, + o1_name: Cow<'static, str>, /// The second observer to compare against - o2_name: String, + o2_name: Cow<'static, str>, /// The function used to compare the two observers compare_fn: F, phantomm: PhantomData<(O1, O2, I, S)>, @@ -70,9 +70,9 @@ where O2: Named, { /// Create a new [`DiffFeedback`] using two observers and a test function. - pub fn new(name: &str, o1: &O1, o2: &O2, compare_fn: F) -> Result { - let o1_name = o1.name().to_string(); - let o2_name = o2.name().to_string(); + 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 { Err(Error::illegal_argument(format!( "DiffFeedback: observer names must be different (both were {o1_name})" @@ -81,7 +81,7 @@ where Ok(Self { o1_name, o2_name, - name: name.to_string(), + name: Cow::from(name), compare_fn, phantomm: PhantomData, }) @@ -115,7 +115,7 @@ where O1: Named, O2: Named, { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } @@ -172,7 +172,7 @@ where #[cfg(test)] mod tests { - use alloc::string::{String, ToString}; + use alloc::borrow::Cow; use core::marker::PhantomData; use libafl_bolts::{tuples::tuple_list, Named}; @@ -188,13 +188,13 @@ mod tests { #[derive(Debug)] struct NopObserver { - name: String, + name: Cow<'static, str>, value: bool, } impl NopObserver { - fn new(name: &str, value: bool) -> Self { + fn new(name: &'static str, value: bool) -> Self { Self { - name: name.to_string(), + name: Cow::from(name), value, } } @@ -206,7 +206,7 @@ mod tests { } } impl Named for NopObserver { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } diff --git a/libafl/src/feedbacks/list.rs b/libafl/src/feedbacks/list.rs index ab9071be78..dad5c2fbb8 100644 --- a/libafl/src/feedbacks/list.rs +++ b/libafl/src/feedbacks/list.rs @@ -1,4 +1,4 @@ -use alloc::string::{String, ToString}; +use alloc::borrow::Cow; use core::{fmt::Debug, hash::Hash, marker::PhantomData}; use hashbrown::HashSet; @@ -70,8 +70,8 @@ pub struct ListFeedback where T: Hash + Eq, { - name: String, - observer_name: String, + name: Cow<'static, str>, + observer_name: Cow<'static, str>, novelty: HashSet, phantom: PhantomData, } @@ -151,8 +151,8 @@ where T: Debug + Serialize + Hash + Eq + DeserializeOwned, { #[inline] - fn name(&self) -> &str { - self.name.as_str() + fn name(&self) -> &Cow<'static, str> { + &self.name } } @@ -164,8 +164,8 @@ where #[must_use] pub fn new(observer: &ListObserver) -> Self { Self { - name: observer.name().to_string(), - observer_name: observer.name().to_string(), + name: observer.name().clone(), + observer_name: observer.name().clone(), novelty: HashSet::::new(), phantom: PhantomData, } diff --git a/libafl/src/feedbacks/map.rs b/libafl/src/feedbacks/map.rs index 3520dc164f..c0ead2010e 100644 --- a/libafl/src/feedbacks/map.rs +++ b/libafl/src/feedbacks/map.rs @@ -1,9 +1,6 @@ //! Map feedback, maximizing or minimizing maps, for example the afl-style map observer. -use alloc::{ - string::{String, ToString}, - vec::Vec, -}; +use alloc::{borrow::Cow, vec::Vec}; #[rustversion::nightly] use core::simd::prelude::SimdOrd; use core::{ @@ -12,7 +9,7 @@ use core::{ ops::{BitAnd, BitOr}, }; -use libafl_bolts::{AsIter, AsMutSlice, AsSlice, HasRefCnt, Named}; +use libafl_bolts::{AsIter, AsSlice, AsSliceMut, HasRefCnt, Named}; use num_traits::PrimInt; use serde::{de::DeserializeOwned, Deserialize, Serialize}; @@ -244,11 +241,11 @@ impl AsSlice for MapIndexesMetadata { } } -impl AsMutSlice for MapIndexesMetadata { +impl AsSliceMut for MapIndexesMetadata { type Entry = usize; /// Convert to a slice - fn as_mut_slice(&mut self) -> &mut [usize] { - self.list.as_mut_slice() + fn as_slice_mut(&mut self) -> &mut [usize] { + self.list.as_slice_mut() } } @@ -292,12 +289,12 @@ impl AsSlice for MapNoveltiesMetadata { } } -impl AsMutSlice for MapNoveltiesMetadata { +impl AsSliceMut for MapNoveltiesMetadata { type Entry = usize; /// Convert to a slice #[must_use] - fn as_mut_slice(&mut self) -> &mut [usize] { - self.list.as_mut_slice() + fn as_slice_mut(&mut self) -> &mut [usize] { + self.list.as_slice_mut() } } @@ -387,11 +384,11 @@ pub struct MapFeedback { /// New indexes observed in the last observation novelties: Option>, /// Name identifier of this instance - name: String, + name: Cow<'static, str>, /// Name identifier of the observer - observer_name: String, + observer_name: Cow<'static, str>, /// Name of the feedback as shown in the `UserStats` - stats_name: String, + stats_name: Cow<'static, str>, /// Phantom Data of Reducer phantom: PhantomData<(C, N, O, R, S, T)>, } @@ -481,7 +478,7 @@ where map_state.history_map.resize(len, observer.initial()); } - let history_map = map_state.history_map.as_mut_slice(); + let history_map = map_state.history_map.as_slice_mut(); if C::INDICES { let mut indices = Vec::new(); @@ -534,7 +531,7 @@ where manager.fire( state, Event::UpdateUserStats { - name: self.stats_name.to_string(), + name: self.stats_name.clone(), value: UserStats::new( UserStatsValue::Ratio(covered as u64, len as u64), AggregatorOps::Avg, @@ -671,8 +668,8 @@ where impl Named for MapFeedback { #[inline] - fn name(&self) -> &str { - self.name.as_str() + fn name(&self) -> &Cow<'static, str> { + &self.name } } @@ -682,13 +679,18 @@ where C: AsRef, { #[inline] - fn observer_name(&self) -> &str { - self.observer_name.as_str() + fn observer_name(&self) -> &Cow<'static, str> { + &self.observer_name } } -fn create_stats_name(name: &str) -> String { - name.to_lowercase() +#[allow(clippy::ptr_arg)] +fn create_stats_name(name: &Cow<'static, str>) -> Cow<'static, str> { + if name.chars().all(char::is_lowercase) { + name.clone() + } else { + name.to_lowercase().into() + } } impl MapFeedback @@ -707,8 +709,8 @@ where let map_observer = map_observer.as_ref(); Self { novelties: if C::NOVELTIES { Some(vec![]) } else { None }, - name: map_observer.name().to_string(), - observer_name: map_observer.name().to_string(), + name: map_observer.name().clone(), + observer_name: map_observer.name().clone(), stats_name: create_stats_name(map_observer.name()), phantom: PhantomData, } @@ -719,12 +721,13 @@ where /// same name and therefore also the same history. #[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 }, - name: name.to_string(), - observer_name: map_observer.name().to_string(), - stats_name: create_stats_name(name), + observer_name: map_observer.name().clone(), + stats_name: create_stats_name(&name), + name, phantom: PhantomData, } } diff --git a/libafl/src/feedbacks/mod.rs b/libafl/src/feedbacks/mod.rs index 8d149bb3f7..fb57a35083 100644 --- a/libafl/src/feedbacks/mod.rs +++ b/libafl/src/feedbacks/mod.rs @@ -5,6 +5,9 @@ // 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; @@ -29,7 +32,6 @@ pub mod transferred; /// The module for list feedback pub mod list; -use alloc::string::{String, ToString}; use core::{ fmt::{self, Debug, Formatter}, marker::PhantomData, @@ -138,7 +140,7 @@ where /// Has an associated observer name (mostly used to retrieve the observer with `MatchName` from an `ObserverTuple`) pub trait HasObserverName { /// The name associated with the observer - fn observer_name(&self) -> &str; + fn observer_name(&self) -> &Cow<'static, str>; } /// A combined feedback consisting of multiple [`Feedback`]s @@ -154,7 +156,7 @@ where pub first: A, /// Second [`Feedback`] pub second: B, - name: String, + name: Cow<'static, str>, phantom: PhantomData<(S, FL)>, } @@ -165,8 +167,8 @@ where FL: FeedbackLogic, S: State, { - fn name(&self) -> &str { - self.name.as_ref() + fn name(&self) -> &Cow<'static, str> { + &self.name } } @@ -179,7 +181,12 @@ where { /// Create a new combined feedback pub fn new(first: A, second: B) -> Self { - let name = format!("{} ({},{})", FL::name(), first.name(), second.name()); + let name = Cow::from(format!( + "{} ({},{})", + FL::name(), + first.name(), + second.name() + )); Self { first, second, @@ -641,7 +648,7 @@ where /// The feedback to invert pub first: A, /// The name - name: String, + name: Cow<'static, str>, phantom: PhantomData, } @@ -713,7 +720,7 @@ where S: State, { #[inline] - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } @@ -725,7 +732,7 @@ where { /// Creates a new [`NotFeedback`]. pub fn new(first: A) -> Self { - let name = format!("Not({})", first.name()); + let name = Cow::from(format!("Not({})", first.name())); Self { first, name, @@ -839,8 +846,9 @@ where impl Named for CrashFeedback { #[inline] - fn name(&self) -> &str { - "CrashFeedback" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("CrashFeedback"); + &NAME } } @@ -895,8 +903,9 @@ where impl Named for TimeoutFeedback { #[inline] - fn name(&self) -> &str { - "TimeoutFeedback" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("TimeoutFeedback"); + &NAME } } @@ -922,7 +931,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: String, + name: Cow<'static, str>, } impl Feedback for TimeFeedback @@ -973,8 +982,8 @@ where impl Named for TimeFeedback { #[inline] - fn name(&self) -> &str { - self.name.as_str() + fn name(&self) -> &Cow<'static, str> { + &self.name } } @@ -983,7 +992,7 @@ impl TimeFeedback { #[must_use] pub fn new(name: &'static str) -> Self { Self { - name: name.to_string(), + name: Cow::from(name), } } @@ -991,7 +1000,7 @@ impl TimeFeedback { #[must_use] pub fn with_observer(observer: &TimeObserver) -> Self { Self { - name: observer.name().to_string(), + name: observer.name().clone(), } } } @@ -1033,8 +1042,9 @@ where impl Named for ConstFeedback { #[inline] - fn name(&self) -> &str { - "ConstFeedback" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("ConstFeedback"); + &NAME } } diff --git a/libafl/src/feedbacks/nautilus.rs b/libafl/src/feedbacks/nautilus.rs index f06db45cd3..a2407577ce 100644 --- a/libafl/src/feedbacks/nautilus.rs +++ b/libafl/src/feedbacks/nautilus.rs @@ -1,5 +1,5 @@ //! Nautilus grammar mutator, see -use alloc::string::String; +use alloc::{borrow::Cow, string::String}; use core::{fmt::Debug, marker::PhantomData}; use std::fs::create_dir_all; @@ -74,8 +74,9 @@ impl<'a, S> NautilusFeedback<'a, S> { } impl<'a, S> Named for NautilusFeedback<'a, S> { - fn name(&self) -> &str { - "NautilusFeedback" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("NautilusFeedback"); + &NAME } } diff --git a/libafl/src/feedbacks/new_hash_feedback.rs b/libafl/src/feedbacks/new_hash_feedback.rs index c99c4e79e9..366e41ccc4 100644 --- a/libafl/src/feedbacks/new_hash_feedback.rs +++ b/libafl/src/feedbacks/new_hash_feedback.rs @@ -1,6 +1,6 @@ //! The ``NewHashFeedback`` uses the backtrace hash and a hashset to only keep novel cases -use alloc::string::{String, ToString}; +use alloc::{borrow::Cow, string::ToString}; use std::{fmt::Debug, marker::PhantomData}; use hashbrown::HashSet; @@ -78,8 +78,8 @@ impl HashSetState for NewHashFeedbackMetadata { /// A [`NewHashFeedback`] maintains a hashset of already seen stacktraces and considers interesting unseen ones #[derive(Serialize, Deserialize, Clone, Debug)] pub struct NewHashFeedback { - name: String, - observer_name: String, + name: Cow<'static, str>, + observer_name: Cow<'static, str>, /// Initial capacity of hash set capacity: usize, o_type: PhantomData<(O, S)>, @@ -137,14 +137,14 @@ where impl Named for NewHashFeedback { #[inline] - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } impl HasObserverName for NewHashFeedback { #[inline] - fn observer_name(&self) -> &str { + fn observer_name(&self) -> &Cow<'static, str> { &self.observer_name } } @@ -159,18 +159,6 @@ impl NewHashFeedback where O: ObserverWithHashField + Named, { - /// Returns a new [`NewHashFeedback`]. - /// Setting an observer name that doesn't exist would eventually trigger a panic. - #[must_use] - pub fn with_names(name: &str, observer_name: &str) -> Self { - Self { - name: name.to_string(), - observer_name: observer_name.to_string(), - capacity: DEFAULT_CAPACITY, - o_type: PhantomData, - } - } - /// Returns a new [`NewHashFeedback`]. #[must_use] pub fn new(observer: &O) -> Self { @@ -182,8 +170,8 @@ where #[must_use] pub fn with_capacity(observer: &O, capacity: usize) -> Self { Self { - name: NEWHASHFEEDBACK_PREFIX.to_string() + observer.name(), - observer_name: observer.name().to_string(), + name: Cow::from(NEWHASHFEEDBACK_PREFIX.to_string() + observer.name()), + observer_name: observer.name().clone(), capacity, o_type: PhantomData, } diff --git a/libafl/src/feedbacks/stdio.rs b/libafl/src/feedbacks/stdio.rs index 06cb5f9224..d79b41ac90 100644 --- a/libafl/src/feedbacks/stdio.rs +++ b/libafl/src/feedbacks/stdio.rs @@ -1,6 +1,6 @@ //! Feedback and metatadata for stderr and stdout. -use alloc::string::{String, ToString}; +use alloc::{borrow::Cow, string::String}; use libafl_bolts::{impl_serdeany, Named}; use serde::{Deserialize, Serialize}; @@ -28,7 +28,7 @@ impl_serdeany!(StdOutMetadata); /// is never interesting (use with an OR). #[derive(Serialize, Deserialize, Clone, Debug)] pub struct StdOutToMetadataFeedback { - name: String, + name: Cow<'static, str>, } impl Feedback for StdOutToMetadataFeedback @@ -90,8 +90,8 @@ where impl Named for StdOutToMetadataFeedback { #[inline] - fn name(&self) -> &str { - self.name.as_str() + fn name(&self) -> &Cow<'static, str> { + &self.name } } @@ -99,9 +99,9 @@ impl StdOutToMetadataFeedback { /// Creates a new [`StdOutToMetadataFeedback`]. The provided `name` is /// used to look up the observer. #[must_use] - pub fn new(name: &str) -> Self { + pub fn new(name: &'static str) -> Self { Self { - name: name.to_string(), + name: Cow::from(name), } } @@ -109,7 +109,7 @@ impl StdOutToMetadataFeedback { #[must_use] pub fn with_observer(observer: &StdOutObserver) -> Self { Self { - name: observer.name().to_string(), + name: observer.name().clone(), } } } @@ -127,7 +127,7 @@ impl_serdeany!(StdErrMetadata); /// is never interesting (use with an OR). #[derive(Serialize, Deserialize, Clone, Debug)] pub struct StdErrToMetadataFeedback { - name: String, + name: Cow<'static, str>, } impl Feedback for StdErrToMetadataFeedback @@ -189,8 +189,8 @@ where impl Named for StdErrToMetadataFeedback { #[inline] - fn name(&self) -> &str { - self.name.as_str() + fn name(&self) -> &Cow<'static, str> { + &self.name } } @@ -198,9 +198,9 @@ impl StdErrToMetadataFeedback { /// Creates a new [`StdErrToMetadataFeedback`]. The provided `name` is /// used to look up the observer. #[must_use] - pub fn new(name: &str) -> Self { + pub fn new(name: &'static str) -> Self { Self { - name: name.to_string(), + name: Cow::from(name), } } @@ -208,7 +208,7 @@ impl StdErrToMetadataFeedback { #[must_use] pub fn with_observer(observer: &StdErrObserver) -> Self { Self { - name: observer.name().to_string(), + name: observer.name().clone(), } } } diff --git a/libafl/src/feedbacks/transferred.rs b/libafl/src/feedbacks/transferred.rs index e0c4090da2..d6d2c36b5a 100644 --- a/libafl/src/feedbacks/transferred.rs +++ b/libafl/src/feedbacks/transferred.rs @@ -1,6 +1,8 @@ //! Feedbacks and associated metadata for detecting whether a given testcase was transferred from //! another node. +use alloc::borrow::Cow; + use libafl_bolts::{impl_serdeany, Error, Named}; use serde::{Deserialize, Serialize}; @@ -10,7 +12,8 @@ use crate::{ }; /// Constant name of the [`TransferringMetadata`]. -pub const TRANSFERRED_FEEDBACK_NAME: &str = "transferred_feedback_internal"; +pub const TRANSFERRED_FEEDBACK_NAME: Cow<'static, str> = + Cow::Borrowed("transferred_feedback_internal"); /// Metadata which denotes whether we are currently transferring an input. Implementors of /// multi-node communication systems (like [`crate::events::LlmpEventManager`]) should wrap any @@ -37,8 +40,8 @@ impl TransferringMetadata { pub struct TransferredFeedback; impl Named for TransferredFeedback { - fn name(&self) -> &str { - TRANSFERRED_FEEDBACK_NAME + fn name(&self) -> &Cow<'static, str> { + &TRANSFERRED_FEEDBACK_NAME } } diff --git a/libafl/src/monitors/mod.rs b/libafl/src/monitors/mod.rs index f0aacfc6b4..5b3a3081d3 100644 --- a/libafl/src/monitors/mod.rs +++ b/libafl/src/monitors/mod.rs @@ -16,7 +16,7 @@ use alloc::string::ToString; pub use prometheus::PrometheusMonitor; #[cfg(feature = "std")] pub mod disk; -use alloc::{fmt::Debug, string::String, vec::Vec}; +use alloc::{borrow::Cow, fmt::Debug, string::String, vec::Vec}; use core::{fmt, fmt::Write, time::Duration}; #[cfg(feature = "std")] @@ -158,7 +158,7 @@ pub enum UserStatsValue { /// A Float value Float(f64), /// A `String` - String(String), + String(Cow<'static, str>), /// A ratio of two values Ratio(u64, u64), /// Percent @@ -364,7 +364,7 @@ pub struct ClientStats { /// the start time of the client pub start_time: Duration, /// User-defined monitor - pub user_monitor: HashMap, + pub user_monitor: HashMap, UserStats>, /// Client performance statistics #[cfg(feature = "introspection")] pub introspection_monitor: ClientPerfMonitor, @@ -465,7 +465,11 @@ impl ClientStats { } /// Update the user-defined stat with name and value - pub fn update_user_stats(&mut self, name: String, value: UserStats) -> Option { + pub fn update_user_stats( + &mut self, + name: Cow<'static, str>, + value: UserStats, + ) -> Option { self.user_monitor.insert(name, value) } diff --git a/libafl/src/monitors/prometheus.rs b/libafl/src/monitors/prometheus.rs index 63132b5896..2ef8227b9b 100644 --- a/libafl/src/monitors/prometheus.rs +++ b/libafl/src/monitors/prometheus.rs @@ -22,7 +22,7 @@ // When using docker, you may need to point prometheus.yml to the docker0 interface or host.docker.internal // ==================== -use alloc::{fmt::Debug, string::String, vec::Vec}; +use alloc::{borrow::Cow, fmt::Debug, string::String, vec::Vec}; use core::{fmt, time::Duration}; use std::{ sync::{atomic::AtomicU64, Arc}, @@ -111,42 +111,42 @@ where self.corpus_count .get_or_create(&Labels { client: sender_id.0, - stat: String::new(), + stat: Cow::from(""), }) .set(corpus_size.try_into().unwrap()); let objective_size = self.objective_size(); self.objective_count .get_or_create(&Labels { client: sender_id.0, - stat: String::new(), + stat: Cow::from(""), }) .set(objective_size.try_into().unwrap()); let total_execs = self.total_execs(); self.executions .get_or_create(&Labels { client: sender_id.0, - stat: String::new(), + stat: Cow::from(""), }) .set(total_execs.try_into().unwrap()); let execs_per_sec = self.execs_per_sec(); self.exec_rate .get_or_create(&Labels { client: sender_id.0, - stat: String::new(), + stat: Cow::from(""), }) .set(execs_per_sec); let run_time = (current_time() - self.start_time).as_secs(); self.runtime .get_or_create(&Labels { client: sender_id.0, - stat: String::new(), + stat: Cow::from(""), }) .set(run_time.try_into().unwrap()); // run time in seconds, which can be converted to a time format by Grafana or similar let total_clients = self.client_stats_count().try_into().unwrap(); // convert usize to u64 (unlikely that # of clients will be > 2^64 -1...) self.clients_count .get_or_create(&Labels { client: sender_id.0, - stat: String::new(), + stat: Cow::from(""), }) .set(total_clients); @@ -352,7 +352,7 @@ pub async fn serve_metrics( #[derive(Clone, Hash, PartialEq, Eq, EncodeLabelSet, Debug)] pub struct Labels { client: u32, // sender_id: u32, to differentiate between clients when multiple are spawned. - stat: String, // for custom_stat filtering. + stat: Cow<'static, str>, // for custom_stat filtering. } #[derive(Clone)] diff --git a/libafl/src/monitors/tui/mod.rs b/libafl/src/monitors/tui/mod.rs index d407e0ad9d..149760aa69 100644 --- a/libafl/src/monitors/tui/mod.rs +++ b/libafl/src/monitors/tui/mod.rs @@ -1,6 +1,6 @@ //! Monitor based on ratatui -use alloc::{boxed::Box, string::ToString}; +use alloc::{borrow::Cow, boxed::Box, string::ToString}; use core::cmp; use std::{ collections::VecDeque, @@ -211,7 +211,7 @@ pub struct ClientTuiContext { pub process_timing: ProcessTiming, pub item_geometry: ItemGeometry, - pub user_stats: HashMap, + pub user_stats: HashMap, UserStats>, } impl ClientTuiContext { diff --git a/libafl/src/mutators/encoded_mutations.rs b/libafl/src/mutators/encoded_mutations.rs index a7dfac9716..7d35a10c3a 100644 --- a/libafl/src/mutators/encoded_mutations.rs +++ b/libafl/src/mutators/encoded_mutations.rs @@ -1,6 +1,6 @@ //! Mutations for [`EncodedInput`]s //! -use alloc::vec::Vec; +use alloc::{borrow::Cow, vec::Vec}; use core::cmp::{max, min}; use libafl_bolts::{ @@ -37,8 +37,9 @@ impl Mutator for EncodedRandMutator { } impl Named for EncodedRandMutator { - fn name(&self) -> &str { - "EncodedRandMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("EncodedRandMutator"); + &NAME } } @@ -67,8 +68,9 @@ impl Mutator for EncodedIncMutator { } impl Named for EncodedIncMutator { - fn name(&self) -> &str { - "EncodedIncMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("EncodedIncMutator"); + &NAME } } @@ -97,8 +99,9 @@ impl Mutator for EncodedDecMutator { } impl Named for EncodedDecMutator { - fn name(&self) -> &str { - "EncodedDecMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("EncodedDecMutator"); + &NAME } } @@ -131,8 +134,9 @@ impl Mutator for EncodedAddMutator { } impl Named for EncodedAddMutator { - fn name(&self) -> &str { - "EncodedAddMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("EncodedAddMutator"); + &NAME } } @@ -164,8 +168,9 @@ impl Mutator for EncodedDeleteMutator { } impl Named for EncodedDeleteMutator { - fn name(&self) -> &str { - "EncodedDeleteMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("EncodedDeleteMutator"); + &NAME } } @@ -224,8 +229,9 @@ where } impl Named for EncodedInsertCopyMutator { - fn name(&self) -> &str { - "EncodedInsertCopyMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("EncodedInsertCopyMutator"); + &NAME } } @@ -261,8 +267,9 @@ impl Mutator for EncodedCopyMutator { } impl Named for EncodedCopyMutator { - fn name(&self) -> &str { - "EncodedCopyMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("EncodedCopyMutator"); + &NAME } } @@ -330,8 +337,9 @@ where } impl Named for EncodedCrossoverInsertMutator { - fn name(&self) -> &str { - "EncodedCrossoverInsertMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("EncodedCrossoverInsertMutator"); + &NAME } } @@ -392,8 +400,9 @@ where } impl Named for EncodedCrossoverReplaceMutator { - fn name(&self) -> &str { - "EncodedCrossoverReplaceMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("EncodedCrossoverReplaceMutator"); + &NAME } } diff --git a/libafl/src/mutators/gramatron.rs b/libafl/src/mutators/gramatron.rs index 0f24ad53ea..79f383fead 100644 --- a/libafl/src/mutators/gramatron.rs +++ b/libafl/src/mutators/gramatron.rs @@ -1,6 +1,6 @@ //! Gramatron is the rewritten gramatron fuzzer in rust. //! See the original gramatron repo [`Gramatron`](https://github.com/HexHive/Gramatron) for more details. -use alloc::vec::Vec; +use alloc::{borrow::Cow, vec::Vec}; use core::cmp::max; use hashbrown::HashMap; @@ -56,8 +56,9 @@ impl<'a, S> Named for GramatronRandomMutator<'a, S> where S: HasRand + HasMetadata, { - fn name(&self) -> &str { - "GramatronRandomMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("GramatronRandomMutator"); + &NAME } } @@ -151,8 +152,9 @@ where } impl Named for GramatronSpliceMutator { - fn name(&self) -> &str { - "GramatronSpliceMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("GramatronSpliceMutator"); + &NAME } } @@ -253,8 +255,9 @@ where } impl Named for GramatronRecursionMutator { - fn name(&self) -> &str { - "GramatronRecursionMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("GramatronRecursionMutator"); + &NAME } } diff --git a/libafl/src/mutators/grimoire.rs b/libafl/src/mutators/grimoire.rs index 73f73221de..6947235e53 100644 --- a/libafl/src/mutators/grimoire.rs +++ b/libafl/src/mutators/grimoire.rs @@ -1,7 +1,7 @@ //! Grimoire is the rewritten grimoire mutator in rust. //! See the original repo [`Grimoire`](https://github.com/RUB-SysSec/grimoire) for more details. -use alloc::vec::Vec; +use alloc::{borrow::Cow, vec::Vec}; use core::cmp::{max, min}; use libafl_bolts::{ @@ -135,8 +135,9 @@ where } impl Named for GrimoireExtensionMutator { - fn name(&self) -> &str { - "GrimoireExtensionMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("GrimoireExtensionMutator"); + &NAME } } @@ -209,8 +210,9 @@ where } impl Named for GrimoireRecursiveReplacementMutator { - fn name(&self) -> &str { - "GrimoireRecursiveReplacementMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("GrimoireRecursiveReplacementMutator"); + &NAME } } @@ -320,8 +322,9 @@ where } impl Named for GrimoireStringReplacementMutator { - fn name(&self) -> &str { - "GrimoireStringReplacementMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("GrimoireStringReplacementMutator"); + &NAME } } @@ -378,8 +381,9 @@ where } impl Named for GrimoireRandomDeleteMutator { - fn name(&self) -> &str { - "GrimoireRandomDeleteMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("GrimoireRandomDeleteMutator"); + &NAME } } diff --git a/libafl/src/mutators/mod.rs b/libafl/src/mutators/mod.rs index 7a45850a1a..5024e67d48 100644 --- a/libafl/src/mutators/mod.rs +++ b/libafl/src/mutators/mod.rs @@ -394,11 +394,11 @@ impl MutatorsTuple for Vec>> { } fn names_reversed(&self) -> Vec<&str> { - self.iter().rev().map(|x| x.name()).collect() + self.iter().rev().map(|x| x.name().as_ref()).collect() } fn names(&self) -> Vec<&str> { - self.iter().map(|x| x.name()).collect() + self.iter().map(|x| x.name().as_ref()).collect() } } diff --git a/libafl/src/mutators/mopt_mutator.rs b/libafl/src/mutators/mopt_mutator.rs index ad45a6a6ee..8d0f4507bd 100644 --- a/libafl/src/mutators/mopt_mutator.rs +++ b/libafl/src/mutators/mopt_mutator.rs @@ -1,8 +1,5 @@ //! The `MOpt` mutator scheduler, see and -use alloc::{ - string::{String, ToString}, - vec::Vec, -}; +use alloc::{borrow::Cow, string::ToString, vec::Vec}; use core::{ fmt::{self, Debug}, marker::PhantomData, @@ -367,7 +364,7 @@ where MT: MutatorsTuple, S: HasRand + HasMetadata + HasCorpus + HasSolutions, { - name: String, + name: Cow<'static, str>, mode: MOptMode, finds_before: usize, mutations: MT, @@ -532,7 +529,7 @@ where state.add_metadata::(MOpt::new(mutations.len(), swarm_num, rand_seed)?); } Ok(Self { - name: format!("StdMOptMutator[{}]", mutations.names().join(",")), + name: Cow::from(format!("StdMOptMutator[{}]", mutations.names().join(","))), mode: MOptMode::Pilotfuzzing, finds_before: 0, mutations, @@ -617,7 +614,7 @@ where MT: MutatorsTuple, S: HasRand + HasMetadata + HasCorpus + HasSolutions, { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } diff --git a/libafl/src/mutators/mutations.rs b/libafl/src/mutators/mutations.rs index 0b02e55019..3687e6d22b 100644 --- a/libafl/src/mutators/mutations.rs +++ b/libafl/src/mutators/mutations.rs @@ -1,6 +1,9 @@ //! A wide variety of mutations used during fuzzing. -use alloc::{borrow::ToOwned, vec::Vec}; +use alloc::{ + borrow::{Cow, ToOwned}, + vec::Vec, +}; use core::{cmp::min, marker::PhantomData, mem::size_of, ops::Range}; use libafl_bolts::{rands::Rand, Named}; @@ -135,8 +138,9 @@ where } impl Named for BitFlipMutator { - fn name(&self) -> &str { - "BitFlipMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("BitFlipMutator"); + &NAME } } @@ -168,8 +172,9 @@ where } impl Named for ByteFlipMutator { - fn name(&self) -> &str { - "ByteFlipMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("ByteFlipMutator"); + &NAME } } @@ -202,8 +207,9 @@ where } impl Named for ByteIncMutator { - fn name(&self) -> &str { - "ByteIncMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("ByteIncMutator"); + &NAME } } @@ -236,8 +242,9 @@ where } impl Named for ByteDecMutator { - fn name(&self) -> &str { - "ByteDecMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("ByteDecMutator"); + &NAME } } @@ -270,8 +277,9 @@ where } impl Named for ByteNegMutator { - fn name(&self) -> &str { - "ByteNegMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("ByteNegMutator"); + &NAME } } @@ -304,8 +312,9 @@ where } impl Named for ByteRandMutator { - fn name(&self) -> &str { - "ByteRandMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("ByteRandMutator"); + &NAME } } @@ -364,8 +373,9 @@ macro_rules! add_mutator_impl { } impl Named for $name { - fn name(&self) -> &str { - stringify!($name) + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed(stringify!($name)); + &NAME } } @@ -417,8 +427,9 @@ macro_rules! interesting_mutator_impl { } impl Named for $name { - fn name(&self) -> &str { - stringify!($name) + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed(stringify!($name)); + &NAME } } @@ -460,8 +471,9 @@ where } impl Named for BytesDeleteMutator { - fn name(&self) -> &str { - "BytesDeleteMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("BytesDeleteMutator"); + &NAME } } @@ -506,8 +518,9 @@ where } impl Named for BytesExpandMutator { - fn name(&self) -> &str { - "BytesExpandMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("BytesExpandMutator"); + &NAME } } @@ -559,8 +572,9 @@ where } impl Named for BytesInsertMutator { - fn name(&self) -> &str { - "BytesInsertMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("BytesInsertMutator"); + &NAME } } @@ -612,8 +626,9 @@ where } impl Named for BytesRandInsertMutator { - fn name(&self) -> &str { - "BytesRandInsertMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("BytesRandInsertMutator"); + &NAME } } @@ -650,8 +665,9 @@ where } impl Named for BytesSetMutator { - fn name(&self) -> &str { - "BytesSetMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("BytesSetMutator"); + &NAME } } @@ -688,8 +704,9 @@ where } impl Named for BytesRandSetMutator { - fn name(&self) -> &str { - "BytesRandSetMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("BytesRandSetMutator"); + &NAME } } @@ -728,8 +745,9 @@ where } impl Named for BytesCopyMutator { - fn name(&self) -> &str { - "BytesCopyMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("BytesCopyMutator"); + &NAME } } @@ -787,8 +805,9 @@ where } impl Named for BytesInsertCopyMutator { - fn name(&self) -> &str { - "BytesInsertCopyMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("BytesInsertCopyMutator"); + &NAME } } @@ -990,8 +1009,9 @@ where } impl Named for BytesSwapMutator { - fn name(&self) -> &str { - "BytesSwapMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("BytesSwapMutator"); + &NAME } } @@ -1082,8 +1102,9 @@ where } impl Named for CrossoverInsertMutator { - fn name(&self) -> &str { - "CrossoverInsertMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("CrossoverInsertMutator"); + &NAME } } @@ -1163,8 +1184,9 @@ where } impl Named for CrossoverReplaceMutator { - fn name(&self) -> &str { - "CrossoverReplaceMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("CrossoverReplaceMutator"); + &NAME } } @@ -1242,8 +1264,9 @@ where } impl Named for SpliceMutator { - fn name(&self) -> &str { - "SpliceMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("SpliceMutator"); + &NAME } } diff --git a/libafl/src/mutators/nautilus.rs b/libafl/src/mutators/nautilus.rs index 88d808c915..c544b3e4ad 100644 --- a/libafl/src/mutators/nautilus.rs +++ b/libafl/src/mutators/nautilus.rs @@ -1,5 +1,6 @@ //! Mutators for the `Nautilus` grammmar fuzzer +use alloc::borrow::Cow; use core::fmt::Debug; use grammartec::{ @@ -60,8 +61,9 @@ impl Mutator for NautilusRandomMutator<'_> { } impl Named for NautilusRandomMutator<'_> { - fn name(&self) -> &str { - "NautilusRandomMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("NautilusRandomMutator"); + &NAME } } @@ -123,8 +125,9 @@ impl Mutator for NautilusRecursionMutator<'_> { } impl Named for NautilusRecursionMutator<'_> { - fn name(&self) -> &str { - "NautilusRecursionMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("NautilusRecursionMutator"); + &NAME } } @@ -190,8 +193,9 @@ where } impl Named for NautilusSpliceMutator<'_> { - fn name(&self) -> &str { - "NautilusSpliceMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("NautilusSpliceMutator"); + &NAME } } diff --git a/libafl/src/mutators/scheduled.rs b/libafl/src/mutators/scheduled.rs index ffbb190fb7..87d6a188e6 100644 --- a/libafl/src/mutators/scheduled.rs +++ b/libafl/src/mutators/scheduled.rs @@ -1,6 +1,6 @@ //! The `ScheduledMutator` schedules multiple mutations internally. -use alloc::{string::String, vec::Vec}; +use alloc::{borrow::Cow, vec::Vec}; use core::{ fmt::{self, Debug}, marker::PhantomData, @@ -9,7 +9,7 @@ use core::{ use libafl_bolts::{ rands::Rand, tuples::{tuple_list, tuple_list_type, Merge, NamedTuple}, - AsMutSlice, AsSlice, Named, + AsSlice, AsSliceMut, Named, }; use serde::{Deserialize, Serialize}; @@ -40,30 +40,30 @@ use crate::{ )] // for SerdeAny pub struct LogMutationMetadata { /// A list of logs - pub list: Vec, + pub list: Vec>, } libafl_bolts::impl_serdeany!(LogMutationMetadata); impl AsSlice for LogMutationMetadata { - type Entry = String; + type Entry = Cow<'static, str>; #[must_use] - fn as_slice(&self) -> &[String] { + fn as_slice(&self) -> &[Cow<'static, str>] { self.list.as_slice() } } -impl AsMutSlice for LogMutationMetadata { - type Entry = String; +impl AsSliceMut for LogMutationMetadata { + type Entry = Cow<'static, str>; #[must_use] - fn as_mut_slice(&mut self) -> &mut [String] { - self.list.as_mut_slice() + fn as_slice_mut(&mut self) -> &mut [Cow<'static, str>] { + self.list.as_slice_mut() } } impl LogMutationMetadata { /// Creates new [`struct@LogMutationMetadata`]. #[must_use] - pub fn new(list: Vec) -> Self { + pub fn new(list: Vec>) -> Self { Self { list } } } @@ -113,7 +113,7 @@ where MT: MutatorsTuple, S: HasRand, { - name: String, + name: Cow<'static, str>, mutations: MT, max_stack_pow: u64, phantom: PhantomData<(I, S)>, @@ -139,7 +139,7 @@ where MT: MutatorsTuple, S: HasRand, { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } @@ -198,7 +198,10 @@ where /// Create a new [`StdScheduledMutator`] instance specifying mutations pub fn new(mutations: MT) -> Self { StdScheduledMutator { - name: format!("StdScheduledMutator[{}]", mutations.names().join(", ")), + name: Cow::from(format!( + "StdScheduledMutator[{}]", + mutations.names().join(", ") + )), mutations, max_stack_pow: 7, phantom: PhantomData, @@ -208,7 +211,10 @@ where /// Create a new [`StdScheduledMutator`] instance specifying mutations and the maximun number of iterations pub fn with_max_stack_pow(mutations: MT, max_stack_pow: u64) -> Self { StdScheduledMutator { - name: format!("StdScheduledMutator[{}]", mutations.names().join(", ")), + name: Cow::from(format!( + "StdScheduledMutator[{}]", + mutations.names().join(", ") + )), mutations, max_stack_pow, phantom: PhantomData, @@ -340,7 +346,7 @@ where S: HasRand + HasCorpus, SM: ScheduledMutator, { - name: String, + name: Cow<'static, str>, scheduled: SM, mutation_log: Vec, phantom: PhantomData<(I, MT, S)>, @@ -368,7 +374,7 @@ where S: HasRand + HasCorpus, SM: ScheduledMutator, { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } @@ -386,9 +392,9 @@ where fn post_exec(&mut self, state: &mut S, corpus_idx: Option) -> Result<(), Error> { if let Some(idx) = corpus_idx { let mut testcase = (*state.corpus_mut().get(idx)?).borrow_mut(); - let mut log = Vec::::new(); + let mut log = Vec::>::new(); while let Some(idx) = self.mutation_log.pop() { - let name = String::from(self.scheduled.mutations().name(idx.0).unwrap()); // TODO maybe return an Error on None + let name = self.scheduled.mutations().name(idx.0).unwrap().clone(); // TODO maybe return an Error on None log.push(name); } let meta = LogMutationMetadata::new(log); @@ -460,7 +466,7 @@ where /// This mutator logs all mutators. pub fn new(scheduled: SM) -> Self { Self { - name: format!("LoggerScheduledMutator[{}]", scheduled.name()), + name: Cow::from(format!("LoggerScheduledMutator[{}]", scheduled.name())), scheduled, mutation_log: vec![], phantom: PhantomData, diff --git a/libafl/src/mutators/string.rs b/libafl/src/mutators/string.rs index 144a12e243..348521bddf 100644 --- a/libafl/src/mutators/string.rs +++ b/libafl/src/mutators/string.rs @@ -1,5 +1,5 @@ //! Mutators for preserving string categories, which may be useful for certain targets which are primarily string-oriented. -use alloc::vec::Vec; +use alloc::{borrow::Cow, vec::Vec}; use core::{ cmp::{Ordering, Reverse}, ops::Range, @@ -271,8 +271,9 @@ fn rand_replace_range char>( pub struct StringCategoryRandMutator; impl Named for StringCategoryRandMutator { - fn name(&self) -> &str { - "string-category-rand" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("string-category-rand"); + &NAME } } @@ -329,8 +330,9 @@ where pub struct StringSubcategoryRandMutator; impl Named for StringSubcategoryRandMutator { - fn name(&self) -> &str { - "string-subcategory-rand" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("string-subcategory-rand"); + &NAME } } @@ -375,8 +377,9 @@ where pub struct StringCategoryTokenReplaceMutator; impl Named for StringCategoryTokenReplaceMutator { - fn name(&self) -> &str { - "string-category-token-replace" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("string-category-token-replace"); + &NAME } } @@ -434,8 +437,9 @@ where pub struct StringSubcategoryTokenReplaceMutator; impl Named for StringSubcategoryTokenReplaceMutator { - fn name(&self) -> &str { - "string-subcategory-replace" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("string-subcategory-replace"); + &NAME } } diff --git a/libafl/src/mutators/token_mutations.rs b/libafl/src/mutators/token_mutations.rs index 22819942bf..3783d9adb8 100644 --- a/libafl/src/mutators/token_mutations.rs +++ b/libafl/src/mutators/token_mutations.rs @@ -1,6 +1,6 @@ //! Tokens are what AFL calls extras or dictionaries. //! They may be inserted as part of mutations during fuzzing. -use alloc::vec::Vec; +use alloc::{borrow::Cow, vec::Vec}; #[cfg(any(target_os = "linux", target_vendor = "apple"))] use core::slice::from_raw_parts; use core::{ @@ -346,8 +346,9 @@ where } impl Named for TokenInsert { - fn name(&self) -> &str { - "TokenInsert" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("TokenInsert"); + &NAME } } @@ -404,8 +405,9 @@ where } impl Named for TokenReplace { - fn name(&self) -> &str { - "TokenReplace" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("TokenReplace"); + &NAME } } @@ -588,8 +590,9 @@ where } impl Named for I2SRandReplace { - fn name(&self) -> &str { - "I2SRandReplace" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("I2SRandReplace"); + &NAME } } @@ -1673,8 +1676,9 @@ where } impl Named for AFLppRedQueen { - fn name(&self) -> &str { - "AFLppRedQueen" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("AFLppRedQueen"); + &NAME } } diff --git a/libafl/src/mutators/tuneable.rs b/libafl/src/mutators/tuneable.rs index 524e007902..c5c63fbda3 100644 --- a/libafl/src/mutators/tuneable.rs +++ b/libafl/src/mutators/tuneable.rs @@ -2,7 +2,7 @@ //! Instead of a random mutator for a random amount of iterations, we can run //! a specific mutator for a specified amount of iterations -use alloc::{string::String, vec::Vec}; +use alloc::{borrow::Cow, vec::Vec}; use core::{ fmt::{self, Debug}, marker::PhantomData, @@ -85,7 +85,7 @@ where MT: MutatorsTuple, S: HasRand, { - name: String, + name: Cow<'static, str>, mutations: MT, max_stack_pow: u64, phantom: PhantomData<(I, S)>, @@ -140,7 +140,7 @@ where MT: MutatorsTuple, S: HasRand, { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } @@ -238,7 +238,7 @@ where state.add_metadata(TuneableScheduledMutatorMetadata::default()); } TuneableScheduledMutator { - name: format!("TuneableMutator[{}]", mutations.names().join(", ")), + name: Cow::from(format!("TuneableMutator[{}]", mutations.names().join(", "))), mutations, max_stack_pow: 7, phantom: PhantomData, diff --git a/libafl/src/observers/cmp.rs b/libafl/src/observers/cmp.rs index 7483af0582..294a04e5be 100644 --- a/libafl/src/observers/cmp.rs +++ b/libafl/src/observers/cmp.rs @@ -1,14 +1,11 @@ //! The `CmpObserver` provides access to the logged values of CMP instructions -use alloc::{ - string::{String, ToString}, - vec::Vec, -}; +use alloc::{borrow::Cow, vec::Vec}; use core::{fmt::Debug, marker::PhantomData}; use c2rust_bitfields::BitfieldStruct; use hashbrown::HashMap; -use libafl_bolts::{ownedref::OwnedRefMut, serdeany::SerdeAny, AsMutSlice, AsSlice, Named}; +use libafl_bolts::{ownedref::OwnedRefMut, serdeany::SerdeAny, AsSlice, AsSliceMut, Named}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use crate::{executors::ExitKind, inputs::UsesInput, observers::Observer, Error, HasMetadata}; @@ -95,12 +92,12 @@ impl AsSlice for CmpValuesMetadata { } } -impl AsMutSlice for CmpValuesMetadata { +impl AsSliceMut for CmpValuesMetadata { type Entry = CmpValues; /// Convert to a slice #[must_use] - fn as_mut_slice(&mut self) -> &mut [CmpValues] { - self.list.as_mut_slice() + fn as_slice_mut(&mut self) -> &mut [CmpValues] { + self.list.as_slice_mut() } } @@ -250,7 +247,7 @@ where { cmp_map: OwnedRefMut<'a, CM>, size: Option>, - name: String, + name: Cow<'static, str>, add_meta: bool, data: M::Data, phantom: PhantomData, @@ -313,7 +310,7 @@ where S: UsesInput + HasMetadata, M: CmpObserverMetadata<'a, CM>, { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } @@ -328,7 +325,7 @@ where #[must_use] pub fn new(name: &'static str, map: OwnedRefMut<'a, CM>, add_meta: bool) -> Self { Self { - name: name.to_string(), + name: Cow::from(name), size: None, cmp_map: map, add_meta, @@ -347,7 +344,7 @@ where data: M::Data, ) -> Self { Self { - name: name.to_string(), + name: Cow::from(name), size: None, cmp_map, add_meta, @@ -365,7 +362,7 @@ where size: OwnedRefMut<'a, usize>, ) -> Self { Self { - name: name.to_string(), + name: Cow::from(name), size: Some(size), cmp_map, add_meta, @@ -385,7 +382,7 @@ where size: OwnedRefMut<'a, usize>, ) -> Self { Self { - name: name.to_string(), + name: Cow::from(name), size: Some(size), cmp_map, add_meta, diff --git a/libafl/src/observers/concolic/observer.rs b/libafl/src/observers/concolic/observer.rs index c84da0651f..a3e47ed1d3 100644 --- a/libafl/src/observers/concolic/observer.rs +++ b/libafl/src/observers/concolic/observer.rs @@ -1,4 +1,4 @@ -use alloc::string::String; +use alloc::borrow::Cow; use libafl_bolts::Named; use serde::{Deserialize, Serialize}; @@ -16,7 +16,7 @@ use crate::{ pub struct ConcolicObserver<'map> { #[serde(skip)] map: &'map [u8], - name: String, + name: Cow<'static, str>, } impl<'map, S> Observer for ConcolicObserver<'map> where S: UsesInput {} @@ -32,7 +32,7 @@ impl<'map> ConcolicObserver<'map> { } impl<'map> Named for ConcolicObserver<'map> { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } @@ -40,7 +40,10 @@ impl<'map> Named for ConcolicObserver<'map> { impl<'map> ConcolicObserver<'map> { /// Creates a new [`ConcolicObserver`] with the given name and memory buffer. #[must_use] - pub fn new(name: String, map: &'map [u8]) -> Self { - Self { map, name } + pub fn new(name: &'static str, map: &'map [u8]) -> Self { + Self { + map, + name: Cow::from(name), + } } } diff --git a/libafl/src/observers/list.rs b/libafl/src/observers/list.rs index 8ce3b08c2f..84fc2caeb3 100644 --- a/libafl/src/observers/list.rs +++ b/libafl/src/observers/list.rs @@ -1,7 +1,4 @@ -use alloc::{ - string::{String, ToString}, - vec::Vec, -}; +use alloc::{borrow::Cow, vec::Vec}; use core::fmt::Debug; use libafl_bolts::{ownedref::OwnedMutPtr, Error, Named}; @@ -17,7 +14,7 @@ pub struct ListObserver where T: Debug + Serialize, { - name: String, + name: Cow<'static, str>, /// The list list: OwnedMutPtr>, } @@ -34,7 +31,7 @@ where #[must_use] pub fn new(name: &'static str, list: OwnedMutPtr>) -> Self { Self { - name: name.to_string(), + name: Cow::from(name), list, } } @@ -67,7 +64,7 @@ impl Named for ListObserver where T: Debug + Serialize + serde::de::DeserializeOwned, { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } diff --git a/libafl/src/observers/map.rs b/libafl/src/observers/map.rs index 45cd46be53..aceb48d622 100644 --- a/libafl/src/observers/map.rs +++ b/libafl/src/observers/map.rs @@ -1,9 +1,6 @@ //! The `MapObserver` provides access a map, usually injected into the target -use alloc::{ - string::{String, ToString}, - vec::Vec, -}; +use alloc::{borrow::Cow, vec::Vec}; use core::{ fmt::Debug, hash::{Hash, Hasher}, @@ -16,7 +13,7 @@ use core::{ use ahash::RandomState; use libafl_bolts::{ ownedref::{OwnedMutPtr, OwnedMutSlice}, - AsIter, AsIterMut, AsMutSlice, AsSlice, HasLen, Named, Truncate, + AsIter, AsIterMut, AsSlice, AsSliceMut, HasLen, Named, Truncate, }; use meminterval::IntervalTree; use num_traits::Bounded; @@ -181,7 +178,7 @@ impl Named for ExplicitTracking &str { + fn name(&self) -> &Cow<'static, str> { self.0.name() } } @@ -532,7 +529,7 @@ where { map: OwnedMutSlice<'a, T>, initial: T, - name: String, + name: Cow<'static, str>, } impl<'a, S, T> Observer for StdMapObserver<'a, T, false> @@ -573,8 +570,8 @@ where T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned, { #[inline] - fn name(&self) -> &str { - self.name.as_str() + fn name(&self) -> &Cow<'static, str> { + &self.name } } @@ -626,7 +623,7 @@ where fn as_iter_mut(&'it mut self) -> Self::IntoIter { let cnt = self.usable_count(); - self.as_mut_slice()[..cnt].iter_mut() + self.as_slice_mut()[..cnt].iter_mut() } } @@ -669,7 +666,7 @@ where fn into_iter(self) -> Self::IntoIter { let cnt = self.usable_count(); - self.as_mut_slice()[..cnt].iter_mut() + self.as_slice_mut()[..cnt].iter_mut() } } @@ -753,7 +750,7 @@ where #[inline] fn get_mut(&mut self, idx: usize) -> &mut T { - &mut self.as_mut_slice()[idx] + &mut self.as_slice_mut()[idx] } /// Count the set bytes in the map @@ -795,7 +792,7 @@ where // Normal memset, see https://rust.godbolt.org/z/Trs5hv let initial = self.initial(); let cnt = self.usable_count(); - let map = self.as_mut_slice(); + let map = self.as_slice_mut(); for x in &mut map[0..cnt] { *x = initial; } @@ -844,15 +841,15 @@ where } } -impl<'a, T, const DIFFERENTIAL: bool> AsMutSlice for StdMapObserver<'a, T, DIFFERENTIAL> +impl<'a, T, const DIFFERENTIAL: bool> AsSliceMut for StdMapObserver<'a, T, DIFFERENTIAL> where T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, { type Entry = T; #[must_use] #[inline] - fn as_mut_slice(&mut self) -> &mut [T] { - self.map.as_mut_slice() + fn as_slice_mut(&mut self) -> &mut [T] { + self.map.as_slice_mut() } } @@ -868,7 +865,7 @@ where #[must_use] unsafe fn maybe_differential(name: S, map: &'a mut [T]) -> Self where - S: Into, + S: Into>, { let len = map.len(); let ptr = map.as_mut_ptr(); @@ -879,7 +876,7 @@ where #[must_use] fn maybe_differential_from_mut_slice(name: S, map: OwnedMutSlice<'a, T>) -> Self where - S: Into, + S: Into>, { StdMapObserver { name: name.into(), @@ -892,7 +889,7 @@ where #[must_use] fn maybe_differential_owned(name: S, map: Vec) -> Self where - S: Into, + S: Into>, { Self { map: OwnedMutSlice::from(map), @@ -908,7 +905,7 @@ where #[must_use] fn maybe_differential_from_ownedref(name: S, map: OwnedMutSlice<'a, T>) -> Self where - S: Into, + S: Into>, { Self { map, @@ -923,7 +920,7 @@ where /// Will dereference the `map_ptr` with up to len elements. unsafe fn maybe_differential_from_mut_ptr(name: S, map_ptr: *mut T, len: usize) -> Self where - S: Into, + S: Into>, { Self::maybe_differential_from_mut_slice( name, @@ -959,7 +956,7 @@ where #[must_use] pub unsafe fn new(name: S, map: &'a mut [T]) -> Self where - S: Into, + S: Into>, { Self::maybe_differential(name, map) } @@ -967,7 +964,7 @@ where /// Creates a new [`MapObserver`] from an [`OwnedMutSlice`] pub fn from_mut_slice(name: S, map: OwnedMutSlice<'a, T>) -> Self where - S: Into, + S: Into>, { Self::maybe_differential_from_mut_slice(name, map) } @@ -976,7 +973,7 @@ where #[must_use] pub fn owned(name: S, map: Vec) -> Self where - S: Into, + S: Into>, { Self::maybe_differential_owned(name, map) } @@ -988,7 +985,7 @@ where #[must_use] pub fn from_ownedref(name: S, map: OwnedMutSlice<'a, T>) -> Self where - S: Into, + S: Into>, { Self::maybe_differential_from_ownedref(name, map) } @@ -999,7 +996,7 @@ where /// Will dereference the `map_ptr` with up to len elements. pub unsafe fn from_mut_ptr(name: S, map_ptr: *mut T, len: usize) -> Self where - S: Into, + S: Into>, { Self::maybe_differential_from_mut_ptr(name, map_ptr, len) } @@ -1017,7 +1014,7 @@ where #[must_use] pub unsafe fn differential(name: S, map: &'a mut [T]) -> Self where - S: Into, + S: Into>, { Self::maybe_differential(name, map) } @@ -1026,7 +1023,7 @@ where #[must_use] pub fn differential_owned(name: S, map: Vec) -> Self where - S: Into, + S: Into>, { Self::maybe_differential_owned(name, map) } @@ -1038,7 +1035,7 @@ where #[must_use] pub fn differential_from_ownedref(name: S, map: OwnedMutSlice<'a, T>) -> Self where - S: Into, + S: Into>, { Self::maybe_differential_from_ownedref(name, map) } @@ -1049,7 +1046,7 @@ where /// Will dereference the `map_ptr` with up to len elements. pub unsafe fn differential_from_mut_ptr(name: S, map_ptr: *mut T, len: usize) -> Self where - S: Into, + S: Into>, { Self::maybe_differential_from_mut_ptr(name, map_ptr, len) } @@ -1082,7 +1079,7 @@ where { map: OwnedMutSlice<'a, T>, initial: T, - name: String, + name: Cow<'static, str>, } impl<'a, S, T, const N: usize> Observer for ConstMapObserver<'a, T, N> @@ -1102,8 +1099,8 @@ where T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned, { #[inline] - fn name(&self) -> &str { - self.name.as_str() + fn name(&self) -> &Cow<'static, str> { + &self.name } } @@ -1155,7 +1152,7 @@ where fn as_iter_mut(&'it mut self) -> Self::IntoIter { let cnt = self.usable_count(); - self.as_mut_slice()[..cnt].iter_mut() + self.as_slice_mut()[..cnt].iter_mut() } } @@ -1197,7 +1194,7 @@ where fn into_iter(self) -> Self::IntoIter { let cnt = self.usable_count(); - self.as_mut_slice()[..cnt].iter_mut() + self.as_slice_mut()[..cnt].iter_mut() } } @@ -1285,7 +1282,7 @@ where #[inline] fn get_mut(&mut self, idx: usize) -> &mut T { - &mut self.as_mut_slice()[idx] + &mut self.as_slice_mut()[idx] } /// Count the set bytes in the map @@ -1317,7 +1314,7 @@ where // Normal memset, see https://rust.godbolt.org/z/Trs5hv let initial = self.initial(); let cnt = self.usable_count(); - let map = self.as_mut_slice(); + let map = self.as_slice_mut(); for x in &mut map[0..cnt] { *x = initial; } @@ -1354,14 +1351,14 @@ where } } -impl<'a, T, const N: usize> AsMutSlice for ConstMapObserver<'a, T, N> +impl<'a, T, const N: usize> AsSliceMut for ConstMapObserver<'a, T, N> where T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, { type Entry = T; #[inline] - fn as_mut_slice(&mut self) -> &mut [T] { - self.map.as_mut_slice() + fn as_slice_mut(&mut self) -> &mut [T] { + self.map.as_slice_mut() } } @@ -1379,7 +1376,7 @@ where assert!(map.len() >= N); Self { map: OwnedMutSlice::from(map), - name: name.to_string(), + name: Cow::from(name), initial: T::default(), } } @@ -1391,7 +1388,7 @@ where let initial = if map.is_empty() { T::default() } else { map[0] }; Self { map: OwnedMutSlice::from(map), - name: name.to_string(), + name: Cow::from(name), initial, } } @@ -1403,7 +1400,7 @@ where pub unsafe fn from_mut_ptr(name: &'static str, map_ptr: *mut T) -> Self { ConstMapObserver { map: OwnedMutSlice::from_raw_parts_mut(map_ptr, N), - name: name.to_string(), + name: Cow::from(name), initial: T::default(), } } @@ -1420,7 +1417,7 @@ where map: OwnedMutSlice<'a, T>, size: OwnedMutPtr, initial: T, - name: String, + name: Cow<'static, str>, } impl<'a, S, T> Observer for VariableMapObserver<'a, T> @@ -1447,8 +1444,8 @@ where T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Bounded + PartialEq, { #[inline] - fn name(&self) -> &str { - self.name.as_str() + fn name(&self) -> &Cow<'static, str> { + &self.name } } @@ -1504,7 +1501,7 @@ where fn as_iter_mut(&'it mut self) -> Self::IntoIter { let cnt = self.usable_count(); - self.as_mut_slice()[..cnt].iter_mut() + self.as_slice_mut()[..cnt].iter_mut() } } @@ -1550,7 +1547,7 @@ where fn into_iter(self) -> Self::IntoIter { let cnt = self.usable_count(); - self.as_mut_slice()[..cnt].iter_mut() + self.as_slice_mut()[..cnt].iter_mut() } } @@ -1647,7 +1644,7 @@ where } fn get_mut(&mut self, idx: usize) -> &mut T { - &mut self.map.as_mut_slice()[idx] + &mut self.map.as_slice_mut()[idx] } /// Count the set bytes in the map @@ -1675,7 +1672,7 @@ where // Normal memset, see https://rust.godbolt.org/z/Trs5hv let initial = self.initial(); let cnt = self.usable_count(); - let map = self.as_mut_slice(); + let map = self.as_slice_mut(); for x in &mut map[0..cnt] { *x = initial; } @@ -1722,7 +1719,7 @@ where } } -impl<'a, T> AsMutSlice for VariableMapObserver<'a, T> +impl<'a, T> AsSliceMut for VariableMapObserver<'a, T> where T: 'static + Default @@ -1736,9 +1733,9 @@ where { type Entry = T; #[inline] - fn as_mut_slice(&mut self) -> &mut [T] { + fn as_slice_mut(&mut self) -> &mut [T] { let cnt = self.usable_count(); - &mut self.map.as_mut_slice()[..cnt] + &mut self.map.as_slice_mut()[..cnt] } } @@ -1798,7 +1795,7 @@ where impl Observer for HitcountsMapObserver where - M: MapObserver + Observer + AsMutSlice, + M: MapObserver + Observer + AsSliceMut, S: UsesInput, { #[inline] @@ -1814,7 +1811,7 @@ where input: &S::Input, exit_kind: &ExitKind, ) -> Result<(), Error> { - let map = self.as_mut_slice(); + let map = self.as_slice_mut(); let mut len = map.len(); let align_offset = map.as_ptr().align_offset(size_of::()); @@ -1861,7 +1858,7 @@ where M: Named + Serialize + serde::de::DeserializeOwned, { #[inline] - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { self.base.name() } } @@ -1964,14 +1961,14 @@ where } } -impl AsMutSlice for HitcountsMapObserver +impl AsSliceMut for HitcountsMapObserver where - M: MapObserver + AsMutSlice, + M: MapObserver + AsSliceMut, { - type Entry = ::Entry; + type Entry = ::Entry; #[inline] - fn as_mut_slice(&mut self) -> &mut [Self::Entry] { - self.base.as_mut_slice() + fn as_slice_mut(&mut self) -> &mut [Self::Entry] { + self.base.as_slice_mut() } } @@ -2063,7 +2060,7 @@ where M: DifferentialObserver + MapObserver + Serialize - + AsMutSlice, + + AsSliceMut, OTA: ObserversTuple, OTB: ObserversTuple, S: UsesInput, @@ -2129,7 +2126,7 @@ where M: Named + Serialize + serde::de::DeserializeOwned, { #[inline] - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { self.base.name() } } @@ -2235,14 +2232,14 @@ where } } -impl AsMutSlice for HitcountsIterableMapObserver +impl AsSliceMut for HitcountsIterableMapObserver where - M: MapObserver + AsMutSlice, + M: MapObserver + AsSliceMut, { - type Entry = ::Entry; + type Entry = ::Entry; #[inline] - fn as_mut_slice(&mut self) -> &mut [Self::Entry] { - self.base.as_mut_slice() + fn as_slice_mut(&mut self) -> &mut [Self::Entry] { + self.base.as_slice_mut() } } @@ -2366,7 +2363,7 @@ where intervals: IntervalTree, len: usize, initial: T, - name: String, + name: Cow<'static, str>, iter_idx: usize, } @@ -2396,8 +2393,8 @@ where T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug, { #[inline] - fn name(&self) -> &str { - self.name.as_str() + fn name(&self) -> &Cow<'static, str> { + &self.name } } @@ -2472,7 +2469,7 @@ where let elem = self.intervals.query(idx..=idx).next().unwrap(); let i = *elem.value; let j = idx - elem.interval.start; - &mut self.maps[i].as_mut_slice()[j] + &mut self.maps[i].as_slice_mut()[j] } #[inline] @@ -2501,7 +2498,7 @@ where fn reset_map(&mut self) -> Result<(), Error> { let initial = self.initial(); for map in &mut self.maps { - for x in map.as_mut_slice() { + for x in map.as_slice_mut() { *x = initial; } } @@ -2553,7 +2550,7 @@ where maps, intervals, len: idx, - name: name.to_string(), + name: Cow::from(name), initial: T::default(), iter_idx: 0, } @@ -2601,7 +2598,7 @@ where maps, intervals, len: idx, - name: name.to_string(), + name: Cow::from(name), initial: T::default(), iter_idx: 0, } @@ -2695,7 +2692,7 @@ where { map: Vec, initial: T, - name: String, + name: Cow<'static, str>, } impl Observer for OwnedMapObserver @@ -2715,8 +2712,8 @@ where T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned, { #[inline] - fn name(&self) -> &str { - self.name.as_str() + fn name(&self) -> &Cow<'static, str> { + &self.name } } @@ -2750,7 +2747,7 @@ where type IntoIter = IterMut<'it, T>; fn as_iter_mut(&'it mut self) -> Self::IntoIter { - self.as_mut_slice().iter_mut() + self.as_slice_mut().iter_mut() } } @@ -2774,7 +2771,7 @@ where type IntoIter = IterMut<'it, T>; fn into_iter(self) -> Self::IntoIter { - self.as_mut_slice().iter_mut() + self.as_slice_mut().iter_mut() } } @@ -2842,7 +2839,7 @@ where #[inline] fn get_mut(&mut self, idx: usize) -> &mut T { - &mut self.as_mut_slice()[idx] + &mut self.as_slice_mut()[idx] } /// Count the set bytes in the map @@ -2880,7 +2877,7 @@ where // Normal memset, see https://rust.godbolt.org/z/Trs5hv let initial = self.initial(); let cnt = self.usable_count(); - let map = self.as_mut_slice(); + let map = self.as_slice_mut(); for x in &mut map[0..cnt] { *x = initial; } @@ -2916,15 +2913,15 @@ where } } -impl AsMutSlice for OwnedMapObserver +impl AsSliceMut for OwnedMapObserver where T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug, { type Entry = T; #[must_use] #[inline] - fn as_mut_slice(&mut self) -> &mut [T] { - self.map.as_mut_slice() + fn as_slice_mut(&mut self) -> &mut [T] { + self.map.as_slice_mut() } } @@ -2938,7 +2935,7 @@ where let initial = if map.is_empty() { T::default() } else { map[0] }; Self { map, - name: name.to_string(), + name: Cow::from(name), initial, } } diff --git a/libafl/src/observers/mod.rs b/libafl/src/observers/mod.rs index edcf4c903d..63b3f2801c 100644 --- a/libafl/src/observers/mod.rs +++ b/libafl/src/observers/mod.rs @@ -1,6 +1,9 @@ //! Observers give insights about runs of a target, such as coverage, timing, stack depth, and more. pub mod map; + +use alloc::borrow::Cow; + pub use map::*; pub mod cmp; @@ -22,7 +25,6 @@ pub mod value; /// List observer pub mod list; -use alloc::string::{String, ToString}; use core::{fmt::Debug, time::Duration}; #[cfg(feature = "std")] use std::time::Instant; @@ -410,7 +412,7 @@ where /// A simple observer, just overlooking the runtime of the target. #[derive(Serialize, Deserialize, Debug, Clone)] pub struct TimeObserver { - name: String, + name: Cow<'static, str>, #[cfg(feature = "std")] #[serde(with = "instant_serializer")] @@ -453,7 +455,7 @@ impl TimeObserver { #[must_use] pub fn new(name: &'static str) -> Self { Self { - name: name.to_string(), + name: Cow::from(name), #[cfg(feature = "std")] start_time: Instant::now(), @@ -513,7 +515,7 @@ where } impl Named for TimeObserver { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } diff --git a/libafl/src/observers/stacktrace.rs b/libafl/src/observers/stacktrace.rs index b1d2ee1719..9f082afa43 100644 --- a/libafl/src/observers/stacktrace.rs +++ b/libafl/src/observers/stacktrace.rs @@ -1,13 +1,11 @@ //! the ``StacktraceObserver`` looks up the stacktrace on the execution thread and computes a hash for it for dedupe -use alloc::{ - string::{String, ToString}, - vec::Vec, -}; +use alloc::{borrow::Cow, string::String, vec::Vec}; #[cfg(feature = "casr")] use std::{ collections::hash_map::DefaultHasher, hash::{Hash, Hasher}, + string::ToString, }; use std::{ fmt::Debug, @@ -83,10 +81,10 @@ pub fn collect_backtrace() -> u64 { if symbols.len() > 1 { let symbol = &symbols[0]; if let Some(name) = symbol.name() { - strace_entry.function = name.as_str().unwrap_or("").to_string(); + strace_entry.function = name.as_str().map_or_else(String::new, str::to_string); } if let Some(file) = symbol.filename() { - strace_entry.debug.file = file.to_str().unwrap_or("").to_string(); + strace_entry.debug.file = file.to_string_lossy().to_string(); } strace_entry.debug.line = u64::from(symbol.lineno().unwrap_or(0)); strace_entry.debug.column = u64::from(symbol.colno().unwrap_or(0)); @@ -116,7 +114,7 @@ pub enum HarnessType { #[allow(clippy::unsafe_derive_deserialize)] #[derive(Serialize, Deserialize, Debug)] pub struct BacktraceObserver<'a> { - observer_name: String, + observer_name: Cow<'static, str>, hash: OwnedRefMut<'a, Option>, harness_type: HarnessType, } @@ -125,13 +123,16 @@ impl<'a> BacktraceObserver<'a> { #[cfg(not(feature = "casr"))] /// Creates a new [`BacktraceObserver`] with the given name. #[must_use] - pub fn new( - observer_name: &str, + pub fn new( + observer_name: S, backtrace_hash: OwnedRefMut<'a, Option>, harness_type: HarnessType, - ) -> Self { + ) -> Self + where + S: Into>, + { Self { - observer_name: observer_name.to_string(), + observer_name: observer_name.into(), hash: backtrace_hash, harness_type, } @@ -140,14 +141,17 @@ impl<'a> BacktraceObserver<'a> { #[cfg(feature = "casr")] /// Creates a new [`BacktraceObserver`] with the given name. #[must_use] - pub fn new( - observer_name: &str, + pub fn new( + observer_name: S, backtrace_hash: OwnedRefMut<'a, Option>, harness_type: HarnessType, - ) -> Self { + ) -> Self + where + S: Into>, + { init_ignored_frames!("rust", "cpp", "go"); Self { - observer_name: observer_name.to_string(), + observer_name: observer_name.into(), hash: backtrace_hash, harness_type, } @@ -155,7 +159,10 @@ impl<'a> BacktraceObserver<'a> { /// Creates a new [`BacktraceObserver`] with the given name, owning a new `backtrace_hash` variable. #[must_use] - pub fn owned(observer_name: &str, harness_type: HarnessType) -> Self { + pub fn owned(observer_name: S, harness_type: HarnessType) -> Self + where + S: Into>, + { Self::new(observer_name, OwnedRefMut::owned(None), harness_type) } @@ -227,7 +234,7 @@ where } impl<'a> Named for BacktraceObserver<'a> { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.observer_name } } @@ -263,7 +270,7 @@ pub fn get_asan_runtime_flags() -> String { /// An observer looking at the backtrace of target command using ASAN output #[derive(Serialize, Deserialize, Debug, Clone)] pub struct AsanBacktraceObserver { - observer_name: String, + observer_name: Cow<'static, str>, hash: Option, } @@ -271,9 +278,12 @@ impl AsanBacktraceObserver { #[cfg(not(feature = "casr"))] /// Creates a new [`BacktraceObserver`] with the given name. #[must_use] - pub fn new(observer_name: &str) -> Self { + pub fn new(observer_name: S) -> Self + where + S: Into>, + { Self { - observer_name: observer_name.to_string(), + observer_name: observer_name.into(), hash: None, } } @@ -281,10 +291,13 @@ impl AsanBacktraceObserver { #[cfg(feature = "casr")] /// Creates a new [`BacktraceObserver`] with the given name. #[must_use] - pub fn new(observer_name: &str) -> Self { + pub fn new(observer_name: S) -> Self + where + S: Into>, + { init_ignored_frames!("rust", "cpp", "go"); Self { - observer_name: observer_name.to_string(), + observer_name: observer_name.into(), hash: None, } } @@ -390,7 +403,7 @@ where } impl Named for AsanBacktraceObserver { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.observer_name } } diff --git a/libafl/src/observers/stdio.rs b/libafl/src/observers/stdio.rs index 5e0ddc98ad..bc921c95f2 100644 --- a/libafl/src/observers/stdio.rs +++ b/libafl/src/observers/stdio.rs @@ -2,7 +2,7 @@ //! The executor must explicitly support these observers. //! For example, they are supported on the [`crate::executors::CommandExecutor`]. -use alloc::string::String; +use alloc::borrow::Cow; use std::vec::Vec; use libafl_bolts::Named; @@ -15,7 +15,7 @@ use crate::{inputs::UsesInput, observers::Observer}; #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct StdOutObserver { /// The name of the observer. - pub name: String, + pub name: Cow<'static, str>, /// The stdout of the target during its last execution. pub stdout: Option>, } @@ -24,8 +24,11 @@ pub struct StdOutObserver { impl StdOutObserver { /// Create a new [`StdOutObserver`] with the given name. #[must_use] - pub fn new(name: String) -> Self { - Self { name, stdout: None } + pub fn new(name: &'static str) -> Self { + Self { + name: Cow::from(name), + stdout: None, + } } } @@ -45,7 +48,7 @@ where } impl Named for StdOutObserver { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } @@ -55,7 +58,7 @@ impl Named for StdOutObserver { #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct StdErrObserver { /// The name of the observer. - pub name: String, + pub name: Cow<'static, str>, /// The stderr of the target during its last execution. pub stderr: Option>, } @@ -64,8 +67,11 @@ pub struct StdErrObserver { impl StdErrObserver { /// Create a new [`StdErrObserver`] with the given name. #[must_use] - pub fn new(name: String) -> Self { - Self { name, stderr: None } + pub fn new(name: &'static str) -> Self { + Self { + name: Cow::from(name), + stderr: None, + } } } @@ -85,7 +91,7 @@ where } impl Named for StdErrObserver { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } diff --git a/libafl/src/observers/value.rs b/libafl/src/observers/value.rs index d8610486c2..d6c84f8d12 100644 --- a/libafl/src/observers/value.rs +++ b/libafl/src/observers/value.rs @@ -1,9 +1,6 @@ //! A simple observer with a single value. -use alloc::{ - boxed::Box, - string::{String, ToString}, -}; +use alloc::{borrow::Cow, boxed::Box}; use core::{ cell::{Ref, RefCell}, fmt::Debug, @@ -29,7 +26,7 @@ where T: Debug + Serialize, { /// The name of this observer. - name: String, + name: Cow<'static, str>, /// The value. pub value: OwnedRef<'a, T>, } @@ -42,7 +39,7 @@ where #[must_use] pub fn new(name: &'static str, value: OwnedRef<'a, T>) -> Self { Self { - name: name.to_string(), + name: Cow::from(name), value, } } @@ -87,7 +84,7 @@ impl<'a, T> Named for ValueObserver<'a, T> where T: Debug + Serialize + serde::de::DeserializeOwned, { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } @@ -109,7 +106,7 @@ where T: Debug + Serialize, { /// The name of this observer. - name: String, + name: Cow<'static, str>, /// The value. pub value: OwnedRef<'a, RefCell>, } @@ -122,7 +119,7 @@ where #[must_use] pub fn new(name: &'static str, value: OwnedRef<'a, RefCell>) -> Self { Self { - name: name.to_string(), + name: Cow::from(name), value, } } @@ -170,7 +167,7 @@ impl<'a, T> Named for RefCellValueObserver<'a, T> where T: Debug + Serialize + serde::de::DeserializeOwned, { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } diff --git a/libafl/src/schedulers/accounting.rs b/libafl/src/schedulers/accounting.rs index 157394f5b1..bae451ce07 100644 --- a/libafl/src/schedulers/accounting.rs +++ b/libafl/src/schedulers/accounting.rs @@ -4,7 +4,7 @@ use alloc::vec::Vec; use core::fmt::Debug; use hashbrown::HashMap; -use libafl_bolts::{rands::Rand, AsMutSlice, AsSlice, HasLen, HasRefCnt}; +use libafl_bolts::{rands::Rand, AsSlice, AsSliceMut, HasLen, HasRefCnt}; use serde::{Deserialize, Serialize}; use crate::{ @@ -42,12 +42,12 @@ impl AsSlice for AccountingIndexesMetadata { self.list.as_slice() } } -impl AsMutSlice for AccountingIndexesMetadata { +impl AsSliceMut for AccountingIndexesMetadata { type Entry = usize; /// Convert to a slice - fn as_mut_slice(&mut self) -> &mut [usize] { - self.list.as_mut_slice() + fn as_slice_mut(&mut self) -> &mut [usize] { + self.list.as_slice_mut() } } diff --git a/libafl/src/stages/calibrate.rs b/libafl/src/stages/calibrate.rs index 2f4b4c3c38..c8ec6fcc1f 100644 --- a/libafl/src/stages/calibrate.rs +++ b/libafl/src/stages/calibrate.rs @@ -1,6 +1,7 @@ //! The calibration stage. The fuzzer measures the average exec time and the bitmap size. use alloc::{ + borrow::Cow, string::{String, ToString}, vec::Vec, }; @@ -311,7 +312,7 @@ where mgr.fire( state, Event::UpdateUserStats { - name: "stability".to_string(), + name: Cow::from("stability"), value: UserStats::new( UserStatsValue::Ratio( (map_len - unstable_entries) as u64, diff --git a/libafl/src/stages/colorization.rs b/libafl/src/stages/colorization.rs index f70f5906be..0042c5913f 100644 --- a/libafl/src/stages/colorization.rs +++ b/libafl/src/stages/colorization.rs @@ -1,9 +1,5 @@ //! The colorization stage from `colorization()` in afl++ -use alloc::{ - collections::binary_heap::BinaryHeap, - string::{String, ToString}, - vec::Vec, -}; +use alloc::{borrow::Cow, collections::binary_heap::BinaryHeap, string::ToString, vec::Vec}; use core::{cmp::Ordering, fmt::Debug, marker::PhantomData, ops::Range}; use libafl_bolts::{rands::Rand, tuples::MatchName, Named}; @@ -55,7 +51,7 @@ impl Ord for Earlier { /// The mutational stage using power schedules #[derive(Clone, Debug)] pub struct ColorizationStage { - map_observer_name: String, + map_observer_name: Cow<'static, str>, #[allow(clippy::type_complexity)] phantom: PhantomData<(C, E, EM, O, E, Z)>, } @@ -71,7 +67,7 @@ impl Named for ColorizationStage where E: UsesState, { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.map_observer_name } } @@ -301,7 +297,7 @@ where /// Creates a new [`ColorizationStage`] pub fn new(map_observer: &C) -> Self { Self { - map_observer_name: map_observer.name().to_string(), + map_observer_name: map_observer.name().clone(), phantom: PhantomData, } } diff --git a/libafl/src/stages/concolic.rs b/libafl/src/stages/concolic.rs index 58c799963d..f2d3a1245e 100644 --- a/libafl/src/stages/concolic.rs +++ b/libafl/src/stages/concolic.rs @@ -2,7 +2,7 @@ //! and use the results for fuzzer input and mutations. //! -use alloc::string::String; +use alloc::{borrow::Cow, string::String}; #[cfg(feature = "concolic_mutation")] use alloc::{string::ToString, vec::Vec}; #[cfg(feature = "concolic_mutation")] @@ -47,8 +47,9 @@ where } impl Named for ConcolicTracingStage { - fn name(&self) -> &str { - "ConcolicTracingStage" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("ConcolicTracingStage"); + &NAME } } diff --git a/libafl/src/stages/generalization.rs b/libafl/src/stages/generalization.rs index f27d9ba3eb..67554e7b9c 100644 --- a/libafl/src/stages/generalization.rs +++ b/libafl/src/stages/generalization.rs @@ -1,6 +1,7 @@ //! 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, }; @@ -49,8 +50,9 @@ pub struct GeneralizationStage { } impl Named for GeneralizationStage { - fn name(&self) -> &str { - "GeneralizationStage" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("GeneralizationStage"); + &NAME } } diff --git a/libafl/src/stages/mod.rs b/libafl/src/stages/mod.rs index 8e3f90e986..033a512ed5 100644 --- a/libafl/src/stages/mod.rs +++ b/libafl/src/stages/mod.rs @@ -4,8 +4,8 @@ A well-known [`Stage`], for example, is the mutational stage, running multiple [ Other stages may enrich [`crate::corpus::Testcase`]s with metadata. */ -use alloc::{boxed::Box, vec::Vec}; -use core::{any, marker::PhantomData}; +use alloc::{borrow::Cow, boxed::Box, vec::Vec}; +use core::marker::PhantomData; pub use calibrate::CalibrationStage; pub use colorization::*; @@ -305,8 +305,9 @@ where CB: FnMut(&mut Z, &mut E, &mut E::State, &mut EM) -> Result<(), Error>, E: UsesState, { - fn name(&self) -> &str { - any::type_name::() + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed(""); + &NAME } } @@ -644,6 +645,7 @@ impl ExecutionCountRestartHelper { #[cfg(test)] pub mod test { + use alloc::borrow::Cow; use core::marker::PhantomData; use libafl_bolts::{impl_serdeany, Error, Named}; @@ -745,8 +747,9 @@ pub mod test { struct StageWithOneTry; impl Named for StageWithOneTry { - fn name(&self) -> &str { - "TestStage" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("TestStage"); + &NAME } } diff --git a/libafl/src/stages/mutational.rs b/libafl/src/stages/mutational.rs index 834f432ec9..ca9655ad8c 100644 --- a/libafl/src/stages/mutational.rs +++ b/libafl/src/stages/mutational.rs @@ -1,7 +1,8 @@ //| The [`MutationalStage`] is the default stage used during fuzzing. //! For the current input, it will perform a range of random mutations, and then run them in the executor. -use core::{any::type_name, marker::PhantomData}; +use alloc::borrow::Cow; +use core::marker::PhantomData; use libafl_bolts::{rands::Rand, Named}; @@ -313,8 +314,9 @@ where Z: Evaluator, Z::State: HasCorpus + HasRand, { - fn name(&self) -> &str { - type_name::() + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("MultiMutational"); + &NAME } } diff --git a/libafl/src/stages/stats.rs b/libafl/src/stages/stats.rs index 27266abb69..59ba9655cb 100644 --- a/libafl/src/stages/stats.rs +++ b/libafl/src/stages/stats.rs @@ -1,7 +1,7 @@ //! Stage to compute/report AFL stats #[cfg(feature = "std")] -use alloc::string::ToString; +use alloc::{borrow::Cow, string::ToString}; use core::{marker::PhantomData, time::Duration}; use libafl_bolts::current_time; @@ -109,9 +109,9 @@ where _manager.fire( state, Event::UpdateUserStats { - name: "AflStats".to_string(), + name: Cow::from("AflStats"), value: UserStats::new( - UserStatsValue::String(json.to_string()), + UserStatsValue::String(Cow::from(json.to_string())), AggregatorOps::None, ), phantom: PhantomData, diff --git a/libafl/src/stages/sync.rs b/libafl/src/stages/sync.rs index fcb9050baf..520365ba01 100644 --- a/libafl/src/stages/sync.rs +++ b/libafl/src/stages/sync.rs @@ -1,5 +1,6 @@ //! The [`SyncFromDiskStage`] is a stage that imports inputs from disk for e.g. sync with AFL +use alloc::borrow::Cow; use core::marker::PhantomData; use std::{ fs, @@ -63,8 +64,9 @@ impl Named for SyncFromDiskStage where E: UsesState, { - fn name(&self) -> &str { - self.sync_dir.to_str().unwrap() + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("SyncFromDiskStage"); + &NAME } } diff --git a/libafl/src/stages/tmin.rs b/libafl/src/stages/tmin.rs index c155cb2023..62fa4756e5 100644 --- a/libafl/src/stages/tmin.rs +++ b/libafl/src/stages/tmin.rs @@ -1,6 +1,6 @@ //! The [`TMinMutationalStage`] is a stage which will attempt to minimize corpus entries. -use alloc::string::{String, ToString}; +use alloc::borrow::Cow; use core::{borrow::BorrowMut, fmt::Debug, hash::Hash, marker::PhantomData}; use ahash::RandomState; @@ -349,33 +349,20 @@ where /// provided #[derive(Clone, Debug)] pub struct MapEqualityFeedback { - name: String, - obs_name: String, + name: Cow<'static, str>, + obs_name: Cow<'static, str>, orig_hash: u64, phantom: PhantomData<(M, S)>, } -impl MapEqualityFeedback { - /// Create a new map equality feedback -- can be used with feedback logic - #[must_use] - pub fn new(name: &str, obs_name: &str, orig_hash: u64) -> Self { - MapEqualityFeedback { - name: name.to_string(), - obs_name: obs_name.to_string(), - orig_hash, - phantom: PhantomData, - } - } -} - impl Named for MapEqualityFeedback { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } impl HasObserverName for MapEqualityFeedback { - fn observer_name(&self) -> &str { + fn observer_name(&self) -> &Cow<'static, str> { &self.obs_name } } @@ -407,7 +394,7 @@ where /// A feedback factory for ensuring that the maps for minimized inputs are the same #[derive(Debug, Clone)] pub struct MapEqualityFactory { - obs_name: String, + obs_name: Cow<'static, str>, phantom: PhantomData<(M, S)>, } @@ -418,14 +405,14 @@ where /// Creates a new map equality feedback for the given observer pub fn with_observer(obs: &M) -> Self { Self { - obs_name: obs.name().to_string(), + obs_name: obs.name().clone(), phantom: PhantomData, } } } impl HasObserverName for MapEqualityFactory { - fn observer_name(&self) -> &str { + fn observer_name(&self) -> &Cow<'static, str> { &self.obs_name } } @@ -441,7 +428,7 @@ where .match_name::(self.observer_name()) .expect("Should have been provided valid observer name."); MapEqualityFeedback { - name: "MapEq".to_string(), + name: Cow::from("MapEq"), obs_name: self.obs_name.clone(), orig_hash: obs.hash_simple(), phantom: PhantomData, diff --git a/libafl/src/stages/tracing.rs b/libafl/src/stages/tracing.rs index f00b8c43ec..0bc40360a1 100644 --- a/libafl/src/stages/tracing.rs +++ b/libafl/src/stages/tracing.rs @@ -1,5 +1,6 @@ //! The tracing stage can trace the target and enrich a testcase with metadata, for example for `CmpLog`. +use alloc::borrow::Cow; use core::{fmt::Debug, marker::PhantomData}; use libafl_bolts::Named; @@ -106,8 +107,9 @@ where } impl Named for TracingStage { - fn name(&self) -> &str { - "TracingStage" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("TracingStage"); + &NAME } } @@ -159,8 +161,9 @@ impl Named for ShadowTracingStage where E: UsesState, { - fn name(&self) -> &str { - "ShadowTracingStage" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("ShadowTracingStage"); + &NAME } } diff --git a/libafl_bolts/src/lib.rs b/libafl_bolts/src/lib.rs index 8b8cae2835..0d0ab670e1 100644 --- a/libafl_bolts/src/lib.rs +++ b/libafl_bolts/src/lib.rs @@ -164,7 +164,7 @@ pub mod bolts_prelude { #[cfg(all(unix, feature = "std"))] use alloc::boxed::Box; #[cfg(feature = "alloc")] -use alloc::vec::Vec; +use alloc::{borrow::Cow, vec::Vec}; #[cfg(all(not(feature = "xxh3"), feature = "alloc"))] use core::hash::BuildHasher; #[cfg(any(feature = "xxh3", feature = "alloc"))] @@ -231,9 +231,10 @@ use { pub const IP_LOCALHOST: &str = "127.0.0.1"; /// We need fixed names for many parts of this lib. +#[cfg(feature = "alloc")] pub trait Named { /// Provide the name of this element. - fn name(&self) -> &str; + fn name(&self) -> &Cow<'static, str>; } #[cfg(feature = "errors_backtrace")] @@ -681,11 +682,11 @@ pub trait AsSlice { } /// Can be converted to a mutable slice -pub trait AsMutSlice { +pub trait AsSliceMut { /// Type of the entries in this mut slice type Entry; /// Convert to a slice - fn as_mut_slice(&mut self) -> &mut [Self::Entry]; + fn as_slice_mut(&mut self) -> &mut [Self::Entry]; } #[cfg(feature = "alloc")] @@ -698,10 +699,10 @@ impl AsSlice for Vec { } #[cfg(feature = "alloc")] -impl AsMutSlice for Vec { +impl AsSliceMut for Vec { type Entry = T; - fn as_mut_slice(&mut self) -> &mut [Self::Entry] { + fn as_slice_mut(&mut self) -> &mut [Self::Entry] { self } } @@ -722,18 +723,18 @@ impl AsSlice for [T] { } } -impl AsMutSlice for &mut [T] { +impl AsSliceMut for &mut [T] { type Entry = T; - fn as_mut_slice(&mut self) -> &mut [Self::Entry] { + fn as_slice_mut(&mut self) -> &mut [Self::Entry] { self } } -impl AsMutSlice for [T] { +impl AsSliceMut for [T] { type Entry = T; - fn as_mut_slice(&mut self) -> &mut [Self::Entry] { + fn as_slice_mut(&mut self) -> &mut [Self::Entry] { self } } diff --git a/libafl_bolts/src/llmp.rs b/libafl_bolts/src/llmp.rs index 3cf6fce245..c769117b43 100644 --- a/libafl_bolts/src/llmp.rs +++ b/libafl_bolts/src/llmp.rs @@ -394,7 +394,7 @@ impl Listener { #[inline] #[allow(clippy::cast_ptr_alignment)] unsafe fn shmem2page_mut(afl_shmem: &mut SHM) -> *mut LlmpPage { - afl_shmem.as_mut_slice().as_mut_ptr() as *mut LlmpPage + afl_shmem.as_slice_mut().as_mut_ptr() as *mut LlmpPage } /// Get sharedmem from a page diff --git a/libafl_bolts/src/os/unix_shmem_server.rs b/libafl_bolts/src/os/unix_shmem_server.rs index 1d1dbd501f..07e887f189 100644 --- a/libafl_bolts/src/os/unix_shmem_server.rs +++ b/libafl_bolts/src/os/unix_shmem_server.rs @@ -40,7 +40,7 @@ use uds::{UnixListenerExt, UnixSocketAddr, UnixStreamExt}; use crate::{ shmem::{ShMem, ShMemDescription, ShMemId, ShMemProvider}, - AsMutSlice, AsSlice, Error, + AsSlice, AsSliceMut, Error, }; /// The default server name for our abstract shmem server @@ -102,13 +102,13 @@ where self.inner.as_slice() } } -impl AsMutSlice for ServedShMem +impl AsSliceMut for ServedShMem where SH: ShMem, { type Entry = u8; - fn as_mut_slice(&mut self) -> &mut [u8] { - self.inner.as_mut_slice() + fn as_slice_mut(&mut self) -> &mut [u8] { + self.inner.as_slice_mut() } } diff --git a/libafl_bolts/src/ownedref.rs b/libafl_bolts/src/ownedref.rs index 9bd14b85f2..27726f0263 100644 --- a/libafl_bolts/src/ownedref.rs +++ b/libafl_bolts/src/ownedref.rs @@ -10,7 +10,7 @@ use core::{clone::Clone, fmt::Debug, slice}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use crate::{shmem::ShMem, AsMutSlice, AsSlice, IntoOwned, Truncate}; +use crate::{shmem::ShMem, AsSlice, AsSliceMut, IntoOwned, Truncate}; /// Private part of the unsafe marker, making sure this cannot be initialized directly. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] @@ -562,7 +562,7 @@ impl<'a, 'it, T> IntoIterator for &'it mut OwnedMutSlice<'a, T> { type IntoIter = IterMut<'it, T>; fn into_iter(self) -> Self::IntoIter { - self.as_mut_slice().iter_mut() + self.as_slice_mut().iter_mut() } } @@ -651,17 +651,17 @@ impl<'a, T: Sized> AsSlice for OwnedMutSlice<'a, T> { } } } -impl<'a, T: Sized> AsMutSlice for OwnedMutSlice<'a, T> { +impl<'a, T: Sized> AsSliceMut for OwnedMutSlice<'a, T> { type Entry = T; /// Get the value as mut slice #[must_use] - fn as_mut_slice(&mut self) -> &mut [T] { + fn as_slice_mut(&mut self) -> &mut [T] { match &mut self.inner { OwnedMutSliceInner::RefRaw(rr, len, _) => unsafe { slice::from_raw_parts_mut(*rr, *len) }, OwnedMutSliceInner::Ref(r) => r, - OwnedMutSliceInner::Owned(v) => v.as_mut_slice(), + OwnedMutSliceInner::Owned(v) => v.as_slice_mut(), } } } diff --git a/libafl_bolts/src/shmem.rs b/libafl_bolts/src/shmem.rs index 268348403e..f46e27a765 100644 --- a/libafl_bolts/src/shmem.rs +++ b/libafl_bolts/src/shmem.rs @@ -31,7 +31,7 @@ pub use win32_shmem::{Win32ShMem, Win32ShMemProvider}; use crate::os::pipes::Pipe; #[cfg(all(feature = "std", unix, not(target_os = "haiku")))] pub use crate::os::unix_shmem_server::{ServedShMemProvider, ShMemService}; -use crate::{AsMutSlice, AsSlice, Error}; +use crate::{AsSlice, AsSliceMut, Error}; /// The standard sharedmem provider #[cfg(all(windows, feature = "std"))] @@ -192,7 +192,7 @@ impl Display for ShMemId { /// A [`ShMem`] is an interface to shared maps. /// They are the backbone of [`crate::llmp`] for inter-process communication. /// All you need for scaling on a new target is to implement this interface, as well as the respective [`ShMemProvider`]. -pub trait ShMem: Sized + Debug + Clone + AsSlice + AsMutSlice { +pub trait ShMem: Sized + Debug + Clone + AsSlice + AsSliceMut { /// Get the id of this shared memory mapping fn id(&self) -> ShMemId; @@ -218,7 +218,7 @@ pub trait ShMem: Sized + Debug + Clone + AsSlice + AsMutSlice(&mut self) -> Option<*mut T> { if self.len() >= mem::size_of::() { - Some(self.as_mut_slice().as_mut_ptr() as *mut T) + Some(self.as_slice_mut().as_mut_ptr() as *mut T) } else { None } @@ -357,13 +357,13 @@ where } #[cfg(feature = "alloc")] -impl AsMutSlice for RcShMem +impl AsSliceMut for RcShMem where T: ShMemProvider + Debug, { type Entry = u8; - fn as_mut_slice(&mut self) -> &mut [u8] { - self.internal.as_mut_slice() + fn as_slice_mut(&mut self) -> &mut [u8] { + self.internal.as_slice_mut() } } @@ -600,7 +600,7 @@ pub mod unix_shmem { use crate::{ rands::{Rand, RandomSeed, StdRand}, shmem::{ShMem, ShMemId, ShMemProvider}, - AsMutSlice, AsSlice, Error, + AsSlice, AsSliceMut, Error, }; // This is macOS's limit @@ -782,9 +782,9 @@ pub mod unix_shmem { } } - impl AsMutSlice for MmapShMem { + impl AsSliceMut for MmapShMem { type Entry = u8; - fn as_mut_slice(&mut self) -> &mut [u8] { + fn as_slice_mut(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self.map, self.map_size) } } } @@ -894,9 +894,9 @@ pub mod unix_shmem { } } - impl AsMutSlice for CommonUnixShMem { + impl AsSliceMut for CommonUnixShMem { type Entry = u8; - fn as_mut_slice(&mut self) -> &mut [u8] { + fn as_slice_mut(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self.map, self.map_size) } } } @@ -964,7 +964,7 @@ pub mod unix_shmem { use crate::{ shmem::{ShMem, ShMemId, ShMemProvider}, - AsMutSlice, AsSlice, Error, + AsSlice, AsSliceMut, Error, }; /// An ashmem based impl for linux/android @@ -1104,10 +1104,10 @@ pub mod unix_shmem { } } - impl AsMutSlice for AshmemShMem { + impl AsSliceMut for AshmemShMem { type Entry = u8; - fn as_mut_slice(&mut self) -> &mut [u8] { + fn as_slice_mut(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self.map, self.map_size) } } } @@ -1189,7 +1189,7 @@ pub mod win32_shmem { use crate::{ shmem::{ShMem, ShMemId, ShMemProvider}, - AsMutSlice, AsSlice, Error, + AsSlice, AsSliceMut, Error, }; const INVALID_HANDLE_VALUE: isize = -1; @@ -1303,9 +1303,9 @@ pub mod win32_shmem { unsafe { slice::from_raw_parts(self.map, self.map_size) } } } - impl AsMutSlice for Win32ShMem { + impl AsSliceMut for Win32ShMem { type Entry = u8; - fn as_mut_slice(&mut self) -> &mut [u8] { + fn as_slice_mut(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self.map, self.map_size) } } } @@ -1395,7 +1395,7 @@ impl ShMemCursor { /// Slice from the current location on this map to the end, mutable fn empty_slice_mut(&mut self) -> &mut [u8] { - &mut (self.inner.as_mut_slice()[self.pos..]) + &mut (self.inner.as_slice_mut()[self.pos..]) } } @@ -1470,7 +1470,7 @@ mod tests { use crate::{ shmem::{ShMemProvider, StdShMemProvider}, - AsMutSlice, AsSlice, + AsSlice, AsSliceMut, }; #[test] @@ -1479,7 +1479,7 @@ mod tests { fn test_shmem_service() { let mut provider = StdShMemProvider::new().unwrap(); let mut map = provider.new_shmem(1024).unwrap(); - map.as_mut_slice()[0] = 1; + map.as_slice_mut()[0] = 1; assert!(map.as_slice()[0] == 1); } } diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index a0c690d046..1e57899476 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -1,11 +1,12 @@ //! Compiletime lists/tuples used throughout the `LibAFL` universe #[cfg(feature = "alloc")] -use alloc::vec::Vec; +use alloc::{borrow::Cow, vec::Vec}; #[rustversion::not(nightly)] use core::any::type_name; use core::{ any::TypeId, + marker::PhantomData, mem::transmute, ptr::{addr_of, addr_of_mut}, }; @@ -14,7 +15,9 @@ pub use tuple_list::{tuple_list, tuple_list_type, TupleList}; #[cfg(any(feature = "xxh3", feature = "alloc"))] use crate::hash_std; -use crate::{HasLen, Named}; +use crate::HasLen; +#[cfg(feature = "alloc")] +use crate::Named; /// Returns if the type `T` is equal to `U` /// From @@ -407,31 +410,36 @@ where } } +#[cfg(feature = "alloc")] /// A named tuple pub trait NamedTuple: HasConstLen { /// Gets the name of this tuple - fn name(&self, index: usize) -> Option<&str>; + fn name(&self, index: usize) -> Option<&Cow<'static, str>>; } +#[cfg(feature = "alloc")] impl NamedTuple for () { - fn name(&self, _index: usize) -> Option<&str> { + fn name(&self, _index: usize) -> Option<&Cow<'static, str>> { None } } +#[cfg(feature = "alloc")] impl Named for () { #[inline] - fn name(&self) -> &str { - "Empty" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("Empty"); + &NAME } } +#[cfg(feature = "alloc")] impl NamedTuple for (Head, Tail) where Head: Named, Tail: NamedTuple, { - fn name(&self, index: usize) -> Option<&str> { + fn name(&self, index: usize) -> Option<&Cow<'static, str>> { if index == 0 { Some(self.0.name()) } else { @@ -445,6 +453,7 @@ where /// # Note /// This operation may not be 100% accurate with Rust stable, see the notes for [`type_eq`] /// (in `nightly`, it uses [specialization](https://stackoverflow.com/a/60138532/7658998)). +#[cfg(feature = "alloc")] pub trait MatchName { /// Match for a name and return the borrowed value fn match_name(&self, name: &str) -> Option<&T>; @@ -452,6 +461,7 @@ pub trait MatchName { fn match_name_mut(&mut self, name: &str) -> Option<&mut T>; } +#[cfg(feature = "alloc")] impl MatchName for () { fn match_name(&self, _name: &str) -> Option<&T> { None @@ -461,6 +471,7 @@ impl MatchName for () { } } +#[cfg(feature = "alloc")] impl MatchName for (Head, Tail) where Head: Named, @@ -484,6 +495,7 @@ where } /// 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>; @@ -491,6 +503,7 @@ pub trait MatchNameAndType { 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 @@ -500,6 +513,7 @@ impl MatchNameAndType for () { } } +#[cfg(feature = "alloc")] impl MatchNameAndType for (Head, Tail) where Head: 'static + Named, @@ -524,6 +538,54 @@ where } } +/// Structs that has `ReReference ` +/// You should use this when you want to avoid specifying types using `match_name_type_mut` +#[cfg(feature = "alloc")] +pub trait Referenceable: Named { + /// Return the `ReReference ` + fn type_ref(&self) -> ReReference { + ReReference { + name: Named::name(self).clone(), + phantom: PhantomData, + } + } +} + +#[cfg(feature = "alloc")] +impl Referenceable for N where N: Named {} + +/// Empty object with the type T +#[derive(Debug)] +#[cfg(feature = "alloc")] +pub struct ReReference { + name: Cow<'static, str>, + phantom: PhantomData, +} + +/// Search using `ReReference ` +#[cfg(feature = "alloc")] +pub trait MatchNameRef { + /// Search using name and `ReReference ` + fn match_by_ref(&self, rf: ReReference) -> Option<&T>; + + /// Search using name and `ReReference ` + fn match_by_ref_mut(&mut self, rf: ReReference) -> Option<&mut T>; +} + +#[cfg(feature = "alloc")] +impl MatchNameRef for M +where + M: MatchName, +{ + fn match_by_ref(&self, rf: ReReference) -> Option<&T> { + self.match_name::(&rf.name) + } + + fn match_by_ref_mut(&mut self, rf: ReReference) -> Option<&mut T> { + self.match_name_mut::(&rf.name) + } +} + /// Allows prepending of values to a tuple pub trait Prepend { /// The Resulting [`TupleList`], of an [`Prepend::prepend()`] call, diff --git a/libafl_concolic/symcc_runtime/src/filter/coverage.rs b/libafl_concolic/symcc_runtime/src/filter/coverage.rs index ff96f5b0f0..59872ea555 100644 --- a/libafl_concolic/symcc_runtime/src/filter/coverage.rs +++ b/libafl_concolic/symcc_runtime/src/filter/coverage.rs @@ -196,7 +196,7 @@ where // The index is modulo by the length, therefore it is always in bounds let len = self.hitcounts_map.len(); self.hitcounts_map - .as_mut_slice() + .as_slice_mut() .get_unchecked_mut(hash % len) }; *val = val.saturating_add(1); diff --git a/libafl_frida/src/asan/errors.rs b/libafl_frida/src/asan/errors.rs index 29197aef41..100d63880b 100644 --- a/libafl_frida/src/asan/errors.rs +++ b/libafl_frida/src/asan/errors.rs @@ -1,5 +1,6 @@ //! Errors that can be caught by the `libafl_frida` address sanitizer. use std::{ + borrow::Cow, fmt::Debug, io::Write, marker::PhantomData, @@ -38,6 +39,8 @@ 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], @@ -587,8 +590,8 @@ where impl Named for AsanErrorsObserver { #[inline] - fn name(&self) -> &str { - "AsanErrors" + fn name(&self) -> &Cow<'static, str> { + &ASAN_ERRORS_NAME } } @@ -662,7 +665,7 @@ where OT: ObserversTuple, { let observer = observers - .match_name::("AsanErrors") + .match_name::(&ASAN_ERRORS_NAME) .expect("An AsanErrorsFeedback needs an AsanErrorsObserver"); let errors = observer.errors(); if errors.is_empty() { @@ -698,8 +701,8 @@ where impl Named for AsanErrorsFeedback { #[inline] - fn name(&self) -> &str { - "AsanErrors" + fn name(&self) -> &Cow<'static, str> { + &ASAN_ERRORS_NAME } } diff --git a/libafl_libfuzzer/libafl_libfuzzer_runtime/src/feedbacks.rs b/libafl_libfuzzer/libafl_libfuzzer_runtime/src/feedbacks.rs index f655ae3866..4b4f3ad026 100644 --- a/libafl_libfuzzer/libafl_libfuzzer_runtime/src/feedbacks.rs +++ b/libafl_libfuzzer/libafl_libfuzzer_runtime/src/feedbacks.rs @@ -1,5 +1,6 @@ use alloc::rc::Rc; use core::{cell::RefCell, fmt::Debug}; +use std::borrow::Cow; use libafl::{ alloc, @@ -36,8 +37,9 @@ impl LibfuzzerKeepFeedback { } impl Named for LibfuzzerKeepFeedback { - fn name(&self) -> &str { - "libfuzzer-keep" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("libfuzzer-keep"); + &NAME } } @@ -90,8 +92,9 @@ impl LibfuzzerCrashCauseFeedback { } impl Named for LibfuzzerCrashCauseFeedback { - fn name(&self) -> &str { - "crash-cause" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("crash-cause"); + &NAME } } diff --git a/libafl_libfuzzer/libafl_libfuzzer_runtime/src/observers.rs b/libafl_libfuzzer/libafl_libfuzzer_runtime/src/observers.rs index 62b82ec920..d363adb33a 100644 --- a/libafl_libfuzzer/libafl_libfuzzer_runtime/src/observers.rs +++ b/libafl_libfuzzer/libafl_libfuzzer_runtime/src/observers.rs @@ -1,4 +1,5 @@ use std::{ + borrow::Cow, fmt::Debug, hash::{Hash, Hasher}, }; @@ -37,7 +38,7 @@ pub trait ValueObserver: for<'de> Deserialize<'de> + Serialize + Debug + Named { #[derive(Deserialize, Serialize, Debug)] pub struct MappedEdgeMapObserver { inner: M, - name: String, + name: Cow<'static, str>, value_observer: O, } @@ -48,7 +49,7 @@ where { pub fn new(obs: M, value_obs: O) -> Self { Self { - name: format!("{}_{}", value_obs.name(), obs.name()), + name: Cow::from(format!("{}_{}", value_obs.name(), obs.name())), inner: obs, value_observer: value_obs, } @@ -77,7 +78,7 @@ where } impl Named for MappedEdgeMapObserver { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } @@ -251,8 +252,9 @@ impl ValueObserver for SizeValueObserver { } impl Named for SizeValueObserver { - fn name(&self) -> &str { - "size" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("size"); + &NAME } } @@ -295,7 +297,7 @@ impl ValueObserver for TimeValueObserver { } impl Named for TimeValueObserver { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { self.time_obs.name() } } @@ -356,8 +358,9 @@ impl ValueObserver for SizeTimeValueObserver { } impl Named for SizeTimeValueObserver { - fn name(&self) -> &str { - "size_time" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("size_time"); + &NAME } } diff --git a/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs b/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs index a94bd688d5..02642508f5 100644 --- a/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs +++ b/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs @@ -101,7 +101,7 @@ impl __IncompleteArrayField { ::std::slice::from_raw_parts(self.as_ptr(), len) } #[inline] - pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { + pub unsafe fn as_slice_mut(&mut self, len: usize) -> &mut [T] { ::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len) } } diff --git a/libafl_sugar/src/forkserver.rs b/libafl_sugar/src/forkserver.rs index 74f18d2d4c..cb3d04fcd6 100644 --- a/libafl_sugar/src/forkserver.rs +++ b/libafl_sugar/src/forkserver.rs @@ -27,7 +27,7 @@ use libafl_bolts::{ rands::StdRand, shmem::{ShMem, ShMemProvider, UnixShMemProvider}, tuples::{tuple_list, Merge}, - AsMutSlice, + AsSliceMut, }; use typed_builder::TypedBuilder; @@ -120,7 +120,7 @@ impl<'a> ForkserverBytesCoverageSugar<'a> { // 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(); - let shmem_map = shmem.as_mut_slice(); + let shmem_map = shmem.as_slice_mut(); // To let know the AFL++ binary that we have a big map std::env::set_var("AFL_MAP_SIZE", format!("{MAP_SIZE}")); diff --git a/libafl_targets/src/cmps/observers/aflpp.rs b/libafl_targets/src/cmps/observers/aflpp.rs index d2d80dcec9..41db1ecac4 100644 --- a/libafl_targets/src/cmps/observers/aflpp.rs +++ b/libafl_targets/src/cmps/observers/aflpp.rs @@ -1,7 +1,4 @@ -use alloc::{ - string::{String, ToString}, - vec::Vec, -}; +use alloc::{borrow::Cow, vec::Vec}; use core::{fmt::Debug, marker::PhantomData}; use libafl::{ @@ -74,7 +71,7 @@ where { cmp_map: OwnedRefMut<'a, AFLppCmpLogMap>, size: Option>, - name: String, + name: Cow<'static, str>, add_meta: bool, original: >::Data, phantom: PhantomData, @@ -183,7 +180,7 @@ impl<'a, S> Named for AFLppCmpLogObserver<'a, S> where S: UsesInput + HasMetadata, { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } @@ -200,7 +197,7 @@ where add_meta: bool, ) -> Self { Self { - name: name.to_string(), + name: Cow::from(name), size: None, cmp_map, add_meta, @@ -223,7 +220,7 @@ where size: OwnedRefMut<'a, usize>, ) -> Self { Self { - name: name.to_string(), + name: Cow::from(name), size: Some(size), cmp_map, add_meta, diff --git a/libafl_targets/src/cmps/observers/cmplog.rs b/libafl_targets/src/cmps/observers/cmplog.rs index 77e3e9f26a..f8583e8c23 100644 --- a/libafl_targets/src/cmps/observers/cmplog.rs +++ b/libafl_targets/src/cmps/observers/cmplog.rs @@ -2,7 +2,7 @@ //! The values will then be used in subsequent mutations. //! -use alloc::string::{String, ToString}; +use alloc::borrow::Cow; use core::fmt::Debug; use libafl::{ @@ -22,7 +22,7 @@ pub struct CmpLogObserver { map: OwnedMutPtr, size: Option>, add_meta: bool, - name: String, + name: Cow<'static, str>, } impl<'a, S> CmpObserver<'a, CmpLogMap, S, CmpValuesMetadata> for CmpLogObserver @@ -78,7 +78,7 @@ where } impl Named for CmpLogObserver { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } @@ -91,7 +91,7 @@ impl CmpLogObserver { #[must_use] pub unsafe fn with_map_ptr(name: &'static str, map: *mut CmpLogMap, add_meta: bool) -> Self { Self { - name: name.to_string(), + name: Cow::from(name), size: None, add_meta, map: OwnedMutPtr::Ptr(map), diff --git a/libafl_targets/src/cmps/stages/aflpptracing.rs b/libafl_targets/src/cmps/stages/aflpptracing.rs index 961e7930d5..3f9f5642a4 100644 --- a/libafl_targets/src/cmps/stages/aflpptracing.rs +++ b/libafl_targets/src/cmps/stages/aflpptracing.rs @@ -1,4 +1,7 @@ -use alloc::string::{String, ToString}; +use alloc::{ + borrow::Cow, + string::{String, ToString}, +}; use core::marker::PhantomData; #[cfg(feature = "introspection")] @@ -32,8 +35,9 @@ where } impl Named for AFLppCmplogTracingStage { - fn name(&self) -> &str { - "AFLppCmplogTracingStage" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("AFLppCmplogTracingStage"); + &NAME } } diff --git a/libafl_targets/src/coverage.rs b/libafl_targets/src/coverage.rs index 28fa7c1823..a578c2645a 100644 --- a/libafl_targets/src/coverage.rs +++ b/libafl_targets/src/coverage.rs @@ -1,6 +1,6 @@ //! Coverage maps as static mut array -use alloc::string::String; +use alloc::borrow::Cow; #[cfg(any(target_os = "linux", target_vendor = "apple"))] use libafl::{mutators::Tokens, Error}; @@ -108,7 +108,7 @@ pub unsafe fn edges_map_mut_slice<'a>() -> OwnedMutSlice<'a, u8> { /// This will dereference [`edges_map_mut_ptr`] and crash if it is not a valid address. pub unsafe fn std_edges_map_observer<'a, S>(name: S) -> StdMapObserver<'a, u8, false> where - S: Into, + S: Into>, { StdMapObserver::from_mut_slice(name, edges_map_mut_slice()) } @@ -152,7 +152,7 @@ pub use swap::*; #[cfg(feature = "pointer_maps")] mod swap { - use alloc::string::{String, ToString}; + use alloc::borrow::Cow; use core::fmt::Debug; use libafl::{ @@ -160,7 +160,7 @@ mod swap { observers::{DifferentialObserver, Observer, ObserversTuple, StdMapObserver}, Error, }; - use libafl_bolts::{ownedref::OwnedMutSlice, AsMutSlice, Named}; + use libafl_bolts::{ownedref::OwnedMutSlice, AsSliceMut, Named}; use serde::{Deserialize, Serialize}; use super::{EDGES_MAP_PTR, EDGES_MAP_PTR_NUM}; @@ -173,9 +173,9 @@ mod swap { pub struct DifferentialAFLMapSwapObserver<'a, 'b> { first_map: OwnedMutSlice<'a, u8>, second_map: OwnedMutSlice<'b, u8>, - first_name: String, - second_name: String, - name: String, + first_name: Cow<'static, str>, + second_name: Cow<'static, str>, + name: Cow<'static, str>, } impl<'a, 'b> DifferentialAFLMapSwapObserver<'a, 'b> { @@ -185,15 +185,15 @@ mod swap { second: &mut StdMapObserver<'b, u8, D2>, ) -> Self { Self { - first_name: first.name().to_string(), - second_name: second.name().to_string(), - name: format!("differential_{}_{}", first.name(), second.name()), + first_name: first.name().clone(), + second_name: second.name().clone(), + name: Cow::from(format!("differential_{}_{}", first.name(), second.name())), first_map: unsafe { - let slice = first.map_mut().as_mut_slice(); + let slice = first.map_mut().as_slice_mut(); OwnedMutSlice::from_raw_parts_mut(slice.as_mut_ptr(), slice.len()) }, second_map: unsafe { - let slice = second.map_mut().as_mut_slice(); + let slice = second.map_mut().as_slice_mut(); OwnedMutSlice::from_raw_parts_mut(slice.as_mut_ptr(), slice.len()) }, } @@ -225,7 +225,7 @@ mod swap { } impl<'a, 'b> Named for DifferentialAFLMapSwapObserver<'a, 'b> { - fn name(&self) -> &str { + fn name(&self) -> &Cow<'static, str> { &self.name } } @@ -240,7 +240,7 @@ mod swap { S: UsesInput, { fn pre_observe_first(&mut self, _: &mut OTA) -> Result<(), Error> { - let slice = self.first_map.as_mut_slice(); + let slice = self.first_map.as_slice_mut(); unsafe { EDGES_MAP_PTR = slice.as_mut_ptr(); EDGES_MAP_PTR_NUM = slice.len(); @@ -249,7 +249,7 @@ mod swap { } fn pre_observe_second(&mut self, _: &mut OTB) -> Result<(), Error> { - let slice = self.second_map.as_mut_slice(); + let slice = self.second_map.as_slice_mut(); unsafe { EDGES_MAP_PTR = slice.as_mut_ptr(); EDGES_MAP_PTR_NUM = slice.len(); diff --git a/libafl_targets/src/libfuzzer/mutators.rs b/libafl_targets/src/libfuzzer/mutators.rs index 62fbb57db4..44324425fc 100644 --- a/libafl_targets/src/libfuzzer/mutators.rs +++ b/libafl_targets/src/libfuzzer/mutators.rs @@ -1,4 +1,7 @@ -use alloc::rc::{Rc, Weak}; +use alloc::{ + borrow::Cow, + rc::{Rc, Weak}, +}; use std::{ cell::RefCell, marker::PhantomData, @@ -279,8 +282,9 @@ where } impl Named for LLVMCustomMutator { - fn name(&self) -> &str { - "LLVMCustomMutator" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("LLVMCustomMutator"); + &NAME } } @@ -353,8 +357,9 @@ where } impl Named for LLVMCustomMutator { - fn name(&self) -> &str { - "LLVMCustomCrossover" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("LLVMCustomCrossover"); + &NAME } } diff --git a/libafl_targets/src/libfuzzer/observers/oom.rs b/libafl_targets/src/libfuzzer/observers/oom.rs index e24c5169c9..78de4c6764 100644 --- a/libafl_targets/src/libfuzzer/observers/oom.rs +++ b/libafl_targets/src/libfuzzer/observers/oom.rs @@ -1,3 +1,4 @@ +use alloc::borrow::Cow; use core::{ffi::c_void, fmt::Debug}; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; @@ -68,7 +69,7 @@ pub unsafe extern "C" fn __sanitizer_free_hook(ptr: *const c_void) { } } -const OOM_OBS_NAME: &str = "libfuzzer-like-oom"; +static OOM_OBS_NAME: Cow<'static, str> = Cow::Borrowed("libfuzzer-like-oom"); /// Observer which detects if the target would run out of memory or otherwise violate the permissible usage of malloc #[derive(Debug, Serialize, Deserialize)] @@ -88,8 +89,8 @@ impl OomObserver { impl Named for OomObserver { // strictly one name to prevent two from being registered - fn name(&self) -> &str { - OOM_OBS_NAME + fn name(&self) -> &Cow<'static, str> { + &OOM_OBS_NAME } } @@ -142,8 +143,9 @@ impl OomFeedback { } impl Named for OomFeedback { - fn name(&self) -> &str { - "oom" + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("oom"); + &NAME } } diff --git a/libafl_targets/src/sancov_8bit.rs b/libafl_targets/src/sancov_8bit.rs index 05d89af829..de2e428f38 100644 --- a/libafl_targets/src/sancov_8bit.rs +++ b/libafl_targets/src/sancov_8bit.rs @@ -2,7 +2,7 @@ use alloc::vec::Vec; use core::ptr::addr_of_mut; -use libafl_bolts::{ownedref::OwnedMutSlice, AsMutSlice, AsSlice}; +use libafl_bolts::{ownedref::OwnedMutSlice, AsSlice, AsSliceMut}; /// A [`Vec`] of `8-bit-counters` maps for multiple modules. /// They are initialized by calling [`__sanitizer_cov_8bit_counters_init`]( @@ -32,9 +32,9 @@ pub unsafe fn extra_counters() -> Vec> { pub extern "C" fn __sanitizer_cov_8bit_counters_init(start: *mut u8, stop: *mut u8) { unsafe { for existing in &mut *addr_of_mut!(COUNTERS_MAPS) { - let range = existing.as_mut_slice().as_mut_ptr() + let range = existing.as_slice_mut().as_mut_ptr() ..=existing - .as_mut_slice() + .as_slice_mut() .as_mut_ptr() .add(existing.as_slice().len()); if range.contains(&start) || range.contains(&stop) { @@ -59,10 +59,7 @@ pub use self::observers::{counters_maps_observer, CountersMultiMapObserver}; #[cfg(feature = "observers")] mod observers { - use alloc::{ - string::{String, ToString}, - vec::Vec, - }; + use alloc::{borrow::Cow, vec::Vec}; use core::{ fmt::Debug, hash::{Hash, Hasher}, @@ -78,7 +75,7 @@ mod observers { Error, }; use libafl_bolts::{ - ownedref::OwnedMutSlice, AsIter, AsIterMut, AsMutSlice, AsSlice, HasLen, Named, + ownedref::OwnedMutSlice, AsIter, AsIterMut, AsSlice, AsSliceMut, HasLen, Named, }; use meminterval::IntervalTree; use serde::{Deserialize, Serialize}; @@ -122,7 +119,7 @@ mod observers { intervals: IntervalTree, len: usize, initial: u8, - name: String, + name: Cow<'static, str>, iter_idx: usize, } @@ -147,8 +144,8 @@ mod observers { impl Named for CountersMultiMapObserver { #[inline] - fn name(&self) -> &str { - self.name.as_str() + fn name(&self) -> &Cow<'static, str> { + &self.name } } @@ -200,7 +197,7 @@ mod observers { let elem = self.intervals.query_mut(idx..=idx).next().unwrap(); let i = elem.value; let j = idx - elem.interval.start; - unsafe { &mut (*addr_of_mut!(COUNTERS_MAPS[*i])).as_mut_slice()[j] } + unsafe { &mut (*addr_of_mut!(COUNTERS_MAPS[*i])).as_slice_mut()[j] } } #[inline] @@ -229,7 +226,7 @@ mod observers { fn reset_map(&mut self) -> Result<(), Error> { let initial = self.initial(); for map in unsafe { &mut *addr_of_mut!(COUNTERS_MAPS) } { - for x in map.as_mut_slice() { + for x in map.as_slice_mut() { *x = initial; } } @@ -277,7 +274,7 @@ mod observers { Self { intervals, len: idx, - name: name.to_string(), + name: Cow::from(name), initial: u8::default(), iter_idx: 0, } @@ -308,7 +305,7 @@ mod observers { unsafe { &mut *addr_of_mut!(COUNTERS_MAPS) } .iter_mut() .for_each(|m| { - let l = m.as_mut_slice().len(); + let l = m.as_slice_mut().len(); intervals.insert(idx..(idx + l), v); idx += l; v += 1; @@ -316,7 +313,7 @@ mod observers { Self { intervals, len: idx, - name: name.to_string(), + name: Cow::from(name), initial: u8::default(), iter_idx: 0, } diff --git a/libafl_tinyinst/src/executor.rs b/libafl_tinyinst/src/executor.rs index d99930bdc9..2a06d05462 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}, - AsMutSlice, AsSlice, + AsSlice, AsSliceMut, }; use tinyinst::tinyinst::{litecov::RunResult, TinyInst}; @@ -65,9 +65,9 @@ where let size = target_bytes.as_slice().len(); let size_in_bytes = size.to_ne_bytes(); // The first four bytes tells the size of the shmem. - shmem.as_mut_slice()[..SHMEM_FUZZ_HDR_SIZE] + shmem.as_slice_mut()[..SHMEM_FUZZ_HDR_SIZE] .copy_from_slice(&size_in_bytes[..SHMEM_FUZZ_HDR_SIZE]); - shmem.as_mut_slice()[SHMEM_FUZZ_HDR_SIZE..(SHMEM_FUZZ_HDR_SIZE + size)] + shmem.as_slice_mut()[SHMEM_FUZZ_HDR_SIZE..(SHMEM_FUZZ_HDR_SIZE + size)] .copy_from_slice(target_bytes.as_slice()); } None => { @@ -240,7 +240,7 @@ where // shmem.write_to_env("__TINY_SHM_FUZZ_ID")?; let size_in_bytes = (MAX_FILE + SHMEM_FUZZ_HDR_SIZE).to_ne_bytes(); - shmem.as_mut_slice()[..4].clone_from_slice(&size_in_bytes[..4]); + shmem.as_slice_mut()[..4].clone_from_slice(&size_in_bytes[..4]); (Some(shmem), Some(shmem_id)) }