diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 8d259ccb77..b4de96f6d1 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -110,7 +110,6 @@ jobs: ubuntu-miri: runs-on: ubuntu-24.04 - needs: ubuntu steps: - name: Add nightly clippy run: rustup toolchain install nightly --component miri --allow-downgrade diff --git a/fuzzers/baby/baby_fuzzer_minimizing/src/main.rs b/fuzzers/baby/baby_fuzzer_minimizing/src/main.rs index 1f32b4ff08..30e920d380 100644 --- a/fuzzers/baby/baby_fuzzer_minimizing/src/main.rs +++ b/fuzzers/baby/baby_fuzzer_minimizing/src/main.rs @@ -94,8 +94,8 @@ pub fn main() -> Result<(), Error> { .expect("Failed to generate the initial corpus"); // Setup a mutational stage with a basic bytes mutator - let mutator = StdScheduledMutator::new(havoc_mutations::()); - let minimizer = StdScheduledMutator::new(havoc_mutations::()); + let mutator = StdScheduledMutator::new(havoc_mutations()); + let minimizer = StdScheduledMutator::new(havoc_mutations()); let mut stages = tuple_list!( StdMutationalStage::new(mutator), StdTMinMutationalStage::new(minimizer, factory, 128) @@ -121,7 +121,7 @@ pub fn main() -> Result<(), Error> { let mut mgr = SimpleEventManager::new(mon); - let minimizer = StdScheduledMutator::new(havoc_mutations::()); + let minimizer = StdScheduledMutator::new(havoc_mutations()); let mut stages = tuple_list!(StdTMinMutationalStage::new( minimizer, CrashFeedback::new(), diff --git a/fuzzers/binary-only/fuzzbench_fork_qemu/src/fuzzer.rs b/fuzzers/binary-only/fuzzbench_fork_qemu/src/fuzzer.rs index 31f15b217d..84cf20dadf 100644 --- a/fuzzers/binary-only/fuzzbench_fork_qemu/src/fuzzer.rs +++ b/fuzzers/binary-only/fuzzbench_fork_qemu/src/fuzzer.rs @@ -301,14 +301,15 @@ fn fuzz( let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(I2SRandReplace::new()))); // Setup a MOPT mutator - let mutator = StdMOptMutator::new( + let mutator = StdMOptMutator::new::( &mut state, havoc_mutations().merge(tokens_mutations()), 7, 5, )?; - let power = StdPowerMutationalStage::new(mutator); + let power: StdPowerMutationalStage<_, _, BytesInput, _, _> = + StdPowerMutationalStage::new(mutator); // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new( diff --git a/fuzzers/binary-only/fuzzbench_qemu/src/fuzzer.rs b/fuzzers/binary-only/fuzzbench_qemu/src/fuzzer.rs index 3ab7a5b484..33441cf6de 100644 --- a/fuzzers/binary-only/fuzzbench_qemu/src/fuzzer.rs +++ b/fuzzers/binary-only/fuzzbench_qemu/src/fuzzer.rs @@ -307,14 +307,15 @@ fn fuzz( let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(I2SRandReplace::new()))); // Setup a MOPT mutator - let mutator = StdMOptMutator::new( + let mutator = StdMOptMutator::new::( &mut state, havoc_mutations().merge(tokens_mutations()), 7, 5, )?; - let power = StdPowerMutationalStage::new(mutator); + let power: StdPowerMutationalStage<_, _, BytesInput, _, _> = + StdPowerMutationalStage::new(mutator); // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new( diff --git a/fuzzers/binary-only/qemu_launcher/src/instance.rs b/fuzzers/binary-only/qemu_launcher/src/instance.rs index 47037c0c14..96feac2248 100644 --- a/fuzzers/binary-only/qemu_launcher/src/instance.rs +++ b/fuzzers/binary-only/qemu_launcher/src/instance.rs @@ -185,14 +185,15 @@ impl<'a, M: Monitor> Instance<'a, M> { ))); // Setup a MOPT mutator - let mutator = StdMOptMutator::new( + let mutator = StdMOptMutator::new::( &mut state, havoc_mutations().merge(tokens_mutations()), 7, 5, )?; - let power = StdPowerMutationalStage::new(mutator); + let power: StdPowerMutationalStage<_, _, BytesInput, _, _> = + StdPowerMutationalStage::new(mutator); // The order of the stages matter! let mut stages = tuple_list!(calibration, tracing, i2s, power); diff --git a/fuzzers/forkserver/fuzzbench_forkserver/src/main.rs b/fuzzers/forkserver/fuzzbench_forkserver/src/main.rs index 68b21d2a53..f927dca6e5 100644 --- a/fuzzers/forkserver/fuzzbench_forkserver/src/main.rs +++ b/fuzzers/forkserver/fuzzbench_forkserver/src/main.rs @@ -293,14 +293,15 @@ fn fuzz( println!("Let's fuzz :)"); // Setup a MOPT mutator - let mutator = StdMOptMutator::new( + let mutator = StdMOptMutator::new::( &mut state, havoc_mutations().merge(tokens_mutations()), 7, 5, )?; - let power = StdPowerMutationalStage::new(mutator); + let power: StdPowerMutationalStage<_, _, BytesInput, _, _> = + StdPowerMutationalStage::new(mutator); // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new( diff --git a/fuzzers/forkserver/fuzzbench_forkserver_cmplog/src/main.rs b/fuzzers/forkserver/fuzzbench_forkserver_cmplog/src/main.rs index 560ab516ff..c1188a5586 100644 --- a/fuzzers/forkserver/fuzzbench_forkserver_cmplog/src/main.rs +++ b/fuzzers/forkserver/fuzzbench_forkserver_cmplog/src/main.rs @@ -293,14 +293,15 @@ fn fuzz( println!("Let's fuzz :)"); // Setup a MOPT mutator - let mutator = StdMOptMutator::new( + let mutator = StdMOptMutator::new::( &mut state, havoc_mutations().merge(tokens_mutations()), 7, 5, )?; - let power = StdPowerMutationalStage::new(mutator); + let power: StdPowerMutationalStage<_, _, BytesInput, _, _> = + StdPowerMutationalStage::new(mutator); // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new( diff --git a/fuzzers/forkserver/libafl-fuzz/src/afl_stats.rs b/fuzzers/forkserver/libafl-fuzz/src/afl_stats.rs index 48203fa47d..f8bc4af728 100644 --- a/fuzzers/forkserver/libafl-fuzz/src/afl_stats.rs +++ b/fuzzers/forkserver/libafl-fuzz/src/afl_stats.rs @@ -9,7 +9,7 @@ use std::{ }; use libafl::{ - corpus::{Corpus, HasCurrentCorpusId, HasTestcase, SchedulerTestcaseMetadata, Testcase}, + corpus::{Corpus, HasCurrentCorpusId, SchedulerTestcaseMetadata, Testcase}, events::EventFirer, executors::HasObservers, inputs::UsesInput, @@ -236,11 +236,11 @@ where + HasStartTime + HasExecutions + HasNamedMetadata - + Stoppable - + HasTestcase, + + Stoppable, O: MapObserver, C: AsRef + Named, ::Scheduler: HasQueueCycles, + <::State as HasCorpus>::Corpus: Corpus, { fn perform( &mut self, diff --git a/fuzzers/forkserver/libafl-fuzz/src/scheduler.rs b/fuzzers/forkserver/libafl-fuzz/src/scheduler.rs index bf74dc4c9e..fa50cdf338 100644 --- a/fuzzers/forkserver/libafl-fuzz/src/scheduler.rs +++ b/fuzzers/forkserver/libafl-fuzz/src/scheduler.rs @@ -2,7 +2,6 @@ use std::marker::PhantomData; use libafl::{ corpus::{Corpus, CorpusId, HasTestcase, SchedulerTestcaseMetadata, Testcase}, - inputs::Input, schedulers::{HasQueueCycles, RemovableScheduler, Scheduler}, state::HasCorpus, Error, HasMetadata, @@ -14,17 +13,19 @@ pub enum SupportedSchedulers { Weighted(W, PhantomData), } -impl RemovableScheduler for SupportedSchedulers +impl RemovableScheduler<::Input, S> for SupportedSchedulers where - Q: Scheduler + RemovableScheduler, - W: Scheduler + RemovableScheduler, + Q: Scheduler<::Input, S> + + RemovableScheduler<::Input, S>, + W: Scheduler<::Input, S> + + RemovableScheduler<::Input, S>, S: HasCorpus + HasTestcase, { fn on_remove( &mut self, state: &mut S, id: CorpusId, - testcase: &Option>, + testcase: &Option::Input>>, ) -> Result<(), Error> { match self { Self::Queue(queue, _) => queue.on_remove(state, id, testcase), @@ -32,7 +33,12 @@ where } } - fn on_replace(&mut self, state: &mut S, id: CorpusId, prev: &Testcase) -> Result<(), Error> { + fn on_replace( + &mut self, + state: &mut S, + id: CorpusId, + prev: &Testcase<::Input>, + ) -> Result<(), Error> { match self { Self::Queue(queue, _) => queue.on_replace(state, id, prev), Self::Weighted(weighted, _) => weighted.on_replace(state, id, prev), @@ -40,11 +46,10 @@ where } } -impl Scheduler for SupportedSchedulers +impl Scheduler<::Input, S> for SupportedSchedulers where - I: Input, - Q: Scheduler, - W: Scheduler, + Q: Scheduler<::Input, S>, + W: Scheduler<::Input, S>, S: HasCorpus + HasTestcase, { fn on_add(&mut self, state: &mut S, id: CorpusId) -> Result<(), Error> { @@ -77,7 +82,12 @@ where Self::Weighted(weighted, _) => weighted.next(state), } } - fn on_evaluation(&mut self, state: &mut S, input: &I, observers: &OTB) -> Result<(), Error> + fn on_evaluation( + &mut self, + state: &mut S, + input: &::Input, + observers: &OTB, + ) -> Result<(), Error> where OTB: MatchName, { diff --git a/fuzzers/forkserver/libafl-fuzz/src/stages/mutational_stage.rs b/fuzzers/forkserver/libafl-fuzz/src/stages/mutational_stage.rs index 3f5bef3dd9..546d2de1a6 100644 --- a/fuzzers/forkserver/libafl-fuzz/src/stages/mutational_stage.rs +++ b/fuzzers/forkserver/libafl-fuzz/src/stages/mutational_stage.rs @@ -1,6 +1,7 @@ use std::{borrow::Cow, marker::PhantomData}; use libafl::{ + corpus::Corpus, inputs::Input, mutators::Mutator, stages::{mutational::MutatedTransform, MutationalStage, Stage}, @@ -26,6 +27,7 @@ where SM: MutationalStage, P: MutationalStage, S: State + HasRand + HasCorpus + HasNamedMetadata, + <::State as HasCorpus>::Corpus: Corpus, //delete me { /// The mutator, added to this stage #[inline] @@ -85,6 +87,7 @@ where SM: MutationalStage, P: MutationalStage, S: State + HasRand + HasCorpus + HasNamedMetadata, + <::State as HasCorpus>::Corpus: Corpus, //delete me { #[inline] #[allow(clippy::let_and_return)] diff --git a/fuzzers/inprocess/dynamic_analysis/src/lib.rs b/fuzzers/inprocess/dynamic_analysis/src/lib.rs index 560ff377c0..89c95facf5 100644 --- a/fuzzers/inprocess/dynamic_analysis/src/lib.rs +++ b/fuzzers/inprocess/dynamic_analysis/src/lib.rs @@ -304,14 +304,15 @@ fn fuzz( let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(I2SRandReplace::new()))); // Setup a MOPT mutator - let mutator = StdMOptMutator::new( + let mutator = StdMOptMutator::new::( &mut state, havoc_mutations().merge(tokens_mutations()), 7, 5, )?; - let power = StdPowerMutationalStage::new(mutator); + let power: StdPowerMutationalStage<_, _, BytesInput, _, _> = + StdPowerMutationalStage::new(mutator); // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new( diff --git a/fuzzers/inprocess/fuzzbench/src/lib.rs b/fuzzers/inprocess/fuzzbench/src/lib.rs index b282d84ab4..4e308071d4 100644 --- a/fuzzers/inprocess/fuzzbench/src/lib.rs +++ b/fuzzers/inprocess/fuzzbench/src/lib.rs @@ -298,14 +298,15 @@ fn fuzz( let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(I2SRandReplace::new()))); // Setup a MOPT mutator - let mutator = StdMOptMutator::new( + let mutator = StdMOptMutator::new::( &mut state, havoc_mutations().merge(tokens_mutations()), 7, 5, )?; - let power = StdPowerMutationalStage::new(mutator); + let power: StdPowerMutationalStage<_, _, BytesInput, _, _> = + StdPowerMutationalStage::new(mutator); // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new( diff --git a/fuzzers/inprocess/fuzzbench_ctx/src/lib.rs b/fuzzers/inprocess/fuzzbench_ctx/src/lib.rs index 52fd37ea59..3ccb152989 100644 --- a/fuzzers/inprocess/fuzzbench_ctx/src/lib.rs +++ b/fuzzers/inprocess/fuzzbench_ctx/src/lib.rs @@ -308,14 +308,15 @@ fn fuzz( let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(I2SRandReplace::new()))); // Setup a MOPT mutator - let mutator = StdMOptMutator::new( + let mutator = StdMOptMutator::new::( &mut state, havoc_mutations().merge(tokens_mutations()), 7, 5, )?; - let power = StdPowerMutationalStage::new(mutator); + let power: StdPowerMutationalStage<_, _, BytesInput, _, _> = + StdPowerMutationalStage::new(mutator); // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new( diff --git a/fuzzers/inprocess/fuzzbench_text/src/lib.rs b/fuzzers/inprocess/fuzzbench_text/src/lib.rs index d97d96bb0c..2d7f81ea4b 100644 --- a/fuzzers/inprocess/fuzzbench_text/src/lib.rs +++ b/fuzzers/inprocess/fuzzbench_text/src/lib.rs @@ -365,14 +365,15 @@ fn fuzz_binary( let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(I2SRandReplace::new()))); // Setup a MOPT mutator - let mutator = StdMOptMutator::new( + let mutator = StdMOptMutator::new::( &mut state, havoc_mutations().merge(tokens_mutations()), 7, 5, )?; - let power = StdPowerMutationalStage::new(mutator); + let power: StdPowerMutationalStage<_, _, BytesInput, _, _> = + StdPowerMutationalStage::new(mutator); // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new( @@ -577,14 +578,15 @@ fn fuzz_text( let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(I2SRandReplace::new()))); // Setup a MOPT mutator - let mutator = StdMOptMutator::new( + let mutator = StdMOptMutator::new::( &mut state, havoc_mutations().merge(tokens_mutations()), 7, 5, )?; - let power = StdPowerMutationalStage::new(mutator); + let power: StdPowerMutationalStage<_, _, BytesInput, _, _> = + StdPowerMutationalStage::new(mutator); let grimoire_mutator = StdScheduledMutator::with_max_stack_pow( tuple_list!( diff --git a/fuzzers/inprocess/libfuzzer_libpng/src/lib.rs b/fuzzers/inprocess/libfuzzer_libpng/src/lib.rs index 9af9b9cbe9..8008bf94f3 100644 --- a/fuzzers/inprocess/libfuzzer_libpng/src/lib.rs +++ b/fuzzers/inprocess/libfuzzer_libpng/src/lib.rs @@ -143,7 +143,8 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations())); - let power = StdPowerMutationalStage::new(mutator); + let power: StdPowerMutationalStage<_, _, BytesInput, _, _> = + StdPowerMutationalStage::new(mutator); let mut stages = tuple_list!(calibration, power); diff --git a/fuzzers/inprocess/libfuzzer_libpng_cmin/src/lib.rs b/fuzzers/inprocess/libfuzzer_libpng_cmin/src/lib.rs index 865097fe74..1e0000aaad 100644 --- a/fuzzers/inprocess/libfuzzer_libpng_cmin/src/lib.rs +++ b/fuzzers/inprocess/libfuzzer_libpng_cmin/src/lib.rs @@ -6,10 +6,7 @@ use std::ptr; use std::{env, path::PathBuf}; use libafl::{ - corpus::{ - minimizer::{CorpusMinimizer, StdCorpusMinimizer}, - Corpus, InMemoryCorpus, OnDiskCorpus, - }, + corpus::{minimizer::StdCorpusMinimizer, Corpus, InMemoryCorpus, OnDiskCorpus}, events::{setup_restarting_mgr_std, EventConfig, EventFirer, EventRestarter, LogSeverity}, executors::{inprocess::InProcessExecutor, ExitKind}, feedback_or, feedback_or_fast, @@ -143,7 +140,8 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations())); - let power = StdPowerMutationalStage::new(mutator); + let power: StdPowerMutationalStage<_, _, BytesInput, _, _> = + StdPowerMutationalStage::new(mutator); let mut stages = tuple_list!(calibration, power); diff --git a/fuzzers/inprocess/libfuzzer_libpng_tcp_manager/src/lib.rs b/fuzzers/inprocess/libfuzzer_libpng_tcp_manager/src/lib.rs index c390a4174b..bc9a60b381 100644 --- a/fuzzers/inprocess/libfuzzer_libpng_tcp_manager/src/lib.rs +++ b/fuzzers/inprocess/libfuzzer_libpng_tcp_manager/src/lib.rs @@ -141,7 +141,8 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations())); - let power = StdPowerMutationalStage::new(mutator); + let power: StdPowerMutationalStage<_, _, BytesInput, _, _> = + StdPowerMutationalStage::new(mutator); let mut stages = tuple_list!(calibration, power); diff --git a/fuzzers/inprocess/libfuzzer_windows_asan/src/lib.rs b/fuzzers/inprocess/libfuzzer_windows_asan/src/lib.rs index 5b9a8aed4d..5623242966 100644 --- a/fuzzers/inprocess/libfuzzer_windows_asan/src/lib.rs +++ b/fuzzers/inprocess/libfuzzer_windows_asan/src/lib.rs @@ -110,7 +110,8 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations())); - let power = StdPowerMutationalStage::new(mutator); + let power: StdPowerMutationalStage<_, _, BytesInput, _, _> = + StdPowerMutationalStage::new(mutator); let mut stages = tuple_list!(calibration, power); diff --git a/fuzzers/inprocess/tutorial/src/lib.rs b/fuzzers/inprocess/tutorial/src/lib.rs index c2f8d2778f..343511d6fc 100644 --- a/fuzzers/inprocess/tutorial/src/lib.rs +++ b/fuzzers/inprocess/tutorial/src/lib.rs @@ -128,7 +128,8 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re // Setup a lain mutator with a mutational stage let mutator = LainMutator::new(); - let power = StdPowerMutationalStage::new(mutator); + let power: StdPowerMutationalStage<_, _, PacketData, _, _> = + StdPowerMutationalStage::new(mutator); let mut stages = tuple_list!(calibration, power); diff --git a/fuzzers/inprocess/tutorial/src/metadata.rs b/fuzzers/inprocess/tutorial/src/metadata.rs index 62543f4211..76159a3b5a 100644 --- a/fuzzers/inprocess/tutorial/src/metadata.rs +++ b/fuzzers/inprocess/tutorial/src/metadata.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; use libafl::{ - corpus::Testcase, + corpus::{Corpus, Testcase}, events::EventFirer, executors::ExitKind, feedbacks::{Feedback, MapIndexesMetadata}, @@ -22,11 +22,14 @@ pub struct PacketLenMetadata { pub struct PacketLenTestcaseScore {} -impl TestcaseScore for PacketLenTestcaseScore +impl TestcaseScore for PacketLenTestcaseScore where - S: HasCorpus + HasMetadata, + S: HasMetadata + HasCorpus, { - fn compute(_state: &S, entry: &mut Testcase) -> Result { + fn compute( + _state: &S, + entry: &mut Testcase<::Input>, + ) -> Result { Ok(entry .metadata_map() .get::() diff --git a/libafl/src/corpus/cached.rs b/libafl/src/corpus/cached.rs index 2855d6814d..dfa7c15f34 100644 --- a/libafl/src/corpus/cached.rs +++ b/libafl/src/corpus/cached.rs @@ -11,7 +11,7 @@ use crate::{ inmemory_ondisk::InMemoryOnDiskCorpus, ondisk::OnDiskMetadataFormat, Corpus, CorpusId, HasTestcase, Testcase, }, - inputs::{Input, UsesInput}, + inputs::Input, Error, }; @@ -20,23 +20,12 @@ use crate::{ /// The eviction policy is FIFO. #[cfg(feature = "std")] #[derive(Default, Serialize, Deserialize, Clone, Debug)] -#[serde(bound = "I: serde::de::DeserializeOwned")] -pub struct CachedOnDiskCorpus -where - I: Input, -{ +pub struct CachedOnDiskCorpus { inner: InMemoryOnDiskCorpus, cached_indexes: RefCell>, cache_max_len: usize, } -impl UsesInput for CachedOnDiskCorpus -where - I: Input, -{ - type Input = I; -} - impl CachedOnDiskCorpus where I: Input, @@ -71,6 +60,8 @@ impl Corpus for CachedOnDiskCorpus where I: Input, { + type Input = I; + /// Returns the number of all enabled entries #[inline] fn count(&self) -> usize { @@ -193,22 +184,16 @@ impl HasTestcase for CachedOnDiskCorpus where I: Input, { - fn testcase(&self, id: CorpusId) -> Result>, Error> { + fn testcase(&self, id: CorpusId) -> Result>, Error> { Ok(self.get(id)?.borrow()) } - fn testcase_mut( - &self, - id: CorpusId, - ) -> Result>, Error> { + fn testcase_mut(&self, id: CorpusId) -> Result>, Error> { Ok(self.get(id)?.borrow_mut()) } } -impl CachedOnDiskCorpus -where - I: Input, -{ +impl CachedOnDiskCorpus { /// Creates the [`CachedOnDiskCorpus`]. /// /// This corpus stores (and reads) all testcases to/from disk diff --git a/libafl/src/corpus/inmemory.rs b/libafl/src/corpus/inmemory.rs index d880caa1da..4af250506c 100644 --- a/libafl/src/corpus/inmemory.rs +++ b/libafl/src/corpus/inmemory.rs @@ -8,18 +8,13 @@ use serde::{Deserialize, Serialize}; use super::HasTestcase; use crate::{ corpus::{Corpus, CorpusId, Testcase}, - inputs::{Input, UsesInput}, Error, }; /// Keep track of the stored `Testcase` and the siblings ids (insertion order) #[cfg(not(feature = "corpus_btreemap"))] #[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(bound = "I: serde::de::DeserializeOwned")] -pub struct TestcaseStorageItem -where - I: Input, -{ +pub struct TestcaseStorageItem { /// The stored testcase pub testcase: RefCell>, /// Previously inserted id @@ -30,11 +25,7 @@ where /// The map type in which testcases are stored (disable the feature `corpus_btreemap` to use a `HashMap` instead of `BTreeMap`) #[derive(Default, Serialize, Deserialize, Clone, Debug)] -#[serde(bound = "I: serde::de::DeserializeOwned")] -pub struct TestcaseStorageMap -where - I: Input, -{ +pub struct TestcaseStorageMap { #[cfg(not(feature = "corpus_btreemap"))] /// A map of `CorpusId` to `TestcaseStorageItem` pub map: hashbrown::HashMap>, @@ -51,10 +42,7 @@ where last_id: Option, } -impl TestcaseStorageMap -where - I: Input, -{ +impl TestcaseStorageMap { /// Insert a key in the keys set fn insert_key(&mut self, id: CorpusId) { if let Err(idx) = self.keys.binary_search(&id) { @@ -235,11 +223,7 @@ where } /// Storage map for the testcases (used in `Corpus` implementations) with an incremental index #[derive(Default, Serialize, Deserialize, Clone, Debug)] -#[serde(bound = "I: serde::de::DeserializeOwned")] -pub struct TestcaseStorage -where - I: Input, -{ +pub struct TestcaseStorage { /// The map in which enabled testcases are stored pub enabled: TestcaseStorageMap, /// The map in which disabled testcases are stored @@ -248,17 +232,7 @@ where progressive_id: usize, } -impl UsesInput for TestcaseStorage -where - I: Input, -{ - type Input = I; -} - -impl TestcaseStorage -where - I: Input, -{ +impl TestcaseStorage { /// Insert a testcase assigning a `CorpusId` to it pub fn insert(&mut self, testcase: RefCell>) -> CorpusId { self.insert_inner(testcase, false) @@ -335,26 +309,14 @@ where /// A corpus handling all in memory. #[derive(Default, Serialize, Deserialize, Clone, Debug)] -#[serde(bound = "I: serde::de::DeserializeOwned")] -pub struct InMemoryCorpus -where - I: Input, -{ +pub struct InMemoryCorpus { storage: TestcaseStorage, current: Option, } -impl UsesInput for InMemoryCorpus -where - I: Input, -{ +impl Corpus for InMemoryCorpus { type Input = I; -} -impl Corpus for InMemoryCorpus -where - I: Input, -{ /// Returns the number of all enabled entries #[inline] fn count(&self) -> usize { @@ -492,29 +454,23 @@ where } } -impl HasTestcase for InMemoryCorpus -where - I: Input, -{ +impl HasTestcase for InMemoryCorpus { fn testcase( &self, id: CorpusId, - ) -> Result::Input>>, Error> { + ) -> Result::Input>>, Error> { Ok(self.get(id)?.borrow()) } fn testcase_mut( &self, id: CorpusId, - ) -> Result::Input>>, Error> { + ) -> Result::Input>>, Error> { Ok(self.get(id)?.borrow_mut()) } } -impl InMemoryCorpus -where - I: Input, -{ +impl InMemoryCorpus { /// Creates a new [`InMemoryCorpus`], keeping all [`Testcase`]`s` in memory. /// This is the simplest and fastest option, however test progress will be lost on exit or on OOM. #[must_use] diff --git a/libafl/src/corpus/inmemory_ondisk.rs b/libafl/src/corpus/inmemory_ondisk.rs index 66ef49ef3a..aa68dcbc86 100644 --- a/libafl/src/corpus/inmemory_ondisk.rs +++ b/libafl/src/corpus/inmemory_ondisk.rs @@ -24,7 +24,7 @@ use super::{ }; use crate::{ corpus::{Corpus, CorpusId, InMemoryCorpus, Testcase}, - inputs::{Input, UsesInput}, + inputs::Input, Error, HasMetadata, }; @@ -52,11 +52,7 @@ fn try_create_new>(path: P) -> Result, io::Error> { /// Metadata is written to a `..metadata` file in the same folder by default. #[cfg(feature = "std")] #[derive(Default, Serialize, Deserialize, Clone, Debug)] -#[serde(bound = "I: serde::de::DeserializeOwned")] -pub struct InMemoryOnDiskCorpus -where - I: Input, -{ +pub struct InMemoryOnDiskCorpus { inner: InMemoryCorpus, dir_path: PathBuf, meta_format: Option, @@ -64,17 +60,12 @@ where locking: bool, } -impl UsesInput for InMemoryOnDiskCorpus -where - I: Input, -{ - type Input = I; -} - impl Corpus for InMemoryOnDiskCorpus where I: Input, { + type Input = I; + /// Returns the number of all enabled entries #[inline] fn count(&self) -> usize { @@ -228,22 +219,19 @@ where fn testcase( &self, id: CorpusId, - ) -> Result::Input>>, Error> { + ) -> Result::Input>>, Error> { Ok(self.get(id)?.borrow()) } fn testcase_mut( &self, id: CorpusId, - ) -> Result::Input>>, Error> { + ) -> Result::Input>>, Error> { Ok(self.get(id)?.borrow_mut()) } } -impl InMemoryOnDiskCorpus -where - I: Input, -{ +impl InMemoryOnDiskCorpus { /// Creates an [`InMemoryOnDiskCorpus`]. /// /// This corpus stores all testcases to disk, and keeps all of them in memory, as well. @@ -388,7 +376,10 @@ where } } - fn save_testcase(&self, testcase: &mut Testcase, id: CorpusId) -> Result<(), Error> { + fn save_testcase(&self, testcase: &mut Testcase, id: CorpusId) -> Result<(), Error> + where + I: Input, + { let file_name_orig = testcase.filename_mut().take().unwrap_or_else(|| { // TODO walk entry metadata to ask for pieces of filename (e.g. :havoc in AFL) testcase.input().as_ref().unwrap().generate_name(Some(id)) diff --git a/libafl/src/corpus/minimizer.rs b/libafl/src/corpus/minimizer.rs index 1548cbaded..0953da8a24 100644 --- a/libafl/src/corpus/minimizer.rs +++ b/libafl/src/corpus/minimizer.rs @@ -24,28 +24,6 @@ use crate::{ Error, HasMetadata, HasScheduler, }; -/// `CorpusMinimizers` minimize corpora according to internal logic. See various implementations for -/// details. -pub trait CorpusMinimizer -where - E: UsesState, - E::State: HasCorpus, -{ - /// Minimize the corpus of the provided state. - fn minimize( - &self, - fuzzer: &mut Z, - executor: &mut E, - manager: &mut EM, - state: &mut E::State, - ) -> Result<(), Error> - where - E: Executor + HasObservers, - CS: Scheduler + RemovableScheduler, // schedulers that has on_remove/on_replace only! - EM: EventFirer, - Z: HasScheduler; -} - /// Minimizes a corpus according to coverage maps, weighting by the specified `TestcaseScore`. /// /// Algorithm based on WMOPT: @@ -62,7 +40,7 @@ impl MapCorpusMinimizer where E: UsesState, E::State: HasCorpus + HasMetadata, - TS: TestcaseScore, + TS: TestcaseScore, C: Named, { /// Constructs a new `MapCorpusMinimizer` from a provided observer. This observer will be used @@ -75,17 +53,19 @@ where } } -impl CorpusMinimizer for MapCorpusMinimizer +impl MapCorpusMinimizer where E: UsesState, for<'a> O: MapObserver + AsIter<'a, Item = T>, C: AsRef, E::State: HasMetadata + HasCorpus + HasExecutions, + <::State as HasCorpus>::Corpus: Corpus, T: Copy + Hash + Eq, - TS: TestcaseScore, + TS: TestcaseScore, { + /// Do the minimization #[allow(clippy::too_many_lines)] - fn minimize( + pub fn minimize( &self, fuzzer: &mut Z, executor: &mut E, diff --git a/libafl/src/corpus/mod.rs b/libafl/src/corpus/mod.rs index f0b1755060..4bf07626c0 100644 --- a/libafl/src/corpus/mod.rs +++ b/libafl/src/corpus/mod.rs @@ -31,7 +31,7 @@ pub use minimizer::*; pub use nop::NopCorpus; use serde::{Deserialize, Serialize}; -use crate::{inputs::UsesInput, Error}; +use crate::Error; /// An abstraction for the index that identify a testcase in the corpus #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] @@ -85,7 +85,10 @@ macro_rules! random_corpus_id_with_disabled { } /// Corpus with all current [`Testcase`]s, or solutions -pub trait Corpus: UsesInput + Serialize + for<'de> Deserialize<'de> { +pub trait Corpus: Sized { + /// The type of input contained in this corpus + type Input; + /// Returns the number of all enabled entries fn count(&self) -> usize; @@ -171,7 +174,10 @@ pub trait Corpus: UsesInput + Serialize + for<'de> Deserialize<'de> { fn store_input_from(&self, testcase: &Testcase) -> Result<(), Error>; /// Loads the `Input` for a given [`CorpusId`] from the [`Corpus`], and returns the clone. - fn cloned_input_for_id(&self, id: CorpusId) -> Result { + fn cloned_input_for_id(&self, id: CorpusId) -> Result + where + Self::Input: Clone, + { let mut testcase = self.get(id)?.borrow_mut(); Ok(testcase.load_input(self)?.clone()) } diff --git a/libafl/src/corpus/nop.rs b/libafl/src/corpus/nop.rs index 051592b576..e50173f9e0 100644 --- a/libafl/src/corpus/nop.rs +++ b/libafl/src/corpus/nop.rs @@ -5,29 +5,18 @@ use serde::{Deserialize, Serialize}; use crate::{ corpus::{Corpus, CorpusId, Testcase}, - inputs::{Input, UsesInput}, Error, }; /// A corpus which does not store any [`Testcase`]s. #[derive(Default, Serialize, Deserialize, Clone, Debug)] -#[serde(bound = "I: serde::de::DeserializeOwned")] pub struct NopCorpus { empty: Option, phantom: PhantomData, } -impl UsesInput for NopCorpus -where - I: Input, -{ +impl Corpus for NopCorpus { type Input = I; -} - -impl Corpus for NopCorpus -where - I: Input, -{ /// Returns the number of all enabled entries #[inline] fn count(&self) -> usize { @@ -142,10 +131,7 @@ where } } -impl NopCorpus -where - I: Input, -{ +impl NopCorpus { /// Creates a new [`NopCorpus`]. #[must_use] pub fn new() -> Self { diff --git a/libafl/src/corpus/ondisk.rs b/libafl/src/corpus/ondisk.rs index ae1342fedc..1e46be9adb 100644 --- a/libafl/src/corpus/ondisk.rs +++ b/libafl/src/corpus/ondisk.rs @@ -6,7 +6,10 @@ //! which stores a certain number of [`Testcase`]s in memory and removes additional ones in a FIFO manner. use alloc::string::String; -use core::{cell::RefCell, time::Duration}; +use core::{ + cell::{Ref, RefCell, RefMut}, + time::Duration, +}; use std::path::{Path, PathBuf}; use libafl_bolts::serdeany::SerdeAnyMap; @@ -14,7 +17,7 @@ use serde::{Deserialize, Serialize}; use crate::{ corpus::{CachedOnDiskCorpus, Corpus, CorpusId, HasTestcase, Testcase}, - inputs::{Input, UsesInput}, + inputs::Input, Error, }; @@ -49,28 +52,18 @@ pub struct OnDiskMetadata<'a> { /// /// Metadata is written to a `..metadata` file in the same folder by default. #[derive(Default, Serialize, Deserialize, Clone, Debug)] -#[serde(bound = "I: serde::de::DeserializeOwned")] -pub struct OnDiskCorpus -where - I: Input, -{ +pub struct OnDiskCorpus { /// The root directory backing this corpus dir_path: PathBuf, /// We wrapp a cached corpus and set its size to 1. inner: CachedOnDiskCorpus, } -impl UsesInput for OnDiskCorpus -where - I: Input, -{ - type Input = I; -} - impl Corpus for OnDiskCorpus where I: Input, { + type Input = I; /// Returns the number of all enabled entries #[inline] fn count(&self) -> usize { @@ -188,25 +181,16 @@ impl HasTestcase for OnDiskCorpus where I: Input, { - fn testcase( - &self, - id: CorpusId, - ) -> Result::Input>>, Error> { + fn testcase(&self, id: CorpusId) -> Result>, Error> { Ok(self.get(id)?.borrow()) } - fn testcase_mut( - &self, - id: CorpusId, - ) -> Result::Input>>, Error> { + fn testcase_mut(&self, id: CorpusId) -> Result>, Error> { Ok(self.get(id)?.borrow_mut()) } } -impl OnDiskCorpus -where - I: Input, -{ +impl OnDiskCorpus { /// Creates an [`OnDiskCorpus`]. /// /// This corpus stores all testcases to disk. diff --git a/libafl/src/corpus/testcase.rs b/libafl/src/corpus/testcase.rs index 89d71ac391..06c211a97b 100644 --- a/libafl/src/corpus/testcase.rs +++ b/libafl/src/corpus/testcase.rs @@ -15,21 +15,24 @@ use libafl_bolts::{serdeany::SerdeAnyMap, HasLen}; use serde::{Deserialize, Serialize}; use super::Corpus; -use crate::{corpus::CorpusId, inputs::UsesInput, Error, HasMetadata}; +use crate::{corpus::CorpusId, state::HasCorpus, Error, HasMetadata}; /// Shorthand to receive a [`Ref`] or [`RefMut`] to a stored [`Testcase`], by [`CorpusId`]. /// For a normal state, this should return a [`Testcase`] in the corpus, not the objectives. -pub trait HasTestcase: UsesInput { +pub trait HasTestcase: HasCorpus { /// Shorthand to receive a [`Ref`] to a stored [`Testcase`], by [`CorpusId`]. /// For a normal state, this should return a [`Testcase`] in the corpus, not the objectives. - fn testcase(&self, id: CorpusId) -> Result::Input>>, Error>; + fn testcase( + &self, + id: CorpusId, + ) -> Result::Input>>, Error>; /// Shorthand to receive a [`RefMut`] to a stored [`Testcase`], by [`CorpusId`]. /// For a normal state, this should return a [`Testcase`] in the corpus, not the objectives. fn testcase_mut( &self, id: CorpusId, - ) -> Result::Input>>, Error>; + ) -> Result::Input>>, Error>; } /// An entry in the [`Testcase`] Corpus diff --git a/libafl/src/executors/hooks/inprocess.rs b/libafl/src/executors/hooks/inprocess.rs index ce26a26113..a63a6032e4 100644 --- a/libafl/src/executors/hooks/inprocess.rs +++ b/libafl/src/executors/hooks/inprocess.rs @@ -28,11 +28,12 @@ use crate::executors::hooks::unix::unix_signal_handler; #[cfg(windows)] use crate::state::State; use crate::{ + corpus::Corpus, events::{EventFirer, EventRestarter}, executors::{hooks::ExecutorHook, inprocess::HasInProcessHooks, Executor, HasObservers}, feedbacks::Feedback, inputs::UsesInput, - state::{HasCorpus, HasExecutions, HasSolutions}, + state::{HasCorpus, HasExecutions, HasSolutions, UsesState}, Error, HasObjective, }; /// The inmem executor's handlers. @@ -236,6 +237,8 @@ where OF: Feedback, E::State: HasExecutions + HasSolutions + HasCorpus, Z: HasObjective, + <::State as HasSolutions>::Solutions: Corpus, //delete me + <<::State as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me { // # Safety // We get a pointer to `GLOBAL_STATE` that will be initialized at this point in time. @@ -276,6 +279,8 @@ where OF: Feedback, E::State: State + HasExecutions + HasSolutions + HasCorpus, Z: HasObjective, + <::State as HasSolutions>::Solutions: Corpus, //delete me + <<::State as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me { let ret; #[cfg(feature = "std")] diff --git a/libafl/src/executors/hooks/unix.rs b/libafl/src/executors/hooks/unix.rs index 2a5c2355c6..90f1b98c75 100644 --- a/libafl/src/executors/hooks/unix.rs +++ b/libafl/src/executors/hooks/unix.rs @@ -9,6 +9,7 @@ pub mod unix_signal_handler { use libc::siginfo_t; use crate::{ + corpus::Corpus, events::{EventFirer, EventRestarter}, executors::{ common_signals, @@ -19,7 +20,7 @@ pub mod unix_signal_handler { feedbacks::Feedback, fuzzer::HasObjective, inputs::{Input, UsesInput}, - state::{HasCorpus, HasExecutions, HasSolutions}, + state::{HasCorpus, HasExecutions, HasSolutions, UsesState}, }; pub(crate) type HandlerFuncPtr = unsafe fn( @@ -80,6 +81,8 @@ pub mod unix_signal_handler { OF: Feedback, E::State: HasExecutions + HasSolutions + HasCorpus, Z: HasObjective, + <::State as HasSolutions>::Solutions: Corpus, //delete me + <<::State as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me { let old_hook = panic::take_hook(); panic::set_hook(Box::new(move |panic_info| unsafe { @@ -127,6 +130,8 @@ pub mod unix_signal_handler { OF: Feedback, E::State: HasExecutions + HasSolutions + HasCorpus, Z: HasObjective, + <::State as HasSolutions>::Solutions: Corpus, //delete me + <<::State as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me { // this stuff is for batch timeout if !data.executor_ptr.is_null() @@ -182,6 +187,8 @@ pub mod unix_signal_handler { OF: Feedback, E::State: HasExecutions + HasSolutions + HasCorpus, Z: HasObjective, + <::State as HasSolutions>::Solutions: Corpus, //delete me + <<::State as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me { #[cfg(all(target_os = "android", target_arch = "aarch64"))] let _context = _context.map(|p| { diff --git a/libafl/src/executors/hooks/windows.rs b/libafl/src/executors/hooks/windows.rs index 7aae4e50f4..982c319715 100644 --- a/libafl/src/executors/hooks/windows.rs +++ b/libafl/src/executors/hooks/windows.rs @@ -12,6 +12,7 @@ pub mod windows_asan_handler { }; use crate::{ + corpus::Corpus, events::{EventFirer, EventRestarter}, executors::{ hooks::inprocess::GLOBAL_STATE, inprocess::run_observers_and_save_state, Executor, @@ -20,7 +21,7 @@ pub mod windows_asan_handler { feedbacks::Feedback, fuzzer::HasObjective, inputs::UsesInput, - state::{HasCorpus, HasExecutions, HasSolutions}, + state::{HasCorpus, HasExecutions, HasSolutions, UsesState}, }; /// # Safety @@ -32,6 +33,8 @@ pub mod windows_asan_handler { OF: Feedback, E::State: HasExecutions + HasSolutions + HasCorpus, Z: HasObjective, + <::State as HasSolutions>::Solutions: Corpus, //delete me + <<::State as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me { let data = addr_of_mut!(GLOBAL_STATE); (*data).set_in_handler(true); @@ -125,6 +128,7 @@ pub mod windows_exception_handler { }; use crate::{ + corpus::Corpus, events::{EventFirer, EventRestarter}, executors::{ hooks::inprocess::{HasTimeout, InProcessExecutorHandlerData, GLOBAL_STATE}, @@ -134,7 +138,7 @@ pub mod windows_exception_handler { feedbacks::Feedback, fuzzer::HasObjective, inputs::{Input, UsesInput}, - state::{HasCorpus, HasExecutions, HasSolutions, State}, + state::{HasCorpus, HasExecutions, HasSolutions, State, UsesState}, }; pub(crate) type HandlerFuncPtr = @@ -180,6 +184,8 @@ pub mod windows_exception_handler { OF: Feedback, E::State: HasExecutions + HasSolutions + HasCorpus, Z: HasObjective, + <::State as HasSolutions>::Solutions: Corpus, //delete me + <<::State as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me { let old_hook = panic::take_hook(); panic::set_hook(Box::new(move |panic_info| unsafe { @@ -240,6 +246,8 @@ pub mod windows_exception_handler { OF: Feedback, E::State: State + HasExecutions + HasSolutions + HasCorpus, Z: HasObjective, + <::State as HasSolutions>::Solutions: Corpus, //delete me + <<::State as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me { let data: &mut InProcessExecutorHandlerData = &mut *(global_state as *mut InProcessExecutorHandlerData); @@ -310,6 +318,8 @@ pub mod windows_exception_handler { OF: Feedback, E::State: HasExecutions + HasSolutions + HasCorpus, Z: HasObjective, + <::State as HasSolutions>::Solutions: Corpus, //delete me + <<::State as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me { // Have we set a timer_before? if data.ptp_timer.is_some() { diff --git a/libafl/src/executors/inprocess/inner.rs b/libafl/src/executors/inprocess/inner.rs index e0d850ac93..7af363edec 100644 --- a/libafl/src/executors/inprocess/inner.rs +++ b/libafl/src/executors/inprocess/inner.rs @@ -16,6 +16,7 @@ use crate::executors::hooks::inprocess::HasTimeout; #[cfg(all(windows, feature = "std"))] use crate::executors::hooks::inprocess::HasTimeout; use crate::{ + corpus::Corpus, events::{EventFirer, EventRestarter}, executors::{ hooks::{ @@ -178,6 +179,8 @@ where OF: Feedback, S: State, Z: HasObjective, + <::State as HasSolutions>::Solutions: Corpus, //delete me + <<::State as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me { Self::with_timeout_generic::( user_hooks, @@ -205,6 +208,8 @@ where OF: Feedback, S: State, Z: HasObjective, + <::State as HasSolutions>::Solutions: Corpus, //delete me + <<::State as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me { let mut me = Self::with_timeout_generic::( user_hooks, observers, fuzzer, state, event_mgr, exec_tmout, @@ -235,6 +240,8 @@ where OF: Feedback, S: State, Z: HasObjective, + <::State as HasSolutions>::Solutions: Corpus, //delete me + <<::State as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me { let default = InProcessHooks::new::(timeout)?; let mut hooks = tuple_list!(default).merge(user_hooks); diff --git a/libafl/src/executors/inprocess/mod.rs b/libafl/src/executors/inprocess/mod.rs index adbe454af5..dea16e9581 100644 --- a/libafl/src/executors/inprocess/mod.rs +++ b/libafl/src/executors/inprocess/mod.rs @@ -168,6 +168,8 @@ where H: FnMut(&S::Input) -> ExitKind + ?Sized, OT: ObserversTuple, S: HasExecutions + HasSolutions + HasCorpus + State, + ::Solutions: Corpus, //delete me + <::Corpus as Corpus>::Input: Clone, //delete me { /// Create a new in mem executor with the default timeout (5 sec) pub fn new( @@ -211,6 +213,8 @@ where OF: Feedback, S: State, Z: HasObjective, + ::Solutions: Corpus, //delete me + <::Corpus as Corpus>::Input: Clone, //delete me { let inner = GenericInProcessExecutorInner::batched_timeout_generic::( tuple_list!(), @@ -250,6 +254,8 @@ where OF: Feedback, S: State, Z: HasObjective, + ::Solutions: Corpus, //delete me + <::Corpus as Corpus>::Input: Clone, //delete me { let inner = GenericInProcessExecutorInner::with_timeout_generic::( tuple_list!(), @@ -275,6 +281,8 @@ where HT: ExecutorHooksTuple, OT: ObserversTuple, S: State + HasExecutions + HasSolutions + HasCorpus, + ::Solutions: Corpus, //delete me + <::Corpus as Corpus>::Input: Clone, //delete me { /// Create a new in mem executor with the default timeout (5 sec) pub fn generic( @@ -320,6 +328,8 @@ where OF: Feedback, S: State, Z: HasObjective, + ::Solutions: Corpus, //delete me + <::Corpus as Corpus>::Input: Clone, //delete me { let inner = GenericInProcessExecutorInner::batched_timeout_generic::( user_hooks, observers, fuzzer, state, event_mgr, exec_tmout, @@ -355,6 +365,8 @@ where OF: Feedback, S: State, Z: HasObjective, + ::Solutions: Corpus, //delete me + <::Corpus as Corpus>::Input: Clone, //delete me { let inner = GenericInProcessExecutorInner::with_timeout_generic::( user_hooks, observers, fuzzer, state, event_mgr, timeout, @@ -431,7 +443,7 @@ where pub fn run_observers_and_save_state( executor: &mut E, state: &mut E::State, - input: &::Input, + input: &E::Input, fuzzer: &mut Z, event_mgr: &mut EM, exitkind: ExitKind, @@ -439,8 +451,9 @@ pub fn run_observers_and_save_state( E: HasObservers, EM: EventFirer + EventRestarter, OF: Feedback, - E::State: HasExecutions + HasSolutions + HasCorpus, + E::State: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase, Z: HasObjective, + <::State as HasSolutions>::Solutions: Corpus, //delete me { let mut observers = executor.observers_mut(); @@ -500,10 +513,11 @@ where E: Executor + HasObservers, EM: EventFirer + EventRestarter, OF: Feedback, - E::State: HasExecutions + HasSolutions + HasCorpus, + E::State: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase, Z: HasObjective + HasScheduler + ExecutionProcessor, + <::State as HasSolutions>::Solutions: Corpus, //delete me { let data = addr_of_mut!(GLOBAL_STATE); let in_handler = (*data).set_in_handler(true); diff --git a/libafl/src/executors/inprocess/stateful.rs b/libafl/src/executors/inprocess/stateful.rs index 969716f5aa..d162f64cdf 100644 --- a/libafl/src/executors/inprocess/stateful.rs +++ b/libafl/src/executors/inprocess/stateful.rs @@ -11,6 +11,7 @@ use core::{ use libafl_bolts::tuples::{tuple_list, RefIndexable}; use crate::{ + corpus::Corpus, events::{EventFirer, EventRestarter}, executors::{ hooks::{inprocess::InProcessHooks, ExecutorHooksTuple}, @@ -157,6 +158,8 @@ where H: FnMut(&mut ES, &mut S, &::Input) -> ExitKind + ?Sized, OT: ObserversTuple, S: HasExecutions + HasSolutions + HasCorpus + State, + ::Solutions: Corpus, //delete me + <::Corpus as Corpus>::Input: Clone, //delete me { /// Create a new in mem executor with the default timeout (5 sec) pub fn new( @@ -203,6 +206,8 @@ where OF: Feedback, S: State, Z: HasObjective, + ::Solutions: Corpus, //delete me + <::Corpus as Corpus>::Input: Clone, //delete me { let inner = GenericInProcessExecutorInner::batched_timeout_generic::( tuple_list!(), @@ -244,6 +249,8 @@ where OF: Feedback, S: State, Z: HasObjective, + ::Solutions: Corpus, //delete me + <::Corpus as Corpus>::Input: Clone, //delete me { let inner = GenericInProcessExecutorInner::with_timeout_generic::( tuple_list!(), @@ -289,6 +296,8 @@ where HT: ExecutorHooksTuple, OT: ObserversTuple, S: State + HasExecutions + HasSolutions + HasCorpus, + ::Solutions: Corpus, //delete me + <::Corpus as Corpus>::Input: Clone, //delete me { /// Create a new in mem executor with the default timeout (5 sec) pub fn generic( @@ -336,6 +345,8 @@ where OF: Feedback, S: State, Z: HasObjective, + ::Solutions: Corpus, //delete me + <::Corpus as Corpus>::Input: Clone, //delete me { let inner = GenericInProcessExecutorInner::batched_timeout_generic::( user_hooks, observers, fuzzer, state, event_mgr, exec_tmout, @@ -373,6 +384,8 @@ where OF: Feedback, S: State, Z: HasObjective, + ::Solutions: Corpus, //delete me + <::Corpus as Corpus>::Input: Clone, //delete me { let inner = GenericInProcessExecutorInner::with_timeout_generic::( user_hooks, observers, fuzzer, state, event_mgr, timeout, diff --git a/libafl/src/feedbacks/nautilus.rs b/libafl/src/feedbacks/nautilus.rs index 4b0d9e1caa..9b0061533f 100644 --- a/libafl/src/feedbacks/nautilus.rs +++ b/libafl/src/feedbacks/nautilus.rs @@ -82,7 +82,8 @@ impl<'a, S> Named for NautilusFeedback<'a, S> { impl<'a, S> Feedback for NautilusFeedback<'a, S> where - S: HasMetadata + HasCorpus + State, + S: HasMetadata + HasCorpus + State, + S::Corpus: Corpus, { #[allow(clippy::wrong_self_convention)] fn is_interesting( diff --git a/libafl/src/fuzzer/mod.rs b/libafl/src/fuzzer/mod.rs index 51d40a151a..d30b35dcf0 100644 --- a/libafl/src/fuzzer/mod.rs +++ b/libafl/src/fuzzer/mod.rs @@ -372,13 +372,9 @@ where CS: Scheduler, F: Feedback, OF: Feedback, - S: HasCorpus - + HasSolutions - + HasExecutions - + HasCorpus - + HasCurrentTestcase - + HasCurrentCorpusId - + State, + S: HasCorpus + HasSolutions + HasExecutions + HasCorpus + HasCurrentCorpusId + State, + S::Corpus: Corpus, //delete me + S::Solutions: Corpus, //delete me { fn check_results( &mut self, @@ -535,7 +531,7 @@ where &mut self, state: &mut Self::State, manager: &mut EM, - input: &::Input, + input: &S::Input, exec_res: &ExecuteInputResult, observers: &OT, ) -> Result, Error> @@ -596,6 +592,8 @@ where F: Feedback, OF: Feedback, S: HasCorpus + HasSolutions + HasExecutions + State, + S::Corpus: Corpus, //delete me + S::Solutions: Corpus, //delete me { /// Process one input, adding to the respective corpora if needed and firing the right events #[inline] @@ -629,6 +627,8 @@ where OF: Feedback, OT: ObserversTuple + Serialize + DeserializeOwned, S: HasCorpus + HasSolutions + HasExecutions + HasLastFoundTime + State, + S::Corpus: Corpus, //delete me + S::Solutions: Corpus, //delete me { /// Process one input, adding to the respective corpora if needed and firing the right events #[inline] @@ -765,8 +765,8 @@ where S: HasExecutions + HasMetadata + HasCorpus - + HasTestcase + HasLastReportTime + + HasTestcase + HasCurrentCorpusId + HasCurrentStageId + State, diff --git a/libafl/src/generators/gramatron.rs b/libafl/src/generators/gramatron.rs index 9bec0e4dd6..4320152e08 100644 --- a/libafl/src/generators/gramatron.rs +++ b/libafl/src/generators/gramatron.rs @@ -34,10 +34,7 @@ pub struct Automaton { #[derive(Clone, Debug)] /// Generates random inputs from a grammar automaton -pub struct GramatronGenerator<'a, S> -where - S: HasRand, -{ +pub struct GramatronGenerator<'a, S> { automaton: &'a Automaton, phantom: PhantomData, } diff --git a/libafl/src/generators/mod.rs b/libafl/src/generators/mod.rs index eeede7528d..e7e47b5fea 100644 --- a/libafl/src/generators/mod.rs +++ b/libafl/src/generators/mod.rs @@ -5,11 +5,7 @@ use core::marker::PhantomData; use libafl_bolts::rands::Rand; -use crate::{ - inputs::{bytes::BytesInput, Input}, - state::HasRand, - Error, -}; +use crate::{inputs::bytes::BytesInput, state::HasRand, Error}; pub mod gramatron; pub use gramatron::*; @@ -20,10 +16,7 @@ pub mod nautilus; pub use nautilus::*; /// Generators can generate ranges of bytes. -pub trait Generator -where - I: Input, -{ +pub trait Generator { /// Generate a new input fn generate(&mut self, state: &mut S) -> Result; } @@ -35,7 +28,6 @@ where impl Generator for T where T: Iterator, - I: Input, { fn generate(&mut self, _state: &mut S) -> Result { match self.next() { @@ -49,21 +41,13 @@ where /// An [`Iterator`] built from a [`Generator`]. #[derive(Debug)] -pub struct GeneratorIter<'a, I, S, G> -where - I: Input, - G: Generator, -{ +pub struct GeneratorIter<'a, I, S, G> { gen: G, state: &'a mut S, phantom: PhantomData, } -impl<'a, I, S, G> GeneratorIter<'a, I, S, G> -where - I: Input, - G: Generator, -{ +impl<'a, I, S, G> GeneratorIter<'a, I, S, G> { /// Create a new [`GeneratorIter`] pub fn new(gen: G, state: &'a mut S) -> Self { Self { @@ -76,7 +60,6 @@ where impl<'a, I, S, G> Iterator for GeneratorIter<'a, I, S, G> where - I: Input, G: Generator, { type Item = I; @@ -88,10 +71,7 @@ where #[derive(Clone, Debug)] /// Generates random bytes -pub struct RandBytesGenerator -where - S: HasRand, -{ +pub struct RandBytesGenerator { max_size: usize, phantom: PhantomData, } @@ -112,10 +92,7 @@ where } } -impl RandBytesGenerator -where - S: HasRand, -{ +impl RandBytesGenerator { /// Returns a new [`RandBytesGenerator`], generating up to `max_size` random bytes. #[must_use] pub fn new(max_size: usize) -> Self { @@ -128,10 +105,7 @@ where #[derive(Clone, Debug)] /// Generates random printable characters -pub struct RandPrintablesGenerator -where - S: HasRand, -{ +pub struct RandPrintablesGenerator { max_size: usize, phantom: PhantomData, } @@ -153,10 +127,7 @@ where } } -impl RandPrintablesGenerator -where - S: HasRand, -{ +impl RandPrintablesGenerator { /// Creates a new [`RandPrintablesGenerator`], generating up to `max_size` random printable characters. #[must_use] pub fn new(max_size: usize) -> Self { diff --git a/libafl/src/lib.rs b/libafl/src/lib.rs index 88047386ae..a78c547c54 100644 --- a/libafl/src/lib.rs +++ b/libafl/src/lib.rs @@ -135,7 +135,10 @@ mod tests { #[cfg(miri)] use libafl_bolts::serdeany::RegistryBuilder; - use libafl_bolts::{rands::StdRand, tuples::tuple_list}; + use libafl_bolts::{ + rands::{RomuDuoJrRand, StdRand}, + tuples::tuple_list, + }; #[cfg(miri)] use crate::stages::ExecutionCountRestartHelperMetadata; @@ -221,7 +224,15 @@ mod tests { InMemoryCorpus, StdRand, InMemoryCorpus, - > = postcard::from_bytes(state_serialized.as_slice()).unwrap(); + > = postcard::from_bytes::< + StdState< + BytesInput, + InMemoryCorpus, + RomuDuoJrRand, + InMemoryCorpus, + >, + >(state_serialized.as_slice()) + .unwrap(); assert_eq!(state.corpus().count(), state_deserialized.corpus().count()); let corpus_serialized = postcard::to_allocvec(state.corpus()).unwrap(); diff --git a/libafl/src/mutators/encoded_mutations.rs b/libafl/src/mutators/encoded_mutations.rs index f652cd0abe..6e07b02f74 100644 --- a/libafl/src/mutators/encoded_mutations.rs +++ b/libafl/src/mutators/encoded_mutations.rs @@ -10,7 +10,7 @@ use libafl_bolts::{ use crate::{ corpus::Corpus, - inputs::{EncodedInput, UsesInput}, + inputs::EncodedInput, mutators::{ mutations::{buffer_copy, buffer_self_copy, ARITH_MAX}, MutationResult, Mutator, Named, @@ -285,9 +285,10 @@ impl EncodedCopyMutator { #[derive(Debug, Default)] pub struct EncodedCrossoverInsertMutator; -impl Mutator for EncodedCrossoverInsertMutator +impl Mutator for EncodedCrossoverInsertMutator where - S: UsesInput + HasRand + HasCorpus + HasMaxSize, + S: HasRand + HasCorpus + HasMaxSize, + S::Corpus: Corpus, { fn mutate(&mut self, state: &mut S, input: &mut EncodedInput) -> Result { let size = input.codes().len(); @@ -355,9 +356,10 @@ impl EncodedCrossoverInsertMutator { #[derive(Debug, Default)] pub struct EncodedCrossoverReplaceMutator; -impl Mutator for EncodedCrossoverReplaceMutator +impl Mutator for EncodedCrossoverReplaceMutator where - S: UsesInput + HasRand + HasCorpus, + S: HasRand + HasCorpus, + S::Corpus: Corpus, { fn mutate(&mut self, state: &mut S, input: &mut EncodedInput) -> Result { let size = input.codes().len(); diff --git a/libafl/src/mutators/gramatron.rs b/libafl/src/mutators/gramatron.rs index 0787144e11..0c963c60b0 100644 --- a/libafl/src/mutators/gramatron.rs +++ b/libafl/src/mutators/gramatron.rs @@ -12,7 +12,7 @@ use libafl_bolts::{ use serde::{Deserialize, Serialize}; use crate::{ - corpus::{Corpus, HasTestcase}, + corpus::Corpus, generators::GramatronGenerator, inputs::{GramatronInput, Terminal}, mutators::{MutationResult, Mutator}, @@ -105,9 +105,10 @@ impl GramatronIdxMapMetadata { #[derive(Default, Debug)] pub struct GramatronSpliceMutator; -impl Mutator for GramatronSpliceMutator +impl Mutator for GramatronSpliceMutator where - S: HasRand + HasCorpus + HasMetadata + HasTestcase, + S: HasRand + HasCorpus + HasMetadata, + S::Corpus: Corpus, { fn mutate( &mut self, diff --git a/libafl/src/mutators/havoc_mutations.rs b/libafl/src/mutators/havoc_mutations.rs index 91a9b654a0..0e278e0475 100644 --- a/libafl/src/mutators/havoc_mutations.rs +++ b/libafl/src/mutators/havoc_mutations.rs @@ -49,8 +49,7 @@ pub type HavocMutationsNoCrossoverType = tuple_list_type!( ); /// Tuple type of the mutations that compose the Havoc mutator's crossover mutations -pub type HavocCrossoverType = - tuple_list_type!(CrossoverInsertMutator, CrossoverReplaceMutator); +pub type HavocCrossoverType = tuple_list_type!(CrossoverInsertMutator, CrossoverReplaceMutator); /// Tuple type of the mutations that compose the Havoc mutator's crossover mutations for mapped input types pub type MappedHavocCrossoverType = tuple_list_type!( @@ -59,7 +58,7 @@ pub type MappedHavocCrossoverType = tuple_list_type!( ); /// Tuple type of the mutations that compose the Havoc mutator -pub type HavocMutationsType = tuple_list_type!( +pub type HavocMutationsType = tuple_list_type!( BitFlipMutator, ByteFlipMutator, ByteIncMutator, @@ -85,8 +84,8 @@ pub type HavocMutationsType = tuple_list_type!( BytesCopyMutator, BytesInsertCopyMutator, BytesSwapMutator, - CrossoverInsertMutator, - CrossoverReplaceMutator, + CrossoverInsertMutator, + CrossoverReplaceMutator, ); /// Tuple type of the mutations that compose the Havoc mutator for mapped input types @@ -193,7 +192,7 @@ pub fn havoc_mutations_no_crossover() -> HavocMutationsNoCrossoverType { /// Get the mutations that compose the Havoc mutator's crossover strategy #[must_use] -pub fn havoc_crossover() -> HavocCrossoverType { +pub fn havoc_crossover() -> HavocCrossoverType { tuple_list!( CrossoverInsertMutator::new(), CrossoverReplaceMutator::new(), @@ -228,7 +227,7 @@ where /// Get the mutations that compose the Havoc mutator #[must_use] -pub fn havoc_mutations() -> HavocMutationsType { +pub fn havoc_mutations() -> HavocMutationsType { havoc_mutations_no_crossover().merge(havoc_crossover()) } diff --git a/libafl/src/mutators/mod.rs b/libafl/src/mutators/mod.rs index ffe736c5f0..73ab635a1d 100644 --- a/libafl/src/mutators/mod.rs +++ b/libafl/src/mutators/mod.rs @@ -161,12 +161,6 @@ pub trait MutatorsTuple: HasLen { corpus_id: Option, ) -> Result<(), Error>; - - /// Gets all names of the wrapped [`Mutator`]`s`, reversed. - fn names_reversed(&self) -> Vec<&str>; - - /// Gets all names of the wrapped [`Mutator`]`s`. - fn names(&self) -> Vec<&str>; } impl MutatorsTuple for () { @@ -203,16 +197,6 @@ impl MutatorsTuple for () { ) -> Result<(), Error> { Ok(()) } - - #[inline] - fn names_reversed(&self) -> Vec<&str> { - Vec::new() - } - - #[inline] - fn names(&self) -> Vec<&str> { - Vec::new() - } } impl MutatorsTuple for (Head, Tail) @@ -263,18 +247,6 @@ where self.1.get_and_post_exec(index - 1, state, new_corpus_id) } } - - fn names_reversed(&self) -> Vec<&str> { - let mut ret = self.1.names_reversed(); - ret.push(self.0.name()); - ret - } - - fn names(&self) -> Vec<&str> { - let mut ret = self.names_reversed(); - ret.reverse(); - ret - } } impl IntoVec>> for (Head, Tail) @@ -329,14 +301,6 @@ where ) -> Result<(), Error> { self.0.get_and_post_exec(index, state, new_corpus_id) } - - fn names(&self) -> Vec<&str> { - self.0.names() - } - - fn names_reversed(&self) -> Vec<&str> { - self.0.names_reversed() - } } impl IntoVec>> for (Tail,) @@ -394,14 +358,6 @@ impl MutatorsTuple for Vec>> { .ok_or_else(|| Error::key_not_found("Mutator with id {index:?} not found."))?; mutator.post_exec(state, new_corpus_id) } - - fn names_reversed(&self) -> Vec<&str> { - self.iter().rev().map(|x| x.name().as_ref()).collect() - } - - fn names(&self) -> Vec<&str> { - self.iter().map(|x| x.name().as_ref()).collect() - } } impl IntoVec>> for Vec>> { diff --git a/libafl/src/mutators/mopt_mutator.rs b/libafl/src/mutators/mopt_mutator.rs index c1689e0985..cf7aa56aa5 100644 --- a/libafl/src/mutators/mopt_mutator.rs +++ b/libafl/src/mutators/mopt_mutator.rs @@ -3,13 +3,11 @@ //! It uses a modified Particle Swarm Optimization algorithm to determine an optimal distribution of mutators. //! See and use alloc::{borrow::Cow, string::ToString, vec::Vec}; -use core::{ - fmt::{self, Debug}, - marker::PhantomData, -}; +use core::fmt::{self, Debug}; use libafl_bolts::{ rands::{Rand, StdRand}, + tuples::NamedTuple, Named, }; use serde::{Deserialize, Serialize}; @@ -363,35 +361,16 @@ pub enum MOptMode { /// This is the main struct of `MOpt`, an `AFL` mutator. /// See the original `MOpt` implementation in -pub struct StdMOptMutator -where - MT: MutatorsTuple, - S: HasRand + HasMetadata + HasCorpus + HasSolutions, -{ +#[derive(Debug)] +pub struct StdMOptMutator { name: Cow<'static, str>, mode: MOptMode, finds_before: usize, mutations: MT, max_stack_pow: usize, - phantom: PhantomData<(I, S)>, } -impl Debug for StdMOptMutator -where - MT: MutatorsTuple, - S: HasRand + HasMetadata + HasCorpus + HasSolutions, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "StdMOptMutator with {} mutations for Input type {}", - self.mutations.len(), - core::any::type_name::() - ) - } -} - -impl Mutator for StdMOptMutator +impl Mutator for StdMOptMutator where MT: MutatorsTuple, S: HasRand + HasMetadata + HasCorpus + HasSolutions, @@ -516,21 +495,21 @@ where } } -impl StdMOptMutator -where - MT: MutatorsTuple, - S: HasRand + HasMetadata + HasCorpus + HasSolutions, -{ +impl StdMOptMutator { /// Create a new [`StdMOptMutator`]. - pub fn new( + pub fn new( state: &mut S, mutations: MT, max_stack_pow: usize, swarm_num: usize, - ) -> Result { + ) -> Result + where + S: HasMetadata + HasRand, + MT: NamedTuple, + { if !state.has_metadata::() { let rand_seed = state.rand_mut().next(); - state.add_metadata::(MOpt::new(mutations.len(), swarm_num, rand_seed)?); + state.add_metadata::(MOpt::new(MT::LEN, swarm_num, rand_seed)?); } Ok(Self { name: Cow::from(format!("StdMOptMutator[{}]", mutations.names().join(","))), @@ -538,10 +517,13 @@ where finds_before: 0, mutations, max_stack_pow, - phantom: PhantomData, }) } - fn core_mutate(&mut self, state: &mut S, input: &mut I) -> Result { + fn core_mutate(&mut self, state: &mut S, input: &mut I) -> Result + where + S: HasMetadata + HasRand + HasSolutions + HasCorpus, + MT: MutatorsTuple, + { let mut r = MutationResult::Skipped; let mopt = state.metadata_map_mut().get_mut::().unwrap(); for i in 0..mopt.operator_num { @@ -564,7 +546,11 @@ where Ok(r) } - fn pilot_mutate(&mut self, state: &mut S, input: &mut I) -> Result { + fn pilot_mutate(&mut self, state: &mut S, input: &mut I) -> Result + where + S: HasMetadata + HasRand + HasSolutions + HasCorpus, + MT: MutatorsTuple, + { let mut r = MutationResult::Skipped; let swarm_now; { @@ -595,11 +581,9 @@ where } } -impl ComposedByMutations for StdMOptMutator -where - MT: MutatorsTuple, - S: HasRand + HasMetadata + HasCorpus + HasSolutions, -{ +impl ComposedByMutations for StdMOptMutator { + type Mutations = MT; + /// Get the mutations #[inline] fn mutations(&self) -> &MT { @@ -613,17 +597,13 @@ where } } -impl Named for StdMOptMutator -where - MT: MutatorsTuple, - S: HasRand + HasMetadata + HasCorpus + HasSolutions, -{ +impl Named for StdMOptMutator { fn name(&self) -> &Cow<'static, str> { &self.name } } -impl ScheduledMutator for StdMOptMutator +impl ScheduledMutator for StdMOptMutator where MT: MutatorsTuple, S: HasRand + HasMetadata + HasCorpus + HasSolutions, diff --git a/libafl/src/mutators/multi.rs b/libafl/src/mutators/multi.rs index fa3405703f..bebe923b4d 100644 --- a/libafl/src/mutators/multi.rs +++ b/libafl/src/mutators/multi.rs @@ -114,10 +114,11 @@ impl_default_multipart!( I2SRandReplace, ); -impl Mutator, S> for CrossoverInsertMutator +impl Mutator, S> for CrossoverInsertMutator where - S: HasCorpus> + HasMaxSize + HasRand, + S: HasCorpus + HasMaxSize + HasRand, I: Input + HasMutatorBytes, + S::Corpus: Corpus>, { fn mutate( &mut self, @@ -224,10 +225,11 @@ where } } -impl Mutator, S> for CrossoverReplaceMutator +impl Mutator, S> for CrossoverReplaceMutator where - S: HasCorpus> + HasMaxSize + HasRand, + S: HasCorpus + HasMaxSize + HasRand, I: Input + HasMutatorBytes, + S::Corpus: Corpus>, { fn mutate( &mut self, diff --git a/libafl/src/mutators/mutations.rs b/libafl/src/mutators/mutations.rs index 93e9d09920..b0d31870d6 100644 --- a/libafl/src/mutators/mutations.rs +++ b/libafl/src/mutators/mutations.rs @@ -10,7 +10,7 @@ use libafl_bolts::{rands::Rand, Named}; use crate::{ corpus::Corpus, - inputs::{HasMutatorBytes, UsesInput}, + inputs::HasMutatorBytes, mutators::{MutationResult, Mutator}, random_corpus_id_with_disabled, state::{HasCorpus, HasMaxSize, HasRand}, @@ -1025,18 +1025,19 @@ impl BytesSwapMutator { /// Crossover insert mutation for inputs with a bytes vector #[derive(Debug, Default)] -pub struct CrossoverInsertMutator { - phantom: PhantomData, -} +pub struct CrossoverInsertMutator; -impl CrossoverInsertMutator { - pub(crate) fn crossover_insert( +impl CrossoverInsertMutator { + pub(crate) fn crossover_insert( input: &mut I, size: usize, target: usize, range: Range, other: &[u8], - ) -> MutationResult { + ) -> MutationResult + where + I: HasMutatorBytes, + { input.resize(size + range.len(), 0); unsafe { buffer_self_copy( @@ -1054,10 +1055,10 @@ impl CrossoverInsertMutator { } } -impl Mutator for CrossoverInsertMutator +impl Mutator for CrossoverInsertMutator where S: HasCorpus + HasRand + HasMaxSize, - S::Input: HasMutatorBytes, + ::Input: HasMutatorBytes, I: HasMutatorBytes, { fn mutate(&mut self, state: &mut S, input: &mut I) -> Result { @@ -1101,36 +1102,35 @@ where } } -impl Named for CrossoverInsertMutator { +impl Named for CrossoverInsertMutator { fn name(&self) -> &Cow<'static, str> { static NAME: Cow<'static, str> = Cow::Borrowed("CrossoverInsertMutator"); &NAME } } -impl CrossoverInsertMutator { +impl CrossoverInsertMutator { /// Creates a new [`CrossoverInsertMutator`]. #[must_use] pub fn new() -> Self { - Self { - phantom: PhantomData, - } + Self {} } } /// Crossover replace mutation for inputs with a bytes vector #[derive(Debug, Default)] -pub struct CrossoverReplaceMutator { - phantom: PhantomData, -} +pub struct CrossoverReplaceMutator; -impl CrossoverReplaceMutator { - pub(crate) fn crossover_replace( +impl CrossoverReplaceMutator { + pub(crate) fn crossover_replace( input: &mut I, target: usize, range: Range, other: &[u8], - ) -> MutationResult { + ) -> MutationResult + where + I: HasMutatorBytes, + { unsafe { buffer_copy(input.bytes_mut(), other, range.start, target, range.len()); } @@ -1138,10 +1138,10 @@ impl CrossoverReplaceMutator { } } -impl Mutator for CrossoverReplaceMutator +impl Mutator for CrossoverReplaceMutator where S: HasCorpus + HasRand, - S::Input: HasMutatorBytes, + ::Input: HasMutatorBytes, I: HasMutatorBytes, { fn mutate(&mut self, state: &mut S, input: &mut I) -> Result { @@ -1178,20 +1178,18 @@ where } } -impl Named for CrossoverReplaceMutator { +impl Named for CrossoverReplaceMutator { fn name(&self) -> &Cow<'static, str> { static NAME: Cow<'static, str> = Cow::Borrowed("CrossoverReplaceMutator"); &NAME } } -impl CrossoverReplaceMutator { +impl CrossoverReplaceMutator { /// Creates a new [`CrossoverReplaceMutator`]. #[must_use] pub fn new() -> Self { - Self { - phantom: PhantomData, - } + Self {} } } @@ -1244,11 +1242,11 @@ impl MappedCrossoverInsertMutator { impl Mutator for MappedCrossoverInsertMutator where - S: HasCorpus + HasMaxSize + HasRand + UsesInput, + S: HasCorpus + HasMaxSize + HasRand, I: HasMutatorBytes, for<'a> O: IntoOptionBytes, for<'a> O::Type<'a>: IntoOptionBytes, - for<'a> F: Fn(&'a S::Input) -> ::Type<'a>, + for<'a> F: Fn(&'a ::Input) -> ::Type<'a>, { fn mutate(&mut self, state: &mut S, input: &mut I) -> Result { let size = input.bytes().len(); @@ -1324,11 +1322,11 @@ impl MappedCrossoverReplaceMutator { impl Mutator for MappedCrossoverReplaceMutator where - S: HasCorpus + HasMaxSize + HasRand + UsesInput, + S: HasCorpus + HasMaxSize + HasRand, I: HasMutatorBytes, O: IntoOptionBytes, for<'a> O::Type<'a>: IntoOptionBytes, - for<'a> F: Fn(&'a S::Input) -> ::Type<'a>, + for<'a> F: Fn(&'a ::Input) -> ::Type<'a>, { fn mutate(&mut self, state: &mut S, input: &mut I) -> Result { let size = input.bytes().len(); @@ -1404,13 +1402,14 @@ fn locate_diffs(this: &[u8], other: &[u8]) -> (i64, i64) { #[derive(Debug, Default)] pub struct SpliceMutator; -impl Mutator for SpliceMutator +impl Mutator for SpliceMutator where S: HasCorpus + HasRand, - S::Input: HasMutatorBytes, + ::Input: HasMutatorBytes, + I: HasMutatorBytes, { #[allow(clippy::cast_sign_loss)] - fn mutate(&mut self, state: &mut S, input: &mut S::Input) -> Result { + fn mutate(&mut self, state: &mut S, input: &mut I) -> Result { let id = random_corpus_id_with_disabled!(state.corpus(), state.rand_mut()); // We don't want to use the testcase we're already using for splicing if let Some(cur) = state.corpus().current() { diff --git a/libafl/src/mutators/nautilus.rs b/libafl/src/mutators/nautilus.rs index e85431e648..02ee3a50c0 100644 --- a/libafl/src/mutators/nautilus.rs +++ b/libafl/src/mutators/nautilus.rs @@ -162,7 +162,7 @@ impl Debug for NautilusSpliceMutator<'_> { impl Mutator for NautilusSpliceMutator<'_> where - S: HasCorpus + HasMetadata + HasRand, + S: HasCorpus + HasMetadata + HasRand, { fn mutate( &mut self, diff --git a/libafl/src/mutators/scheduled.rs b/libafl/src/mutators/scheduled.rs index 850cfc959d..66729b2627 100644 --- a/libafl/src/mutators/scheduled.rs +++ b/libafl/src/mutators/scheduled.rs @@ -2,14 +2,13 @@ use alloc::{borrow::Cow, vec::Vec}; use core::{ - fmt::{self, Debug}, - marker::PhantomData, + fmt::Debug, ops::{Deref, DerefMut}, }; use libafl_bolts::{ rands::Rand, - tuples::{tuple_list, tuple_list_type, NamedTuple}, + tuples::{tuple_list, tuple_list_type, HasConstLen, NamedTuple}, Named, }; use serde::{Deserialize, Serialize}; @@ -60,21 +59,20 @@ impl LogMutationMetadata { } /// A [`Mutator`] that composes multiple mutations into one. -pub trait ComposedByMutations -where - MT: MutatorsTuple, -{ +pub trait ComposedByMutations { + /// The mutations of this + type Mutations; /// Get the mutations - fn mutations(&self) -> &MT; + fn mutations(&self) -> &Self::Mutations; /// Get the mutations (mutable) - fn mutations_mut(&mut self) -> &mut MT; + fn mutations_mut(&mut self) -> &mut Self::Mutations; } /// A [`Mutator`] scheduling multiple [`Mutator`]s for an input. -pub trait ScheduledMutator: ComposedByMutations + Mutator +pub trait ScheduledMutator: ComposedByMutations + Mutator where - MT: MutatorsTuple, + Self::Mutations: MutatorsTuple, { /// Compute the number of iterations used to apply stacked mutations fn iterations(&self, state: &mut S, input: &I) -> u64; @@ -99,43 +97,20 @@ where } /// A [`Mutator`] that schedules one of the embedded mutations on each call. -pub struct StdScheduledMutator -where - MT: MutatorsTuple, - S: HasRand, -{ +#[derive(Debug)] +pub struct StdScheduledMutator { name: Cow<'static, str>, mutations: MT, max_stack_pow: usize, - phantom: PhantomData<(I, S)>, } -impl Debug for StdScheduledMutator -where - MT: MutatorsTuple, - S: HasRand, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "StdScheduledMutator with {} mutations for Input type {}", - self.mutations.len(), - core::any::type_name::() - ) - } -} - -impl Named for StdScheduledMutator -where - MT: MutatorsTuple, - S: HasRand, -{ +impl Named for StdScheduledMutator { fn name(&self) -> &Cow<'static, str> { &self.name } } -impl Mutator for StdScheduledMutator +impl Mutator for StdScheduledMutator where MT: MutatorsTuple, S: HasRand, @@ -146,11 +121,8 @@ where } } -impl ComposedByMutations for StdScheduledMutator -where - MT: MutatorsTuple, - S: HasRand, -{ +impl ComposedByMutations for StdScheduledMutator { + type Mutations = MT; /// Get the mutations #[inline] fn mutations(&self) -> &MT { @@ -164,7 +136,7 @@ where } } -impl ScheduledMutator for StdScheduledMutator +impl ScheduledMutator for StdScheduledMutator where MT: MutatorsTuple, S: HasRand, @@ -181,10 +153,9 @@ where } } -impl StdScheduledMutator +impl StdScheduledMutator where - MT: MutatorsTuple, - S: HasRand, + MT: NamedTuple, { /// Create a new [`StdScheduledMutator`] instance specifying mutations pub fn new(mutations: MT) -> Self { @@ -195,7 +166,6 @@ where )), mutations, max_stack_pow: 7, - phantom: PhantomData, } } @@ -208,7 +178,6 @@ where )), mutations, max_stack_pow, - phantom: PhantomData, } } } @@ -220,50 +189,24 @@ pub fn tokens_mutations() -> tuple_list_type!(TokenInsert, TokenReplace) { } /// A logging [`Mutator`] that wraps around a [`StdScheduledMutator`]. -pub struct LoggerScheduledMutator -where - MT: MutatorsTuple + NamedTuple, - S: HasRand + HasCorpus, - SM: ScheduledMutator, -{ +#[derive(Debug)] +pub struct LoggerScheduledMutator { name: Cow<'static, str>, scheduled: SM, mutation_log: Vec, - phantom: PhantomData<(I, MT, S)>, } -impl Debug for LoggerScheduledMutator -where - MT: MutatorsTuple + NamedTuple, - S: HasRand + HasCorpus, - SM: ScheduledMutator, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "LoggerScheduledMutator with {} mutations for Input type {}", - MT::LEN, - core::any::type_name::() - ) - } -} - -impl Named for LoggerScheduledMutator -where - MT: MutatorsTuple + NamedTuple, - S: HasRand + HasCorpus, - SM: ScheduledMutator, -{ +impl Named for LoggerScheduledMutator { fn name(&self) -> &Cow<'static, str> { &self.name } } -impl Mutator for LoggerScheduledMutator +impl Mutator for LoggerScheduledMutator where - MT: MutatorsTuple + NamedTuple, S: HasRand + HasCorpus, - SM: ScheduledMutator, + SM: ScheduledMutator, + SM::Mutations: MutatorsTuple + NamedTuple, { fn mutate(&mut self, state: &mut S, input: &mut I) -> Result { self.scheduled_mutate(state, input) @@ -286,28 +229,27 @@ where } } -impl ComposedByMutations for LoggerScheduledMutator +impl ComposedByMutations for LoggerScheduledMutator where - MT: MutatorsTuple + NamedTuple, - S: HasRand + HasCorpus, - SM: ScheduledMutator, + SM: ComposedByMutations, { + type Mutations = SM::Mutations; #[inline] - fn mutations(&self) -> &MT { + fn mutations(&self) -> &SM::Mutations { self.scheduled.mutations() } #[inline] - fn mutations_mut(&mut self) -> &mut MT { + fn mutations_mut(&mut self) -> &mut SM::Mutations { self.scheduled.mutations_mut() } } -impl ScheduledMutator for LoggerScheduledMutator +impl ScheduledMutator for LoggerScheduledMutator where - MT: MutatorsTuple + NamedTuple, S: HasRand + HasCorpus, - SM: ScheduledMutator, + SM: ScheduledMutator, + SM::Mutations: MutatorsTuple + NamedTuple, { /// Compute the number of iterations used to apply stacked mutations fn iterations(&self, state: &mut S, _: &I) -> u64 { @@ -316,8 +258,11 @@ where /// Get the next mutation to apply fn schedule(&self, state: &mut S, _: &I) -> MutationId { - debug_assert!(MT::LEN != 0); - state.rand_mut().below(MT::LEN).into() + debug_assert!(::LEN != 0); + state + .rand_mut() + .below(::LEN) + .into() } fn scheduled_mutate(&mut self, state: &mut S, input: &mut I) -> Result { @@ -336,11 +281,9 @@ where } } -impl LoggerScheduledMutator +impl LoggerScheduledMutator where - MT: MutatorsTuple + NamedTuple, - S: HasRand + HasCorpus, - SM: ScheduledMutator, + SM: Named, { /// Create a new [`LoggerScheduledMutator`] instance without mutations and corpus /// This mutator logs all mutators. @@ -349,7 +292,6 @@ where name: Cow::from(format!("LoggerScheduledMutator[{}]", scheduled.name())), scheduled, mutation_log: vec![], - phantom: PhantomData, } } } diff --git a/libafl/src/mutators/token_mutations.rs b/libafl/src/mutators/token_mutations.rs index 8355ed92a2..eb112fae31 100644 --- a/libafl/src/mutators/token_mutations.rs +++ b/libafl/src/mutators/token_mutations.rs @@ -24,7 +24,7 @@ use serde::{Deserialize, Serialize}; use crate::mutators::str_decode; use crate::{ corpus::{CorpusId, HasCurrentCorpusId}, - inputs::{HasMutatorBytes, UsesInput}, + inputs::HasMutatorBytes, mutators::{ buffer_self_copy, mutations::buffer_copy, MultiMutator, MutationResult, Mutator, Named, }, @@ -367,7 +367,7 @@ pub struct TokenReplace; impl Mutator for TokenReplace where - S: UsesInput + HasMetadata + HasRand + HasMaxSize, + S: HasMetadata + HasRand + HasMaxSize, I: HasMutatorBytes, { fn mutate(&mut self, state: &mut S, input: &mut I) -> Result { @@ -426,7 +426,7 @@ pub struct I2SRandReplace; impl Mutator for I2SRandReplace where - S: UsesInput + HasMetadata + HasRand + HasMaxSize, + S: HasMetadata + HasRand + HasMaxSize, I: HasMutatorBytes, { #[allow(clippy::too_many_lines)] @@ -621,7 +621,7 @@ where impl Mutator for I2SRandReplaceBinonly where - S: UsesInput + HasMetadata + HasRand + HasMaxSize, + S: HasMetadata + HasRand + HasMaxSize, I: HasMutatorBytes, { #[allow(clippy::too_many_lines)] @@ -1294,7 +1294,7 @@ impl AFLppRedQueen { impl MultiMutator for AFLppRedQueen where - S: UsesInput + HasMetadata + HasRand + HasMaxSize + HasCorpus + HasCurrentCorpusId, + S: HasMetadata + HasRand + HasMaxSize + HasCorpus + HasCurrentCorpusId, I: HasMutatorBytes + From>, { #[allow(clippy::needless_range_loop)] diff --git a/libafl/src/mutators/tuneable.rs b/libafl/src/mutators/tuneable.rs index 7e9c79b27b..449c49c502 100644 --- a/libafl/src/mutators/tuneable.rs +++ b/libafl/src/mutators/tuneable.rs @@ -4,13 +4,11 @@ //! a specific mutator for a specified amount of iterations use alloc::{borrow::Cow, vec::Vec}; -use core::{ - fmt::{self, Debug}, - marker::PhantomData, -}; +use core::fmt::Debug; use libafl_bolts::{ - impl_serdeany, math::calculate_cumulative_distribution_in_place, rands::Rand, Named, + impl_serdeany, math::calculate_cumulative_distribution_in_place, rands::Rand, + tuples::NamedTuple, Named, }; use serde::{Deserialize, Serialize}; @@ -81,33 +79,14 @@ impl TuneableScheduledMutatorMetadata { /// A [`Mutator`] that schedules one of the embedded mutations on each call. /// The index of the next mutation can be set. -pub struct TuneableScheduledMutator -where - MT: MutatorsTuple, - S: HasRand, -{ +#[derive(Debug)] +pub struct TuneableScheduledMutator { name: Cow<'static, str>, mutations: MT, max_stack_pow: usize, - phantom: PhantomData<(I, S)>, } -impl Debug for TuneableScheduledMutator -where - MT: MutatorsTuple, - S: HasRand, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "TuneableScheduledMutator with {} mutations for Input type {}", - self.mutations.len(), - core::any::type_name::() - ) - } -} - -impl Mutator for TuneableScheduledMutator +impl Mutator for TuneableScheduledMutator where MT: MutatorsTuple, S: HasRand + HasMetadata, @@ -118,11 +97,8 @@ where } } -impl ComposedByMutations for TuneableScheduledMutator -where - MT: MutatorsTuple, - S: HasRand, -{ +impl ComposedByMutations for TuneableScheduledMutator { + type Mutations = MT; /// Get the mutations #[inline] fn mutations(&self) -> &MT { @@ -136,17 +112,13 @@ where } } -impl Named for TuneableScheduledMutator -where - MT: MutatorsTuple, - S: HasRand, -{ +impl Named for TuneableScheduledMutator { fn name(&self) -> &Cow<'static, str> { &self.name } } -impl ScheduledMutator for TuneableScheduledMutator +impl ScheduledMutator for TuneableScheduledMutator where MT: MutatorsTuple, S: HasRand + HasMetadata, @@ -228,13 +200,13 @@ where } } -impl TuneableScheduledMutator -where - MT: MutatorsTuple, - S: HasRand + HasMetadata, -{ +impl TuneableScheduledMutator { /// Create a new [`TuneableScheduledMutator`] instance specifying mutations - pub fn new(state: &mut S, mutations: MT) -> Self { + pub fn new(state: &mut S, mutations: MT) -> Self + where + MT: NamedTuple, + S: HasRand + HasMetadata, + { if !state.has_metadata::() { state.add_metadata(TuneableScheduledMutatorMetadata::default()); } @@ -242,36 +214,22 @@ where name: Cow::from(format!("TuneableMutator[{}]", mutations.names().join(", "))), mutations, max_stack_pow: 7, - phantom: PhantomData, } } } -impl TuneableScheduledMutator<(), (), S> -where - S: HasRand + HasMetadata, -{ - fn metadata_mut(state: &mut S) -> &mut TuneableScheduledMutatorMetadata { - state - .metadata_map_mut() - .get_mut::() - .unwrap() - } - - fn metadata(state: &S) -> &TuneableScheduledMutatorMetadata { - state - .metadata_map() - .get::() - .unwrap() - } - +impl TuneableScheduledMutator { /// Sets the next iterations count, i.e., how many times to mutate the input /// /// Using `set_mutation_ids_and_iter` to set multiple values at the same time /// will be faster than setting them individually /// as it internally only needs a single metadata lookup - pub fn set_iters(state: &mut S, iters: u64) { - let metadata = Self::metadata_mut(state); + pub fn set_iters(&self, state: &mut S, iters: u64) + where + S: HasMetadata, + { + let metadata = TuneableScheduledMutatorMetadata::get_mut(state).unwrap(); + metadata.iters = Some(iters); metadata.iter_probabilities_pow_cumulative.clear(); } @@ -285,16 +243,20 @@ where /// These will be applied for each call of this `mutate` function. /// /// Setting this function will unset everything previously set in `set_iters`. - pub fn set_iter_probabilities_pow( + pub fn set_iter_probabilities_pow( + &self, state: &mut S, mut iter_probabilities_pow: Vec, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + S: HasMetadata, + { if iter_probabilities_pow.len() >= 32 { return Err(Error::illegal_argument( "Cannot stack more than 2^32 mutations", )); } - let metadata = Self::metadata_mut(state); + let metadata = TuneableScheduledMutatorMetadata::get_mut(state).unwrap(); metadata.iters = None; // we precalculate the cumulative probability to be faster when sampling later. @@ -305,13 +267,19 @@ where } /// Gets the set amount of iterations - pub fn get_iters(state: &S) -> Option { - let metadata = Self::metadata(state); + pub fn get_iters(&self, state: &S) -> Option + where + S: HasMetadata, + { + let metadata = TuneableScheduledMutatorMetadata::get(state).unwrap(); metadata.iters } /// Sets the mutation ids - pub fn set_mutation_ids(state: &mut S, mutations: Vec) { + pub fn set_mutation_ids(&self, state: &mut S, mutations: Vec) + where + S: HasMetadata, + { let metadata = TuneableScheduledMutatorMetadata::get_mut(state).unwrap(); metadata.mutation_ids = mutations; metadata.next_id = 0.into(); @@ -321,10 +289,14 @@ where /// The `Vec` contains a probability per [`MutationId`]: between 0 and 1, and they have to add /// up to 1. /// Setting the probabilities will remove the value set through `set_mutation_ids`. - pub fn set_mutation_probabilities( + pub fn set_mutation_probabilities( + &self, state: &mut S, mut mutation_probabilities: Vec, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + S: HasMetadata, + { let metadata = TuneableScheduledMutatorMetadata::get_mut(state).unwrap(); metadata.mutation_ids.clear(); metadata.next_id = 0.into(); @@ -336,7 +308,14 @@ where } /// mutation ids and iterations - pub fn set_mutation_ids_and_iters(state: &mut S, mutations: Vec, iters: u64) { + pub fn set_mutation_ids_and_iters( + &self, + state: &mut S, + mutations: Vec, + iters: u64, + ) where + S: HasMetadata, + { let metadata = TuneableScheduledMutatorMetadata::get_mut(state).unwrap(); metadata.mutation_ids = mutations; metadata.next_id = 0.into(); @@ -344,14 +323,23 @@ where } /// Appends a mutation id to the end of the mutations - pub fn push_mutation_id(state: &mut S, mutation_id: MutationId) { + pub fn push_mutation_id(state: &mut S, mutation_id: MutationId) + where + S: HasMetadata, + { let metadata = TuneableScheduledMutatorMetadata::get_mut(state).unwrap(); metadata.mutation_ids.push(mutation_id); } /// Resets this to a randomic mutational stage - pub fn reset(state: &mut S) { - let metadata = Self::metadata_mut(state); + pub fn reset(self, state: &mut S) + where + S: HasMetadata, + { + let metadata = state + .metadata_map_mut() + .get_mut::() + .unwrap(); metadata.mutation_ids.clear(); metadata.next_id = 0.into(); metadata.iters = None; @@ -417,44 +405,36 @@ mod test { let input = BytesInput::new(vec![42]); // Basic tests over the probability distribution. - assert!( - TuneableScheduledMutator::set_mutation_probabilities(&mut state, vec![0.0]).is_err() - ); - assert!( - TuneableScheduledMutator::set_mutation_probabilities(&mut state, vec![1.0; 3]).is_err() - ); - assert!(TuneableScheduledMutator::set_mutation_probabilities( - &mut state, - vec![-1.0, 1.0, 1.0] - ) - .is_err()); - assert!(TuneableScheduledMutator::set_mutation_probabilities(&mut state, vec![]).is_err()); + assert!(tuneable + .set_mutation_probabilities(&mut state, vec![0.0]) + .is_err()); + assert!(tuneable + .set_mutation_probabilities(&mut state, vec![1.0; 3]) + .is_err()); + assert!(tuneable + .set_mutation_probabilities(&mut state, vec![-1.0, 1.0, 1.0]) + .is_err()); + assert!(tuneable + .set_mutation_probabilities(&mut state, vec![]) + .is_err()); - assert!(TuneableScheduledMutator::set_mutation_probabilities( - &mut state, - vec![0.0, 0.0, 1.0] - ) - .is_ok()); + assert!(tuneable + .set_mutation_probabilities(&mut state, vec![0.0, 0.0, 1.0]) + .is_ok()); assert_eq!(tuneable.schedule(&mut state, &input), 2.into()); - assert!(TuneableScheduledMutator::set_mutation_probabilities( - &mut state, - vec![0.0, 1.0, 0.0] - ) - .is_ok()); + assert!(tuneable + .set_mutation_probabilities(&mut state, vec![0.0, 1.0, 0.0]) + .is_ok()); assert_eq!(tuneable.schedule(&mut state, &input), 1.into()); - assert!(TuneableScheduledMutator::set_mutation_probabilities( - &mut state, - vec![1.0, 0.0, 0.0] - ) - .is_ok()); + assert!(tuneable + .set_mutation_probabilities(&mut state, vec![1.0, 0.0, 0.0]) + .is_ok()); assert_eq!(tuneable.schedule(&mut state, &input), 0.into()); // We should not choose a mutation with p=0. - assert!(TuneableScheduledMutator::set_mutation_probabilities( - &mut state, - vec![0.5, 0.0, 0.5] - ) - .is_ok()); + assert!(tuneable + .set_mutation_probabilities(&mut state, vec![0.5, 0.0, 0.5]) + .is_ok()); assert!(tuneable.schedule(&mut state, &input) != 1.into()); } } diff --git a/libafl/src/mutators/unicode/mod.rs b/libafl/src/mutators/unicode/mod.rs index 60a7b6cdb0..20921e0251 100644 --- a/libafl/src/mutators/unicode/mod.rs +++ b/libafl/src/mutators/unicode/mod.rs @@ -9,7 +9,7 @@ use core::{ use libafl_bolts::{rands::Rand, Error, HasLen, Named}; use crate::{ - corpus::{CorpusId, HasTestcase, Testcase}, + corpus::{Corpus, CorpusId, HasTestcase, Testcase}, inputs::{BytesInput, HasMutatorBytes}, mutators::{rand_range, MutationResult, Mutator, Tokens}, stages::{ @@ -32,7 +32,8 @@ pub type UnicodeInput = (BytesInput, UnicodeIdentificationMetadata); impl MutatedTransform for UnicodeInput where - S: HasCorpus + HasTestcase, + S: HasCorpus + HasTestcase, + S::Corpus: Corpus, { type Post = UnicodeIdentificationMetadata; diff --git a/libafl/src/schedulers/accounting.rs b/libafl/src/schedulers/accounting.rs index beae671f2c..5761dd2102 100644 --- a/libafl/src/schedulers/accounting.rs +++ b/libafl/src/schedulers/accounting.rs @@ -110,11 +110,12 @@ pub struct CoverageAccountingScheduler<'a, CS, O> { inner: IndexesLenTimeMinimizerScheduler, } -impl<'a, CS, I, O, S> Scheduler for CoverageAccountingScheduler<'a, CS, O> +impl<'a, CS, O, S> Scheduler<::Input, S> + for CoverageAccountingScheduler<'a, CS, O> where - CS: Scheduler, - S: HasCorpus + HasMetadata + HasRand, - I: HasLen, + CS: Scheduler<::Input, S>, + S: HasCorpus + HasMetadata + HasRand, + ::Input: HasLen, O: CanTrack, { fn on_add(&mut self, state: &mut S, id: CorpusId) -> Result<(), Error> { @@ -122,7 +123,12 @@ where self.inner.on_add(state, id) } - fn on_evaluation(&mut self, state: &mut S, input: &I, observers: &OT) -> Result<(), Error> + fn on_evaluation( + &mut self, + state: &mut S, + input: &::Input, + observers: &OT, + ) -> Result<(), Error> where OT: MatchName, { diff --git a/libafl/src/schedulers/minimizer.rs b/libafl/src/schedulers/minimizer.rs index eb36d85a0e..bbee468aa8 100644 --- a/libafl/src/schedulers/minimizer.rs +++ b/libafl/src/schedulers/minimizer.rs @@ -79,19 +79,21 @@ pub struct MinimizerScheduler { phantom: PhantomData<(F, M, S)>, } -impl RemovableScheduler for MinimizerScheduler +impl RemovableScheduler<::Input, S> + for MinimizerScheduler where - CS: RemovableScheduler + Scheduler, - F: TestcaseScore, + CS: RemovableScheduler<::Input, S> + + Scheduler<::Input, S>, + F: TestcaseScore, M: for<'a> AsIter<'a, Item = usize> + SerdeAny + HasRefCnt, - S: HasCorpus + HasMetadata + HasRand, + S: HasCorpus + HasMetadata + HasRand, { /// Replaces the [`Testcase`] at the given [`CorpusId`] fn on_replace( &mut self, state: &mut S, id: CorpusId, - testcase: &Testcase, + testcase: &Testcase<::Input>, ) -> Result<(), Error> { self.base.on_replace(state, id, testcase)?; self.update_score(state, id) @@ -102,7 +104,7 @@ where &mut self, state: &mut S, id: CorpusId, - testcase: &Option>, + testcase: &Option::Input>>, ) -> Result<(), Error> { self.base.on_remove(state, id, testcase)?; let mut entries = @@ -186,12 +188,12 @@ where } } -impl Scheduler for MinimizerScheduler +impl Scheduler<::Input, S> for MinimizerScheduler where - CS: Scheduler, - F: TestcaseScore, + CS: Scheduler<::Input, S>, + F: TestcaseScore, M: for<'a> AsIter<'a, Item = usize> + SerdeAny + HasRefCnt, - S: HasCorpus + HasMetadata + HasRand, + S: HasCorpus + HasMetadata + HasRand, { /// Called when a [`Testcase`] is added to the corpus fn on_add(&mut self, state: &mut S, id: CorpusId) -> Result<(), Error> { @@ -200,7 +202,12 @@ where } /// An input has been evaluated - fn on_evaluation(&mut self, state: &mut S, input: &I, observers: &OT) -> Result<(), Error> + fn on_evaluation( + &mut self, + state: &mut S, + input: &::Input, + observers: &OT, + ) -> Result<(), Error> where OT: MatchName, { @@ -243,10 +250,10 @@ where /// Update the [`Corpus`] score using the [`MinimizerScheduler`] #[allow(clippy::unused_self)] #[allow(clippy::cast_possible_wrap)] - pub fn update_score(&self, state: &mut S, id: CorpusId) -> Result<(), Error> + pub fn update_score(&self, state: &mut S, id: CorpusId) -> Result<(), Error> where - F: TestcaseScore, - S: HasCorpus + HasMetadata, + F: TestcaseScore, + S: HasCorpus + HasMetadata, { // Create a new top rated meta if not existing if state.metadata_map().get::().is_none() { diff --git a/libafl/src/schedulers/mod.rs b/libafl/src/schedulers/mod.rs index 410e876b20..252da33b18 100644 --- a/libafl/src/schedulers/mod.rs +++ b/libafl/src/schedulers/mod.rs @@ -215,7 +215,7 @@ pub struct RandScheduler { impl Scheduler for RandScheduler where - S: HasCorpus + HasRand + HasTestcase, + S: HasCorpus + HasRand, { fn on_add(&mut self, state: &mut S, id: CorpusId) -> Result<(), Error> { // Set parent id diff --git a/libafl/src/schedulers/probabilistic_sampling.rs b/libafl/src/schedulers/probabilistic_sampling.rs index 9bb8698de8..ccd6b0e6c3 100644 --- a/libafl/src/schedulers/probabilistic_sampling.rs +++ b/libafl/src/schedulers/probabilistic_sampling.rs @@ -10,7 +10,6 @@ use serde::{Deserialize, Serialize}; use crate::{ corpus::{Corpus, CorpusId, Testcase}, - inputs::Input, schedulers::{RemovableScheduler, Scheduler, TestcaseScore}, state::{HasCorpus, HasRand}, Error, HasMetadata, @@ -66,11 +65,10 @@ impl ProbabilitySamplingScheduler { /// Calculate the score and store in `ProbabilityMetadata` #[allow(clippy::cast_precision_loss)] #[allow(clippy::unused_self)] - pub fn store_probability(&self, state: &mut S, id: CorpusId) -> Result<(), Error> + pub fn store_probability(&self, state: &mut S, id: CorpusId) -> Result<(), Error> where - F: TestcaseScore, - I: Input, - S: HasCorpus + HasMetadata + HasRand, + F: TestcaseScore, + S: HasCorpus + HasMetadata + HasRand, { let prob = F::compute(state, &mut *state.corpus().get(id)?.borrow_mut())?; debug_assert!( @@ -87,17 +85,16 @@ impl ProbabilitySamplingScheduler { } } -impl RemovableScheduler for ProbabilitySamplingScheduler +impl RemovableScheduler<::Input, S> for ProbabilitySamplingScheduler where - F: TestcaseScore, - I: Input, - S: HasCorpus + HasMetadata + HasRand, + F: TestcaseScore, + S: HasCorpus + HasMetadata + HasRand, { fn on_remove( &mut self, state: &mut S, id: CorpusId, - _testcase: &Option>, + _testcase: &Option::Input>>, ) -> Result<(), Error> { let meta = state .metadata_map_mut() @@ -113,7 +110,7 @@ where &mut self, state: &mut S, id: CorpusId, - _prev: &Testcase, + _prev: &Testcase<::Input>, ) -> Result<(), Error> { let meta = state .metadata_map_mut() @@ -127,11 +124,10 @@ where } } -impl Scheduler for ProbabilitySamplingScheduler +impl Scheduler<::Input, S> for ProbabilitySamplingScheduler where - F: TestcaseScore, - I: Input, - S: HasCorpus + HasMetadata + HasRand, + F: TestcaseScore, + S: HasCorpus + HasMetadata + HasRand, { fn on_add(&mut self, state: &mut S, id: CorpusId) -> Result<(), Error> { let current_id = *state.corpus().current(); @@ -209,11 +205,14 @@ mod tests { #[derive(Debug, Clone)] pub struct UniformDistribution {} - impl TestcaseScore for UniformDistribution + impl TestcaseScore for UniformDistribution where S: HasCorpus, { - fn compute(_state: &S, _: &mut Testcase) -> Result { + fn compute( + _state: &S, + _: &mut Testcase<::Input>, + ) -> Result { Ok(FACTOR) } } diff --git a/libafl/src/schedulers/testcase_score.rs b/libafl/src/schedulers/testcase_score.rs index 4cb09f2138..c08454903a 100644 --- a/libafl/src/schedulers/testcase_score.rs +++ b/libafl/src/schedulers/testcase_score.rs @@ -15,9 +15,13 @@ use crate::{ }; /// Compute the favor factor of a [`Testcase`]. Higher is better. -pub trait TestcaseScore { +pub trait TestcaseScore +where + S: HasCorpus, +{ /// Computes the favor factor of a [`Testcase`]. Higher is better. - fn compute(state: &S, entry: &mut Testcase) -> Result; + fn compute(state: &S, entry: &mut Testcase<::Input>) + -> Result; } /// Multiply the testcase size with the execution time. @@ -25,13 +29,16 @@ pub trait TestcaseScore { #[derive(Debug, Clone)] pub struct LenTimeMulTestcaseScore {} -impl TestcaseScore for LenTimeMulTestcaseScore +impl TestcaseScore for LenTimeMulTestcaseScore where - S: HasCorpus, - I: HasLen, + S: HasCorpus, + ::Input: HasLen, { #[allow(clippy::cast_precision_loss, clippy::cast_lossless)] - fn compute(state: &S, entry: &mut Testcase) -> Result { + fn compute( + state: &S, + entry: &mut Testcase<::Input>, + ) -> Result { // TODO maybe enforce entry.exec_time().is_some() Ok(entry.exec_time().map_or(1, |d| d.as_millis()) as f64 * entry.load_len(state.corpus())? as f64) @@ -48,7 +55,7 @@ const HAVOC_MAX_MULT: f64 = 64.0; #[derive(Debug, Clone)] pub struct CorpusPowerTestcaseScore {} -impl TestcaseScore for CorpusPowerTestcaseScore +impl TestcaseScore for CorpusPowerTestcaseScore where S: HasCorpus + HasMetadata, { @@ -59,7 +66,10 @@ where clippy::cast_sign_loss, clippy::cast_lossless )] - fn compute(state: &S, entry: &mut Testcase) -> Result { + fn compute( + state: &S, + entry: &mut Testcase<::Input>, + ) -> Result { let psmeta = state.metadata::()?; let fuzz_mu = if let Some(strat) = psmeta.strat() { @@ -267,13 +277,16 @@ where #[derive(Debug, Clone)] pub struct CorpusWeightTestcaseScore {} -impl TestcaseScore for CorpusWeightTestcaseScore +impl TestcaseScore for CorpusWeightTestcaseScore where S: HasCorpus + HasMetadata, { /// Compute the `weight` used in weighted corpus entry selection algo #[allow(clippy::cast_precision_loss, clippy::cast_lossless)] - fn compute(state: &S, entry: &mut Testcase) -> Result { + fn compute( + state: &S, + entry: &mut Testcase<::Input>, + ) -> Result { let mut weight = 1.0; let psmeta = state.metadata::()?; diff --git a/libafl/src/schedulers/weighted.rs b/libafl/src/schedulers/weighted.rs index 24760f5e8e..6ee0162018 100644 --- a/libafl/src/schedulers/weighted.rs +++ b/libafl/src/schedulers/weighted.rs @@ -16,7 +16,6 @@ use serde::{Deserialize, Serialize}; use super::powersched::PowerSchedule; use crate::{ corpus::{Corpus, CorpusId, HasTestcase, Testcase}, - inputs::Input, observers::MapObserver, random_corpus_id, schedulers::{ @@ -163,11 +162,10 @@ where clippy::cast_precision_loss, clippy::cast_lossless )] - pub fn create_alias_table(&self, state: &mut S) -> Result<(), Error> + pub fn create_alias_table(&self, state: &mut S) -> Result<(), Error> where - F: TestcaseScore, - I: Input, - S: HasCorpus + HasMetadata, + F: TestcaseScore, + S: HasCorpus + HasMetadata, { let n = state.corpus().count(); @@ -312,13 +310,12 @@ impl HasQueueCycles for WeightedScheduler { } } -impl Scheduler for WeightedScheduler +impl Scheduler<::Input, S> for WeightedScheduler where C: AsRef + Named, - F: TestcaseScore, - I: Input, + F: TestcaseScore, O: MapObserver, - S: HasCorpus + HasMetadata + HasRand + HasTestcase, + S: HasCorpus + HasMetadata + HasRand + HasTestcase, { /// Called when a [`Testcase`] is added to the corpus fn on_add(&mut self, state: &mut S, id: CorpusId) -> Result<(), Error> { @@ -327,7 +324,12 @@ where Ok(()) } - fn on_evaluation(&mut self, state: &mut S, _input: &I, observers: &OT) -> Result<(), Error> + fn on_evaluation( + &mut self, + state: &mut S, + _input: &::Input, + observers: &OT, + ) -> Result<(), Error> where OT: MatchName, { diff --git a/libafl/src/stages/calibrate.rs b/libafl/src/stages/calibrate.rs index 661b2f32f5..5dd1059715 100644 --- a/libafl/src/stages/calibrate.rs +++ b/libafl/src/stages/calibrate.rs @@ -100,8 +100,9 @@ where C: AsRef, for<'de> ::Entry: Serialize + Deserialize<'de> + 'static, OT: ObserversTuple, - Self::State: HasCorpus + HasMetadata + HasNamedMetadata + HasExecutions, + E::State: HasCorpus + HasMetadata + HasNamedMetadata + HasExecutions + HasCurrentTestcase, Z: Evaluator, + <::State as HasCorpus>::Corpus: Corpus, //delete me { #[inline] #[allow( diff --git a/libafl/src/stages/colorization.rs b/libafl/src/stages/colorization.rs index 2beef96087..b9e41a7fc6 100644 --- a/libafl/src/stages/colorization.rs +++ b/libafl/src/stages/colorization.rs @@ -14,6 +14,7 @@ use libafl_bolts::{ use serde::{Deserialize, Serialize}; use crate::{ + corpus::Corpus, events::EventFirer, executors::{Executor, HasObservers}, inputs::HasMutatorBytes, @@ -87,11 +88,12 @@ impl Stage for ColorizationStage where EM: UsesState + EventFirer, E: HasObservers + Executor, - Self::State: HasCorpus + HasMetadata + HasRand + HasNamedMetadata, + E::State: HasCorpus + HasMetadata + HasRand + HasNamedMetadata, E::Input: HasMutatorBytes, O: MapObserver, C: AsRef + Named, Z: UsesState, + <::State as HasCorpus>::Corpus: Corpus, //delete me { #[inline] #[allow(clippy::let_and_return)] @@ -165,9 +167,10 @@ where O: MapObserver, C: AsRef + Named, E: HasObservers + Executor, - ::State: HasCorpus + HasMetadata + HasRand, + ::State: HasCorpus + HasMetadata + HasRand, E::Input: HasMutatorBytes, Z: UsesState::State>, + <::State as HasCorpus>::Corpus: Corpus, //delete me { #[inline] #[allow(clippy::let_and_return)] diff --git a/libafl/src/stages/concolic.rs b/libafl/src/stages/concolic.rs index 02aaff2577..820a1bc0bd 100644 --- a/libafl/src/stages/concolic.rs +++ b/libafl/src/stages/concolic.rs @@ -17,6 +17,7 @@ use crate::monitors::PerfFeature; #[cfg(all(feature = "introspection", feature = "concolic_mutation"))] use crate::state::HasClientPerfMonitor; use crate::{ + corpus::Corpus, executors::{Executor, HasObservers}, observers::concolic::ConcolicObserver, stages::{RetryCountRestartHelper, Stage, TracingStage}, @@ -62,8 +63,9 @@ where E: UsesState, EM: UsesState, TE: Executor + HasObservers, - Self::State: HasExecutions + HasCorpus + HasNamedMetadata, + TE::State: HasExecutions + HasCorpus + HasNamedMetadata + HasCurrentTestcase, Z: UsesState, + <::State as HasCorpus>::Corpus: Corpus, //delete me { #[inline] fn perform( @@ -395,7 +397,9 @@ where EM: UsesState, Z: Evaluator, Z::Input: HasMutatorBytes, - Self::State: State + HasExecutions + HasCorpus + HasMetadata + HasNamedMetadata, + Z::State: + State + HasExecutions + HasCorpus + HasMetadata + HasNamedMetadata + HasCurrentTestcase, + <::State as HasCorpus>::Corpus: Corpus, //delete me { #[inline] fn perform( diff --git a/libafl/src/stages/dump.rs b/libafl/src/stages/dump.rs index 5e80591348..90ac253890 100644 --- a/libafl/src/stages/dump.rs +++ b/libafl/src/stages/dump.rs @@ -9,7 +9,6 @@ use serde::{Deserialize, Serialize}; use crate::{ corpus::{Corpus, CorpusId}, - inputs::UsesInput, stages::Stage, state::{HasCorpus, HasRand, HasSolutions, UsesState}, Error, HasMetadata, @@ -46,11 +45,13 @@ where impl Stage for DumpToDiskStage where - CB: FnMut(&::Input, &Self::State) -> Vec, + CB: FnMut(&Self::Input, &Self::State) -> Vec, EM: UsesState, E: UsesState, Z: UsesState, - Self::State: HasCorpus + HasSolutions + HasRand + HasMetadata, + EM::State: HasCorpus + HasSolutions + HasRand + HasMetadata, + <::State as HasCorpus>::Corpus: Corpus, //delete me + <::State as HasSolutions>::Solutions: Corpus, //delete me { #[inline] fn perform( diff --git a/libafl/src/stages/generalization.rs b/libafl/src/stages/generalization.rs index 266e880954..fbbddb767d 100644 --- a/libafl/src/stages/generalization.rs +++ b/libafl/src/stages/generalization.rs @@ -73,9 +73,10 @@ where O: MapObserver, C: CanTrack + AsRef + Named, E: Executor + HasObservers, - Self::State: + EM::State: UsesInput + HasExecutions + HasMetadata + HasCorpus + HasNamedMetadata, EM: UsesState, + <::State as HasCorpus>::Corpus: Corpus, //delete me Z: UsesState, { #[inline] diff --git a/libafl/src/stages/mutational.rs b/libafl/src/stages/mutational.rs index 186de38d27..311da95f8b 100644 --- a/libafl/src/stages/mutational.rs +++ b/libafl/src/stages/mutational.rs @@ -60,7 +60,8 @@ where impl MutatedTransform for I where I: Input + Clone, - S: HasCorpus, + S: HasCorpus, + S::Corpus: Corpus, { type Post = (); @@ -85,8 +86,9 @@ where M: Mutator, EM: UsesState, Z: Evaluator, - Self::State: HasCorpus, + Self::State: HasCorpus + HasCurrentTestcase, I: MutatedTransform + Clone, + <::State as HasCorpus>::Corpus: Corpus, { /// The mutator registered for this stage fn mutator(&self) -> &M; @@ -171,8 +173,9 @@ where EM: UsesState, M: Mutator, Z: Evaluator, - Self::State: HasCorpus + HasRand + HasExecutions + HasMetadata + HasNamedMetadata, + Z::State: HasCorpus + HasRand + HasExecutions + HasMetadata + HasNamedMetadata, I: MutatedTransform + Clone, + <::State as HasCorpus>::Corpus: Corpus, //delete me { /// The mutator, added to this stage #[inline] @@ -216,8 +219,9 @@ where EM: UsesState, M: Mutator, Z: Evaluator, - Self::State: HasCorpus + HasRand + HasMetadata + HasExecutions + HasNamedMetadata, + Z::State: HasCorpus + HasRand + HasMetadata + HasExecutions + HasNamedMetadata, I: MutatedTransform + Clone, + <::State as HasCorpus>::Corpus: Corpus, //delete me { #[inline] #[allow(clippy::let_and_return)] @@ -329,8 +333,9 @@ where EM: UsesState, M: MultiMutator, Z: Evaluator, - Self::State: HasCorpus + HasRand + HasNamedMetadata, + Z::State: HasCorpus + HasRand + HasNamedMetadata + HasCurrentTestcase, I: MutatedTransform + Clone, + <::State as HasCorpus>::Corpus: Corpus, //delete me { #[inline] fn should_restart(&mut self, state: &mut Self::State) -> Result { diff --git a/libafl/src/stages/power.rs b/libafl/src/stages/power.rs index ce88469535..83083a692e 100644 --- a/libafl/src/stages/power.rs +++ b/libafl/src/stages/power.rs @@ -9,6 +9,7 @@ use core::{fmt::Debug, marker::PhantomData}; use libafl_bolts::Named; use crate::{ + corpus::Corpus, executors::{Executor, HasObservers}, fuzzer::Evaluator, inputs::Input, @@ -50,12 +51,14 @@ impl MutationalStage for PowerMutationalStage where E: Executor + HasObservers, EM: UsesState, - F: TestcaseScore, + F: TestcaseScore, I: Input, M: Mutator, - Self::State: HasCorpus + HasMetadata + HasRand + HasExecutions + HasNamedMetadata, + E::State: + HasCorpus + HasMetadata + HasRand + HasExecutions + HasNamedMetadata + HasCurrentTestcase, Z: Evaluator, I: MutatedTransform + Clone, + <::State as HasCorpus>::Corpus: Corpus, //delete me { /// The mutator, added to this stage #[inline] @@ -84,11 +87,13 @@ impl Stage for PowerMutationalStage + HasObservers, EM: UsesState, - F: TestcaseScore, + F: TestcaseScore, M: Mutator, - Self::State: HasCorpus + HasMetadata + HasRand + HasExecutions + HasNamedMetadata, + E::State: + HasCorpus + HasMetadata + HasRand + HasExecutions + HasNamedMetadata + HasCurrentTestcase, Z: Evaluator, I: MutatedTransform + Clone + Input, + <::State as HasCorpus>::Corpus: Corpus, //delete me { #[inline] #[allow(clippy::let_and_return)] @@ -117,7 +122,7 @@ impl PowerMutationalStage where E: Executor + HasObservers, EM: UsesState::State>, - F: TestcaseScore::State>, + F: TestcaseScore<::State>, I: Input, M: Mutator::State>, ::State: HasCorpus + HasMetadata + HasRand, diff --git a/libafl/src/stages/push/mutational.rs b/libafl/src/stages/push/mutational.rs index 4b38846d25..2ef7ee3616 100644 --- a/libafl/src/stages/push/mutational.rs +++ b/libafl/src/stages/push/mutational.rs @@ -21,7 +21,7 @@ use crate::{ observers::ObserversTuple, schedulers::Scheduler, start_timer, - state::{HasCorpus, HasExecutions, HasLastReportTime, HasRand}, + state::{HasCorpus, HasExecutions, HasLastReportTime, HasRand, UsesState}, Error, EvaluatorObservers, ExecutionProcessor, HasMetadata, HasScheduler, }; #[cfg(feature = "introspection")] @@ -88,6 +88,7 @@ where OT: ObserversTuple + Serialize, Z::State: HasCorpus + HasRand + HasExecutions + HasLastReportTime + HasMetadata + Clone + Debug, Z: ExecutionProcessor + EvaluatorObservers + HasScheduler, + <::State as HasCorpus>::Corpus: Corpus, //delete me { #[inline] fn push_stage_helper(&self) -> &PushStageHelper { @@ -196,6 +197,7 @@ where OT: ObserversTuple + Serialize, Z::State: HasCorpus + HasRand + HasExecutions + HasMetadata + HasLastReportTime + Clone + Debug, Z: ExecutionProcessor + EvaluatorObservers + HasScheduler, + <::State as HasCorpus>::Corpus: Corpus, //delete me { type Item = Result<::Input, Error>; diff --git a/libafl/src/stages/sync.rs b/libafl/src/stages/sync.rs index 488fe1968b..7e43c1f230 100644 --- a/libafl/src/stages/sync.rs +++ b/libafl/src/stages/sync.rs @@ -13,7 +13,7 @@ use serde::{Deserialize, Serialize}; #[cfg(feature = "introspection")] use crate::state::HasClientPerfMonitor; use crate::{ - corpus::{Corpus, CorpusId, HasTestcase}, + corpus::{Corpus, CorpusId}, events::{llmp::LlmpEventConverter, Event, EventConfig, EventFirer}, executors::{Executor, ExitKind, HasObservers}, fuzzer::{Evaluator, EvaluatorObservers, ExecutionProcessor}, @@ -249,7 +249,7 @@ where impl Stage for SyncFromBrokerStage where EM: UsesState + EventFirer, - S: State + HasExecutions + HasCorpus + HasRand + HasMetadata + HasTestcase, + S: State + HasExecutions + HasCorpus + HasRand + HasMetadata, SP: ShMemProvider, E: HasObservers + Executor, for<'a> E::Observers: Deserialize<'a>, @@ -257,6 +257,8 @@ where IC: InputConverter, ICB: InputConverter, DI: Input, + <::Corpus as Corpus>::Input: Clone, + S::Corpus: Corpus, // delete me { #[inline] fn perform( diff --git a/libafl/src/stages/tmin.rs b/libafl/src/stages/tmin.rs index b07855ba1e..18535959c5 100644 --- a/libafl/src/stages/tmin.rs +++ b/libafl/src/stages/tmin.rs @@ -48,7 +48,7 @@ where ::Observers: Serialize, EM: UsesState + EventFirer, F: Feedback, - Self::State: HasMaxSize + HasCorpus + HasSolutions + HasExecutions, + Self::State: HasMaxSize + HasCorpus + HasSolutions + HasExecutions + HasCurrentTestcase, Self::Input: MutatedTransform + Clone + Hash + HasLen, IP: Clone + MutatedTransformPost, M: Mutator, @@ -58,6 +58,7 @@ where + ExecutesInput + ExecutionProcessor, Z::Scheduler: RemovableScheduler, + <::State as HasCorpus>::Corpus: Corpus, { /// The mutator registered for this stage fn mutator(&self) -> &M; @@ -246,10 +247,11 @@ where FF: FeedbackFactory, F: Feedback, Self::Input: MutatedTransform + Clone + HasLen + Hash, - Self::State: + Z::State: HasMetadata + HasExecutions + HasSolutions + HasCorpus + HasMaxSize + HasNamedMetadata, M: Mutator, IP: MutatedTransformPost + Clone, + <::State as HasCorpus>::Corpus: Corpus, // delete me { fn should_restart(&mut self, state: &mut Self::State) -> Result { self.restart_helper.should_restart(state, &self.name) @@ -308,10 +310,16 @@ where FF: FeedbackFactory, F: Feedback, Self::Input: MutatedTransform + Clone + HasLen + Hash, - Self::State: - HasMetadata + HasExecutions + HasSolutions + HasCorpus + HasMaxSize + HasNamedMetadata, + Z::State: HasMetadata + + HasExecutions + + HasSolutions + + HasCorpus + + HasMaxSize + + HasNamedMetadata + + HasCurrentTestcase, M: Mutator, IP: MutatedTransformPost + Clone, + <::State as HasCorpus>::Corpus: Corpus, // delete me { /// The mutator, added to this stage #[inline] diff --git a/libafl/src/stages/tracing.rs b/libafl/src/stages/tracing.rs index 8eb20ddd41..b069e97e6b 100644 --- a/libafl/src/stages/tracing.rs +++ b/libafl/src/stages/tracing.rs @@ -9,6 +9,7 @@ use core::{fmt::Debug, marker::PhantomData}; use libafl_bolts::Named; use crate::{ + corpus::Corpus, executors::{Executor, HasObservers, ShadowExecutor}, mark_feature_time, observers::ObserversTuple, @@ -39,9 +40,10 @@ where impl TracingStage where TE: Executor + HasObservers, - ::State: HasExecutions + HasCorpus + HasNamedMetadata, + ::State: HasExecutions + HasCorpus + HasNamedMetadata + HasCurrentTestcase, EM: UsesState::State>, Z: UsesState::State>, + <::State as HasCorpus>::Corpus: Corpus, // delete me { #[allow(rustdoc::broken_intra_doc_links)] /// Perform tracing on the given `CorpusId`. Useful for if wrapping [`TracingStage`] with your @@ -84,9 +86,10 @@ impl Stage for TracingStage where E: UsesState::State>, TE: Executor + HasObservers, - ::State: HasExecutions + HasCorpus + HasNamedMetadata, + ::State: HasExecutions + HasCorpus + HasNamedMetadata, EM: UsesState::State>, Z: UsesState::State>, + <::State as HasCorpus>::Corpus: Corpus, // delete me { #[inline] fn perform( @@ -181,7 +184,9 @@ where EM: UsesState::State>, SOT: ObserversTuple, Z: UsesState::State>, - ::State: State + HasExecutions + HasCorpus + HasNamedMetadata + Debug, + ::State: + State + HasExecutions + HasCorpus + HasNamedMetadata + Debug + HasCurrentTestcase, + <::State as HasCorpus>::Corpus: Corpus, // delete me { #[inline] fn perform( diff --git a/libafl/src/stages/tuneable.rs b/libafl/src/stages/tuneable.rs index 749e74095a..622d143888 100644 --- a/libafl/src/stages/tuneable.rs +++ b/libafl/src/stages/tuneable.rs @@ -7,6 +7,7 @@ use libafl_bolts::{current_time, impl_serdeany, rands::Rand}; use serde::{Deserialize, Serialize}; use crate::{ + corpus::Corpus, mark_feature_time, mutators::{MutationResult, Mutator}, stages::{ @@ -164,8 +165,10 @@ where EM: UsesState, M: Mutator, Z: Evaluator, - Self::State: HasCorpus + HasRand + HasNamedMetadata + HasMetadata + HasExecutions, + Z::State: + HasCorpus + HasRand + HasNamedMetadata + HasMetadata + HasExecutions + HasCurrentTestcase, I: MutatedTransform + Clone, + <::State as HasCorpus>::Corpus: Corpus, // delete me { /// Runs this (mutational) stage for the given `testcase` /// Exactly the same functionality as [`MutationalStage::perform_mutational`], but with added timeout support. @@ -263,8 +266,10 @@ where EM: UsesState, M: Mutator, Z: Evaluator, - Self::State: HasCorpus + HasRand + HasNamedMetadata + HasMetadata + HasExecutions, + Z::State: + HasCorpus + HasRand + HasNamedMetadata + HasMetadata + HasExecutions + HasCurrentTestcase, I: MutatedTransform + Clone, + <::State as HasCorpus>::Corpus: Corpus, // delete me { #[inline] #[allow(clippy::let_and_return)] @@ -298,9 +303,10 @@ where EM: UsesState::State>, M: Mutator::State>, Z: Evaluator, - ::State: - HasCorpus + HasRand + HasNamedMetadata + HasExecutions + HasMetadata, + ::State: + HasCorpus + HasRand + HasNamedMetadata + HasExecutions + HasMetadata + HasCurrentTestcase, I: MutatedTransform::State> + Clone, + <::State as HasCorpus>::Corpus: Corpus, // delete me { fn execs_since_progress_start( &mut self, diff --git a/libafl/src/stages/unicode.rs b/libafl/src/stages/unicode.rs index 98957a015c..efc57b4f81 100644 --- a/libafl/src/stages/unicode.rs +++ b/libafl/src/stages/unicode.rs @@ -8,7 +8,7 @@ use libafl_bolts::{impl_serdeany, Error}; use serde::{Deserialize, Serialize}; use crate::{ - corpus::HasTestcase, + corpus::Corpus, inputs::{BytesInput, HasMutatorBytes}, stages::Stage, state::{HasCorpus, HasCurrentTestcase, State, UsesState}, @@ -100,7 +100,8 @@ where impl Stage for UnicodeIdentificationStage where - S: HasTestcase + HasCorpus + State, + S: HasCorpus + State + HasCurrentTestcase, + S::Corpus: Corpus, E: UsesState, EM: UsesState, Z: UsesState, diff --git a/libafl/src/state/mod.rs b/libafl/src/state/mod.rs index 97c3297134..ed9922cd60 100644 --- a/libafl/src/state/mod.rs +++ b/libafl/src/state/mod.rs @@ -74,9 +74,9 @@ where } /// Trait for elements offering a corpus -pub trait HasCorpus: UsesInput { +pub trait HasCorpus { /// The associated type implementing [`Corpus`]. - type Corpus: Corpus::Input>; + type Corpus: Corpus; /// The testcase corpus fn corpus(&self) -> &Self::Corpus; @@ -84,6 +84,22 @@ pub trait HasCorpus: UsesInput { fn corpus_mut(&mut self) -> &mut Self::Corpus; } +// Reflexivity +impl HasCorpus for C +where + C: Corpus, +{ + type Corpus = Self; + + fn corpus(&self) -> &Self::Corpus { + self + } + + fn corpus_mut(&mut self) -> &mut Self::Corpus { + self + } +} + /// Interact with the maximum size pub trait HasMaxSize { /// The maximum size hint for items and mutations returned @@ -93,9 +109,9 @@ pub trait HasMaxSize { } /// Trait for elements offering a corpus of solutions -pub trait HasSolutions: UsesInput { +pub trait HasSolutions { /// The associated type implementing [`Corpus`] for solutions - type Solutions: Corpus::Input>; + type Solutions: Corpus; /// The solutions corpus fn solutions(&self) -> &Self::Solutions; @@ -289,9 +305,9 @@ where impl State for StdState where - C: Corpus, + C: Corpus + Serialize + DeserializeOwned, R: Rand, - SC: Corpus, + SC: Corpus + Serialize + DeserializeOwned, Self: UsesInput, { } @@ -317,9 +333,7 @@ where impl HasCorpus for StdState where - I: Input, - C: Corpus::Input>, - R: Rand, + C: Corpus, { type Corpus = C; @@ -338,23 +352,15 @@ where impl HasTestcase for StdState where - I: Input, - C: Corpus::Input>, - R: Rand, + C: Corpus, { /// To get the testcase - fn testcase( - &self, - id: CorpusId, - ) -> Result::Input>>, Error> { + fn testcase(&self, id: CorpusId) -> Result>, Error> { Ok(self.corpus().get(id)?.borrow()) } /// To get mutable testcase - fn testcase_mut( - &self, - id: CorpusId, - ) -> Result::Input>>, Error> { + fn testcase_mut(&self, id: CorpusId) -> Result>, Error> { Ok(self.corpus().get(id)?.borrow_mut()) } } @@ -504,20 +510,20 @@ impl HasCurrentCorpusId for StdState { } /// Has information about the current [`Testcase`] we are fuzzing -pub trait HasCurrentTestcase -where - I: Input, -{ +pub trait HasCurrentTestcase: HasCorpus { /// Gets the current [`Testcase`] we are fuzzing /// /// Will return [`Error::key_not_found`] if no `corpus_id` is currently set. - fn current_testcase(&self) -> Result>, Error>; + fn current_testcase(&self) + -> Result::Input>>, Error>; //fn current_testcase(&self) -> Result<&Testcase, Error>; /// Gets the current [`Testcase`] we are fuzzing (mut) /// /// Will return [`Error::key_not_found`] if no `corpus_id` is currently set. - fn current_testcase_mut(&self) -> Result>, Error>; + fn current_testcase_mut( + &self, + ) -> Result::Input>>, Error>; //fn current_testcase_mut(&self) -> Result<&mut Testcase, Error>; /// Gets a cloned representation of the current [`Testcase`]. @@ -527,15 +533,17 @@ where /// # Note /// This allocates memory and copies the contents! /// For performance reasons, if you just need to access the testcase, use [`Self::current_testcase`] instead. - fn current_input_cloned(&self) -> Result; + fn current_input_cloned(&self) -> Result<::Input, Error>; } -impl HasCurrentTestcase for T +impl HasCurrentTestcase for T where - I: Input, - T: HasCorpus + HasCurrentCorpusId + UsesInput, + T: HasCorpus + HasCurrentCorpusId, + ::Input: Clone, { - fn current_testcase(&self) -> Result>, Error> { + fn current_testcase( + &self, + ) -> Result::Input>>, Error> { let Some(corpus_id) = self.current_corpus_id()? else { return Err(Error::key_not_found( "We are not currently processing a testcase", @@ -545,7 +553,9 @@ where Ok(self.corpus().get(corpus_id)?.borrow()) } - fn current_testcase_mut(&self) -> Result>, Error> { + fn current_testcase_mut( + &self, + ) -> Result::Input>>, Error> { let Some(corpus_id) = self.current_corpus_id()? else { return Err(Error::illegal_state( "We are not currently processing a testcase", @@ -555,7 +565,7 @@ where Ok(self.corpus().get(corpus_id)?.borrow_mut()) } - fn current_input_cloned(&self) -> Result { + fn current_input_cloned(&self) -> Result<::Input, Error> { let mut testcase = self.current_testcase_mut()?; Ok(testcase.borrow_mut().load_input(self.corpus())?.clone()) } @@ -1153,6 +1163,8 @@ where where F: Feedback, O: Feedback, + C: Serialize + DeserializeOwned, + SC: Serialize + DeserializeOwned, { let mut state = Self { rand, diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index e3b7a6aa05..8e9437ea01 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -417,6 +417,9 @@ where pub trait NamedTuple: HasConstLen { /// Gets the name of this tuple fn name(&self, index: usize) -> Option<&Cow<'static, str>>; + + /// Gets all the names + fn names(&self) -> Vec>; } #[cfg(feature = "alloc")] @@ -424,6 +427,10 @@ impl NamedTuple for () { fn name(&self, _index: usize) -> Option<&Cow<'static, str>> { None } + + fn names(&self) -> Vec> { + Vec::new() + } } #[cfg(feature = "alloc")] @@ -448,6 +455,13 @@ where self.1.name(index - 1) } } + + fn names(&self) -> Vec> { + let first = self.0.name().clone(); + let mut last = self.1.names(); + last.insert(0, first); + last + } } /// Match for a name and return the value @@ -596,7 +610,6 @@ pub struct RefIndexable(RM, PhantomData); impl From for RefIndexable where RM: Deref, - M: MatchName, { fn from(value: RM) -> Self { RefIndexable(value, PhantomData) diff --git a/libafl_frida/src/executor.rs b/libafl_frida/src/executor.rs index 57629fa060..f004e07281 100644 --- a/libafl_frida/src/executor.rs +++ b/libafl_frida/src/executor.rs @@ -9,6 +9,7 @@ use frida_gum::{ }; #[cfg(windows)] use libafl::{ + corpus::Corpus, executors::{hooks::inprocess::InProcessHooks, inprocess::HasInProcessHooks}, state::{HasCorpus, HasSolutions}, }; @@ -242,6 +243,8 @@ where S::Input: HasTargetBytes, OT: ObserversTuple, RT: FridaRuntimeTuple, + ::Solutions: Corpus, //delete me + <::Corpus as Corpus>::Input: Clone, //delete me { /// the timeout handler #[inline] diff --git a/libafl_libfuzzer/runtime/src/corpus.rs b/libafl_libfuzzer/runtime/src/corpus.rs index 490172ef19..b250cfa78b 100644 --- a/libafl_libfuzzer/runtime/src/corpus.rs +++ b/libafl_libfuzzer/runtime/src/corpus.rs @@ -12,7 +12,7 @@ use libafl::{ inmemory::{TestcaseStorage, TestcaseStorageMap}, Corpus, CorpusId, Testcase, }, - inputs::{Input, UsesInput}, + inputs::Input, }; use libafl_bolts::Error; use serde::{Deserialize, Serialize}; @@ -140,17 +140,12 @@ where } } -impl UsesInput for LibfuzzerCorpus -where - I: Input + Serialize + for<'de> Deserialize<'de>, -{ - type Input = I; -} - impl Corpus for LibfuzzerCorpus where I: Input + Serialize + for<'de> Deserialize<'de>, { + type Input = I; + #[inline] fn count(&self) -> usize { self.mapping.enabled.map.len() @@ -282,17 +277,12 @@ where } } -impl UsesInput for ArtifactCorpus -where - I: Input + Serialize + for<'de> Deserialize<'de>, -{ - type Input = I; -} - impl Corpus for ArtifactCorpus where I: Input + Serialize + for<'de> Deserialize<'de>, { + type Input = I; + fn count(&self) -> usize { self.count } diff --git a/libafl_libfuzzer/runtime/src/lib.rs b/libafl_libfuzzer/runtime/src/lib.rs index db4bf2e2b3..c2fe8dc103 100644 --- a/libafl_libfuzzer/runtime/src/lib.rs +++ b/libafl_libfuzzer/runtime/src/lib.rs @@ -355,7 +355,7 @@ macro_rules! fuzz_with { // TODO configure with mutation stacking options from libfuzzer let std_mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations())); - let std_power = StdPowerMutationalStage::new(std_mutator); + let std_power: StdPowerMutationalStage<_, _, BytesInput, _, _> = StdPowerMutationalStage::new(std_mutator); let std_power = IfStage::new(|_, _, _, _| Ok(mutator_status.std_mutational.into()), (std_power, ())); // for custom mutator and crossover, each have access to the LLVMFuzzerMutate -- but it appears @@ -376,7 +376,7 @@ macro_rules! fuzz_with { }; let std_mutator_no_mutate = StdScheduledMutator::with_max_stack_pow(havoc_crossover(), 3); - let cm_power = StdPowerMutationalStage::new(custom_mutator); + let cm_power: StdPowerMutationalStage<_, _, BytesInput, _, _> = StdPowerMutationalStage::new(custom_mutator); let cm_power = IfStage::new(|_, _, _, _| Ok(mutator_status.custom_mutation.into()), (cm_power, ())); let cm_std_power = StdMutationalStage::new(std_mutator_no_mutate); let cm_std_power = @@ -395,7 +395,7 @@ macro_rules! fuzz_with { let cc_power = StdMutationalStage::new(custom_crossover); let cc_power = IfStage::new(|_, _, _, _| Ok(mutator_status.custom_crossover.into()), (cc_power, ())); - let cc_std_power = StdPowerMutationalStage::new(std_mutator_no_crossover); + let cc_std_power: StdPowerMutationalStage<_, _, BytesInput, _, _> = StdPowerMutationalStage::new(std_mutator_no_crossover); let cc_std_power = IfStage::new(|_, _, _, _| Ok(mutator_status.std_no_crossover.into()), (cc_std_power, ())); diff --git a/libafl_qemu/src/executor.rs b/libafl_qemu/src/executor.rs index d426fd793c..7ebf2c75bb 100644 --- a/libafl_qemu/src/executor.rs +++ b/libafl_qemu/src/executor.rs @@ -7,11 +7,8 @@ use core::{ #[cfg(emulation_mode = "usermode")] use std::ptr; -#[cfg(feature = "fork")] -use libafl::{ - events::EventManager, executors::InProcessForkExecutor, state::HasLastReportTime, HasMetadata, -}; use libafl::{ + corpus::Corpus, events::{EventFirer, EventRestarter}, executors::{ hooks::inprocess::InProcessExecutorHandlerData, @@ -26,6 +23,10 @@ use libafl::{ Error, ExecutionProcessor, HasScheduler, }; #[cfg(feature = "fork")] +use libafl::{ + events::EventManager, executors::InProcessForkExecutor, state::HasLastReportTime, HasMetadata, +}; +#[cfg(feature = "fork")] use libafl_bolts::shmem::ShMemProvider; use libafl_bolts::{ os::unix_signals::{ucontext_t, Signal}, @@ -85,6 +86,8 @@ pub unsafe fn inproc_qemu_timeout_handler( OF: Feedback, E::State: HasExecutions + HasSolutions + HasCorpus, Z: HasObjective, + <::State as HasSolutions>::Solutions: Corpus, //delete me + <<::State as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me { if BREAK_ON_TMOUT { libafl_exit_request_timeout(); @@ -133,6 +136,8 @@ where OF: Feedback, S: Unpin + State + HasExecutions + HasCorpus + HasSolutions, Z: HasObjective + HasScheduler + ExecutionProcessor, + S::Solutions: Corpus, //delete me + ::Input: Clone, //delete me { let mut inner = StatefulInProcessExecutor::with_timeout( harness_fn, emulator, observers, fuzzer, state, event_mgr, timeout, diff --git a/libafl_targets/src/cmps/stages/aflpptracing.rs b/libafl_targets/src/cmps/stages/aflpptracing.rs index d8c8b067ab..95dfadee01 100644 --- a/libafl_targets/src/cmps/stages/aflpptracing.rs +++ b/libafl_targets/src/cmps/stages/aflpptracing.rs @@ -2,6 +2,7 @@ use alloc::borrow::{Cow, ToOwned}; use core::marker::PhantomData; use libafl::{ + corpus::Corpus, executors::{Executor, HasObservers}, inputs::{BytesInput, UsesInput}, observers::ObserversTuple, @@ -51,10 +52,15 @@ impl Stage for AFLppCmplogTracingStage<'_, EM, TE, Z> where E: UsesState, TE: Executor + HasObservers, - Self::State: - HasExecutions + HasCorpus + HasMetadata + UsesInput + HasNamedMetadata, + TE::State: HasExecutions + + HasCorpus + + HasMetadata + + UsesInput + + HasNamedMetadata + + HasCurrentTestcase, EM: UsesState, Z: UsesState, + ::Corpus: Corpus, //delete me { #[inline] fn perform( diff --git a/libafl_targets/src/libfuzzer/mutators.rs b/libafl_targets/src/libfuzzer/mutators.rs index 228522f07a..cab8505dee 100644 --- a/libafl_targets/src/libfuzzer/mutators.rs +++ b/libafl_targets/src/libfuzzer/mutators.rs @@ -82,7 +82,7 @@ pub extern "C" fn LLVMFuzzerMutate(data: *mut u8, size: usize, max_size: usize) /// A proxy which wraps a targeted mutator. This is used to provide dynamic access to a global /// mutator without knowing the concrete type, which is necessary for custom mutators. -struct MutatorProxy<'a, M, MT, S> { +struct MutatorProxy<'a, M, S> { /// Pointer to the state of the fuzzer state: Rc>, // refcell to prevent double-mutability over the pointer /// A weak reference to the mutator to provide to the custom mutator @@ -90,10 +90,10 @@ struct MutatorProxy<'a, M, MT, S> { /// The result of mutation, to be propagated to the mutational stage result: Rc>>, /// Stage index, which is used by libafl mutator implementations - phantom: PhantomData<(&'a mut (), MT)>, + phantom: PhantomData<&'a mut ()>, } -impl<'a, M, MT, S> MutatorProxy<'a, M, MT, S> { +impl<'a, M, S> MutatorProxy<'a, M, S> { /// Crate a new mutator proxy for the given state and mutator fn new( state: &'a mut S, @@ -110,9 +110,7 @@ impl<'a, M, MT, S> MutatorProxy<'a, M, MT, S> { /// Create a weak version of the proxy, which will become unusable when the custom mutator /// is no longer permitted to be executed. - fn weak( - &self, - ) -> WeakMutatorProxy FnMut(&'b mut S)) -> bool, M, MT, S> { + fn weak(&self) -> WeakMutatorProxy FnMut(&'b mut S)) -> bool, M, S> { let state = Rc::downgrade(&self.state); WeakMutatorProxy { accessor: move |f: &mut dyn for<'b> FnMut(&'b mut S)| { @@ -136,7 +134,7 @@ impl<'a, M, MT, S> MutatorProxy<'a, M, MT, S> { /// that once a libafl mutator exits scope (e.g., once the mutational stage is over) that the /// mutator is no longer accessible by the custom mutator. #[derive(Clone)] -struct WeakMutatorProxy { +struct WeakMutatorProxy { /// Function which will perform the access to the state. accessor: F, @@ -145,14 +143,14 @@ struct WeakMutatorProxy { /// The result of mutation, to be propagated to the mutational stage result: Rc>>, - phantom: PhantomData<(MT, S)>, + phantom: PhantomData, } -impl ErasedLLVMFuzzerMutator for WeakMutatorProxy +impl ErasedLLVMFuzzerMutator for WeakMutatorProxy where F: Fn(&mut dyn for<'b> FnMut(&'b mut S)) -> bool, - M: ScheduledMutator, - MT: MutatorsTuple, + M: ScheduledMutator, + M::Mutations: MutatorsTuple, S: HasMaxSize + UsesInput, { fn mutate(&self, data: *mut u8, size: usize, max_size: usize) -> usize { @@ -204,12 +202,12 @@ where /// You should avoid using crossover-like mutators with custom mutators as this may lead to the /// injection of some input portions to another in ways which violate structure. #[derive(Debug)] -pub struct LLVMCustomMutator { +pub struct LLVMCustomMutator { mutator: Rc>, - phantom: PhantomData, + phantom: PhantomData, } -impl LLVMCustomMutator { +impl LLVMCustomMutator { /// Create the mutator which will invoke the custom mutator, emitting an error if the custom mutator is not present /// /// # Safety @@ -238,7 +236,7 @@ impl LLVMCustomMutator { } } -impl LLVMCustomMutator { +impl LLVMCustomMutator { /// Create the mutator which will invoke the custom crossover, emitting an error if the custom crossover is not present /// /// # Safety @@ -267,34 +265,33 @@ impl LLVMCustomMutator { } } -impl ComposedByMutations - for LLVMCustomMutator +impl ComposedByMutations for LLVMCustomMutator where - MT: MutatorsTuple, - S: UsesInput + HasRand + HasMaxSize, - SM: ScheduledMutator, + SM: ScheduledMutator, + SM::Mutations: MutatorsTuple, { - fn mutations(&self) -> &MT { + type Mutations = SM::Mutations; + fn mutations(&self) -> &Self::Mutations { unimplemented!("It is unsafe to provide reference-based access to the mutators as they are behind a RefCell.") } - fn mutations_mut(&mut self) -> &mut MT { + fn mutations_mut(&mut self) -> &mut Self::Mutations { unimplemented!("It is unsafe to provide reference-based access to the mutators as they are behind a RefCell.") } } -impl Named for LLVMCustomMutator { +impl Named for LLVMCustomMutator { fn name(&self) -> &Cow<'static, str> { static NAME: Cow<'static, str> = Cow::Borrowed("LLVMCustomMutator"); &NAME } } -impl Mutator for LLVMCustomMutator +impl Mutator for LLVMCustomMutator where - MT: MutatorsTuple + 'static, S: UsesInput + HasRand + HasMaxSize + 'static, - SM: ScheduledMutator + 'static, + SM: ScheduledMutator + 'static, + SM::Mutations: MutatorsTuple, { #[inline] fn mutate(&mut self, state: &mut S, input: &mut S::Input) -> Result { @@ -302,11 +299,11 @@ where } } -impl ScheduledMutator for LLVMCustomMutator +impl ScheduledMutator for LLVMCustomMutator where - SM: ScheduledMutator + 'static, - MT: MutatorsTuple + 'static, + SM: ScheduledMutator + 'static, S: UsesInput + HasRand + HasMaxSize + 'static, + SM::Mutations: MutatorsTuple, { fn iterations(&self, state: &mut S, input: &S::Input) -> u64 { let mutator = self.mutator.deref().borrow(); @@ -359,18 +356,19 @@ where } } -impl Named for LLVMCustomMutator { +impl Named for LLVMCustomMutator { fn name(&self) -> &Cow<'static, str> { static NAME: Cow<'static, str> = Cow::Borrowed("LLVMCustomMutator"); &NAME } } -impl Mutator for LLVMCustomMutator +impl Mutator for LLVMCustomMutator where - MT: MutatorsTuple + 'static, S: UsesInput + HasRand + HasMaxSize + HasCorpus + 'static, - SM: ScheduledMutator + 'static, + SM: ScheduledMutator + 'static, + S::Corpus: Corpus, + SM::Mutations: MutatorsTuple, { #[inline] fn mutate(&mut self, state: &mut S, input: &mut S::Input) -> Result { @@ -378,11 +376,12 @@ where } } -impl ScheduledMutator for LLVMCustomMutator +impl ScheduledMutator for LLVMCustomMutator where - SM: ScheduledMutator + 'static, - MT: MutatorsTuple + 'static, + SM: ScheduledMutator + 'static, S: UsesInput + HasRand + HasMaxSize + HasCorpus + 'static, + S::Corpus: Corpus, + SM::Mutations: MutatorsTuple, { fn iterations(&self, state: &mut S, input: &S::Input) -> u64 { let mutator = self.mutator.deref().borrow(); diff --git a/libafl_targets/src/windows_asan.rs b/libafl_targets/src/windows_asan.rs index 28244d9b89..17bce87c53 100644 --- a/libafl_targets/src/windows_asan.rs +++ b/libafl_targets/src/windows_asan.rs @@ -1,10 +1,11 @@ //! Setup asan death callbback use libafl::{ + corpus::Corpus, events::{EventFirer, EventRestarter}, executors::{hooks::windows::windows_asan_handler::asan_death_handler, Executor, HasObservers}, feedbacks::Feedback, - state::{HasCorpus, HasExecutions, HasSolutions}, + state::{HasCorpus, HasExecutions, HasSolutions, UsesState}, HasObjective, }; @@ -34,6 +35,8 @@ where OF: Feedback, E::State: HasSolutions + HasCorpus + HasExecutions, Z: HasObjective, + <::State as HasSolutions>::Solutions: Corpus, //delete me + <<::State as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me { __sanitizer_set_death_callback(Some(asan_death_handler::)); }