From c38405ef8385da364c752f7549e6cff4d8e8d5e1 Mon Sep 17 00:00:00 2001 From: Matheus Baptistella <63082492+matheusbaptistella@users.noreply.github.com> Date: Tue, 14 Mar 2023 10:24:33 -0300 Subject: [PATCH] Shorthand functions to get typed metadata, renamed metatdata -> metadata_map (#1123) * Created macro to get the metadata form State and Testcase * Expanded the macros for mutable, or not, State and Testcase metadata * Created functions on traits HasMetadata and HasNamedMetadatato get, mutable or not, metadata * Created the functions to get metadata * Added #[inline] attribute and renamed the functions * Renamed the functions and added #[inline] attribute * Temporarily added testcase() function * Added testcase() function * Changed Ref import to core::cell:Ref * Added testcase_mut() and renamed occurences of metadata() and metadata_mut() * Renamed more occurences * Renamed the metadata() on impl HasMetadata for NopState --------- Co-authored-by: Andrea Fioraldi --- fuzzers/baby_fuzzer_grimoire/src/main.rs | 2 +- fuzzers/baby_fuzzer_nautilus/src/main.rs | 2 +- fuzzers/frida_gdiplus/src/fuzzer.rs | 6 +- fuzzers/frida_libpng/src/fuzzer.rs | 6 +- fuzzers/fuzzbench/src/lib.rs | 2 +- fuzzers/fuzzbench_fork_qemu/src/fuzzer.rs | 2 +- fuzzers/fuzzbench_qemu/src/fuzzer.rs | 2 +- fuzzers/fuzzbench_text/src/lib.rs | 4 +- fuzzers/libafl_atheris/src/lib.rs | 2 +- fuzzers/libfuzzer_libmozjpeg/src/lib.rs | 2 +- fuzzers/libfuzzer_libpng/src/lib.rs | 2 +- .../libfuzzer_libpng_accounting/src/lib.rs | 2 +- fuzzers/libfuzzer_libpng_cmin/src/lib.rs | 2 +- fuzzers/libfuzzer_libpng_ctx/src/lib.rs | 2 +- fuzzers/libfuzzer_libpng_launcher/src/lib.rs | 2 +- fuzzers/nautilus_sync/src/lib.rs | 2 +- fuzzers/tutorial/src/metadata.rs | 4 +- libafl/src/corpus/inmemory_ondisk.rs | 2 +- libafl/src/corpus/testcase.rs | 6 +- libafl/src/feedbacks/concolic.rs | 2 +- libafl/src/feedbacks/map.rs | 6 +- libafl/src/feedbacks/nautilus.rs | 2 +- libafl/src/feedbacks/new_hash_feedback.rs | 2 +- libafl/src/inputs/generalized.rs | 3 +- libafl/src/mutators/gramatron.rs | 2 +- libafl/src/mutators/grimoire.rs | 16 ++- libafl/src/mutators/mopt_mutator.rs | 12 +-- libafl/src/mutators/nautilus.rs | 2 +- libafl/src/mutators/token_mutations.rs | 16 +-- libafl/src/mutators/tuneable.rs | 8 +- libafl/src/observers/cmp.rs | 12 ++- libafl/src/schedulers/accounting.rs | 30 +++--- libafl/src/schedulers/ecofuzz.rs | 40 +++---- libafl/src/schedulers/minimizer.rs | 43 ++++---- libafl/src/schedulers/powersched.rs | 16 +-- .../src/schedulers/probabilistic_sampling.rs | 6 +- libafl/src/schedulers/testcase_score.rs | 16 +-- libafl/src/schedulers/tuneable.rs | 7 +- libafl/src/schedulers/weighted.rs | 20 ++-- libafl/src/stages/calibrate.rs | 13 ++- libafl/src/stages/colorization.rs | 2 +- libafl/src/stages/concolic.rs | 19 ++-- libafl/src/stages/dump.rs | 2 +- libafl/src/stages/generalization.rs | 4 +- libafl/src/stages/sync.rs | 12 +-- libafl/src/stages/tracing.rs | 2 +- libafl/src/stages/tuneable.rs | 6 +- libafl/src/state/mod.rs | 101 +++++++++++++++--- libafl_qemu/src/cmplog.rs | 4 +- libafl_qemu/src/drcov.rs | 7 +- libafl_qemu/src/edges.rs | 4 +- libafl_sugar/src/forkserver.rs | 2 +- libafl_sugar/src/inmemory.rs | 2 +- libafl_sugar/src/qemu.rs | 2 +- 54 files changed, 296 insertions(+), 201 deletions(-) diff --git a/fuzzers/baby_fuzzer_grimoire/src/main.rs b/fuzzers/baby_fuzzer_grimoire/src/main.rs index ed26dd0e9f..8945a36f52 100644 --- a/fuzzers/baby_fuzzer_grimoire/src/main.rs +++ b/fuzzers/baby_fuzzer_grimoire/src/main.rs @@ -107,7 +107,7 @@ pub fn main() { ) .unwrap(); - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(Tokens::from([b"FOO".to_vec(), b"BAR".to_vec()])); } diff --git a/fuzzers/baby_fuzzer_nautilus/src/main.rs b/fuzzers/baby_fuzzer_nautilus/src/main.rs index 62ab42581b..bd74c04416 100644 --- a/fuzzers/baby_fuzzer_nautilus/src/main.rs +++ b/fuzzers/baby_fuzzer_nautilus/src/main.rs @@ -74,7 +74,7 @@ pub fn main() { ) .unwrap(); - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(NautilusChunksMetadata::new("/tmp/".into())); } diff --git a/fuzzers/frida_gdiplus/src/fuzzer.rs b/fuzzers/frida_gdiplus/src/fuzzer.rs index a9f65693ae..233f6ff114 100644 --- a/fuzzers/frida_gdiplus/src/fuzzer.rs +++ b/fuzzers/frida_gdiplus/src/fuzzer.rs @@ -156,7 +156,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { println!("We're a client, let's fuzz :)"); // Create a PNG dictionary if not existing - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(Tokens::from([ vec![137, 80, 78, 71, 13, 10, 26, 10], // PNG header b"IHDR".to_vec(), @@ -271,7 +271,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { println!("We're a client, let's fuzz :)"); // Create a PNG dictionary if not existing - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(Tokens::from([ vec![137, 80, 78, 71, 13, 10, 26, 10], // PNG header b"IHDR".to_vec(), @@ -401,7 +401,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { println!("We're a client, let's fuzz :)"); // Create a PNG dictionary if not existing - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(Tokens::from([ vec![137, 80, 78, 71, 13, 10, 26, 10], // PNG header b"IHDR".to_vec(), diff --git a/fuzzers/frida_libpng/src/fuzzer.rs b/fuzzers/frida_libpng/src/fuzzer.rs index bd862c3b03..fc53cf4684 100644 --- a/fuzzers/frida_libpng/src/fuzzer.rs +++ b/fuzzers/frida_libpng/src/fuzzer.rs @@ -154,7 +154,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { println!("We're a client, let's fuzz :)"); // Create a PNG dictionary if not existing - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(Tokens::from([ vec![137, 80, 78, 71, 13, 10, 26, 10], // PNG header b"IHDR".to_vec(), @@ -269,7 +269,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { println!("We're a client, let's fuzz :)"); // Create a PNG dictionary if not existing - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(Tokens::from([ vec![137, 80, 78, 71, 13, 10, 26, 10], // PNG header b"IHDR".to_vec(), @@ -399,7 +399,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { println!("We're a client, let's fuzz :)"); // Create a PNG dictionary if not existing - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(Tokens::from([ vec![137, 80, 78, 71, 13, 10, 26, 10], // PNG header b"IHDR".to_vec(), diff --git a/fuzzers/fuzzbench/src/lib.rs b/fuzzers/fuzzbench/src/lib.rs index 06134eafc2..d3f1265eac 100644 --- a/fuzzers/fuzzbench/src/lib.rs +++ b/fuzzers/fuzzbench/src/lib.rs @@ -355,7 +355,7 @@ fn fuzz( let mut stages = tuple_list!(calibration, tracing, i2s, power); // Read tokens - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { let mut toks = Tokens::default(); if let Some(tokenfile) = tokenfile { toks.add_from_file(tokenfile)?; diff --git a/fuzzers/fuzzbench_fork_qemu/src/fuzzer.rs b/fuzzers/fuzzbench_fork_qemu/src/fuzzer.rs index a6f10da254..5e248ca7cc 100644 --- a/fuzzers/fuzzbench_fork_qemu/src/fuzzer.rs +++ b/fuzzers/fuzzbench_fork_qemu/src/fuzzer.rs @@ -351,7 +351,7 @@ fn fuzz( // Read tokens if let Some(tokenfile) = tokenfile { - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(Tokens::from_file(tokenfile)?); } } diff --git a/fuzzers/fuzzbench_qemu/src/fuzzer.rs b/fuzzers/fuzzbench_qemu/src/fuzzer.rs index 71df1762f0..618b2c0910 100644 --- a/fuzzers/fuzzbench_qemu/src/fuzzer.rs +++ b/fuzzers/fuzzbench_qemu/src/fuzzer.rs @@ -366,7 +366,7 @@ fn fuzz( // Read tokens if let Some(tokenfile) = tokenfile { - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(Tokens::from_file(tokenfile)?); } } diff --git a/fuzzers/fuzzbench_text/src/lib.rs b/fuzzers/fuzzbench_text/src/lib.rs index 5fa41f1546..37ddfaa5f3 100644 --- a/fuzzers/fuzzbench_text/src/lib.rs +++ b/fuzzers/fuzzbench_text/src/lib.rs @@ -416,7 +416,7 @@ fn fuzz_binary( let mut stages = tuple_list!(calibration, tracing, i2s, power); // Read tokens - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { let mut toks = Tokens::default(); if let Some(tokenfile) = tokenfile { toks.add_from_file(tokenfile)?; @@ -635,7 +635,7 @@ fn fuzz_text( let mut stages = tuple_list!(generalization, calibration, tracing, i2s, power, grimoire); // Read tokens - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { let mut toks = Tokens::default(); if let Some(tokenfile) = tokenfile { toks.add_from_file(tokenfile)?; diff --git a/fuzzers/libafl_atheris/src/lib.rs b/fuzzers/libafl_atheris/src/lib.rs index 822fdd113d..8e7a814e79 100644 --- a/fuzzers/libafl_atheris/src/lib.rs +++ b/fuzzers/libafl_atheris/src/lib.rs @@ -236,7 +236,7 @@ pub fn LLVMFuzzerRunDriver( }); // Create a dictionary if not existing - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { for tokens_file in &token_files { state.add_metadata(Tokens::from_file(tokens_file)?); } diff --git a/fuzzers/libfuzzer_libmozjpeg/src/lib.rs b/fuzzers/libfuzzer_libmozjpeg/src/lib.rs index 6841d3ceee..034194c204 100644 --- a/fuzzers/libfuzzer_libmozjpeg/src/lib.rs +++ b/fuzzers/libfuzzer_libmozjpeg/src/lib.rs @@ -118,7 +118,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re println!("We're a client, let's fuzz :)"); // Add the JPEG tokens if not existing - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(Tokens::from_file("./jpeg.dict")?); } diff --git a/fuzzers/libfuzzer_libpng/src/lib.rs b/fuzzers/libfuzzer_libpng/src/lib.rs index 7e2653c102..19e880e80e 100644 --- a/fuzzers/libfuzzer_libpng/src/lib.rs +++ b/fuzzers/libfuzzer_libpng/src/lib.rs @@ -128,7 +128,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re println!("We're a client, let's fuzz :)"); // Create a PNG dictionary if not existing - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(Tokens::from([ vec![137, 80, 78, 71, 13, 10, 26, 10], // PNG header "IHDR".as_bytes().to_vec(), diff --git a/fuzzers/libfuzzer_libpng_accounting/src/lib.rs b/fuzzers/libfuzzer_libpng_accounting/src/lib.rs index 1d993a06e4..15c0987512 100644 --- a/fuzzers/libfuzzer_libpng_accounting/src/lib.rs +++ b/fuzzers/libfuzzer_libpng_accounting/src/lib.rs @@ -174,7 +174,7 @@ pub fn libafl_main() { println!("We're a client, let's fuzz :)"); // Create a PNG dictionary if not existing - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(Tokens::from(vec![ vec![137, 80, 78, 71, 13, 10, 26, 10], // PNG header "IHDR".as_bytes().to_vec(), diff --git a/fuzzers/libfuzzer_libpng_cmin/src/lib.rs b/fuzzers/libfuzzer_libpng_cmin/src/lib.rs index ffdec2643d..c459e111c9 100644 --- a/fuzzers/libfuzzer_libpng_cmin/src/lib.rs +++ b/fuzzers/libfuzzer_libpng_cmin/src/lib.rs @@ -127,7 +127,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re println!("We're a client, let's fuzz :)"); // Create a PNG dictionary if not existing - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(Tokens::from([ vec![137, 80, 78, 71, 13, 10, 26, 10], // PNG header "IHDR".as_bytes().to_vec(), diff --git a/fuzzers/libfuzzer_libpng_ctx/src/lib.rs b/fuzzers/libfuzzer_libpng_ctx/src/lib.rs index 367d1e7d48..25d2460e87 100644 --- a/fuzzers/libfuzzer_libpng_ctx/src/lib.rs +++ b/fuzzers/libfuzzer_libpng_ctx/src/lib.rs @@ -168,7 +168,7 @@ pub fn libafl_main() { println!("We're a client, let's fuzz :)"); // Create a PNG dictionary if not existing - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(Tokens::from([ vec![137, 80, 78, 71, 13, 10, 26, 10], // PNG header "IHDR".as_bytes().to_vec(), diff --git a/fuzzers/libfuzzer_libpng_launcher/src/lib.rs b/fuzzers/libfuzzer_libpng_launcher/src/lib.rs index 446e548f41..f24dff75ec 100644 --- a/fuzzers/libfuzzer_libpng_launcher/src/lib.rs +++ b/fuzzers/libfuzzer_libpng_launcher/src/lib.rs @@ -173,7 +173,7 @@ pub fn libafl_main() { println!("We're a client, let's fuzz :)"); // Create a PNG dictionary if not existing - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(Tokens::from([ vec![137, 80, 78, 71, 13, 10, 26, 10], // PNG header "IHDR".as_bytes().to_vec(), diff --git a/fuzzers/nautilus_sync/src/lib.rs b/fuzzers/nautilus_sync/src/lib.rs index 232d7b1d87..9b2340629e 100644 --- a/fuzzers/nautilus_sync/src/lib.rs +++ b/fuzzers/nautilus_sync/src/lib.rs @@ -172,7 +172,7 @@ pub fn libafl_main() { .unwrap() }); - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(NautilusChunksMetadata::new("/tmp/".into())); } diff --git a/fuzzers/tutorial/src/metadata.rs b/fuzzers/tutorial/src/metadata.rs index 9f18862b36..195a552ebf 100644 --- a/fuzzers/tutorial/src/metadata.rs +++ b/fuzzers/tutorial/src/metadata.rs @@ -27,7 +27,7 @@ where { fn compute(entry: &mut Testcase, _state: &S) -> Result { Ok(entry - .metadata() + .metadata_map() .get::() .map_or(1, |m| m.length) as f64) } @@ -69,7 +69,7 @@ where testcase: &mut Testcase, ) -> Result<(), Error> { testcase - .metadata_mut() + .metadata_map_mut() .insert(PacketLenMetadata { length: self.len }); Ok(()) } diff --git a/libafl/src/corpus/inmemory_ondisk.rs b/libafl/src/corpus/inmemory_ondisk.rs index af69bcaf3e..5460bcea5d 100644 --- a/libafl/src/corpus/inmemory_ondisk.rs +++ b/libafl/src/corpus/inmemory_ondisk.rs @@ -230,7 +230,7 @@ where )); let ondisk_meta = OnDiskMetadata { - metadata: testcase.metadata(), + metadata: testcase.metadata_map(), exec_time: testcase.exec_time(), executions: testcase.executions(), }; diff --git a/libafl/src/corpus/testcase.rs b/libafl/src/corpus/testcase.rs index f7e2092cf1..d8e559c18b 100644 --- a/libafl/src/corpus/testcase.rs +++ b/libafl/src/corpus/testcase.rs @@ -45,13 +45,13 @@ where { /// Get all the metadata into an [`hashbrown::HashMap`] #[inline] - fn metadata(&self) -> &SerdeAnyMap { + fn metadata_map(&self) -> &SerdeAnyMap { &self.metadata } /// Get all the metadata into an [`hashbrown::HashMap`] (mutable) #[inline] - fn metadata_mut(&mut self) -> &mut SerdeAnyMap { + fn metadata_map_mut(&mut self) -> &mut SerdeAnyMap { &mut self.metadata } } @@ -476,7 +476,7 @@ pub mod pybind { } fn metadata(&mut self) -> PyObject { - let meta = self.inner.as_mut().metadata_mut(); + let meta = self.inner.as_mut().metadata_map_mut(); if !meta.contains::() { Python::with_gil(|py| { let dict: Py = PyDict::new(py).into(); diff --git a/libafl/src/feedbacks/concolic.rs b/libafl/src/feedbacks/concolic.rs index 96cbcae628..6a2b6aae53 100644 --- a/libafl/src/feedbacks/concolic.rs +++ b/libafl/src/feedbacks/concolic.rs @@ -79,7 +79,7 @@ where .match_name::(&self.name) .map(ConcolicObserver::create_metadata_from_current_map) { - testcase.metadata_mut().insert(metadata); + testcase.metadata_map_mut().insert(metadata); } Ok(()) } diff --git a/libafl/src/feedbacks/map.rs b/libafl/src/feedbacks/map.rs index 7f78ab0589..93af4b783f 100644 --- a/libafl/src/feedbacks/map.rs +++ b/libafl/src/feedbacks/map.rs @@ -441,7 +441,7 @@ where let observer = observers.match_name::(&self.observer_name).unwrap(); let initial = observer.initial(); let map_state = state - .named_metadata_mut() + .named_metadata_map_mut() .get_mut::>(&self.name) .unwrap(); @@ -504,7 +504,7 @@ where let observer = observers.match_name::(&self.observer_name).unwrap(); let map_state = state - .named_metadata_mut() + .named_metadata_map_mut() .get_mut::>(&self.name) .unwrap(); let size = observer.usable_count(); @@ -754,7 +754,7 @@ where let observer = observers.match_name::(&self.observer_name).unwrap(); let map_state = state - .named_metadata_mut() + .named_metadata_map_mut() .get_mut::>(&self.name) .unwrap(); let len = observer.len(); diff --git a/libafl/src/feedbacks/nautilus.rs b/libafl/src/feedbacks/nautilus.rs index a7bd967dd2..c2adbec34c 100644 --- a/libafl/src/feedbacks/nautilus.rs +++ b/libafl/src/feedbacks/nautilus.rs @@ -111,7 +111,7 @@ where { let input = testcase.load_input()?.clone(); let meta = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .expect("NautilusChunksMetadata not in the state"); meta.cks.add_tree(input.tree, self.ctx); diff --git a/libafl/src/feedbacks/new_hash_feedback.rs b/libafl/src/feedbacks/new_hash_feedback.rs index d9b3e7d77e..b0dffab72c 100644 --- a/libafl/src/feedbacks/new_hash_feedback.rs +++ b/libafl/src/feedbacks/new_hash_feedback.rs @@ -115,7 +115,7 @@ where .expect("A NewHashFeedback needs a BacktraceObserver"); let backtrace_state = state - .named_metadata_mut() + .named_metadata_map_mut() .get_mut::(&self.name) .unwrap(); diff --git a/libafl/src/inputs/generalized.rs b/libafl/src/inputs/generalized.rs index 5920e5ce49..445f86090b 100644 --- a/libafl/src/inputs/generalized.rs +++ b/libafl/src/inputs/generalized.rs @@ -113,7 +113,7 @@ where corpus_idx: CorpusId, ) -> Result { let meta = base - .metadata() + .metadata_map() .get::() .ok_or_else(|| { Error::key_not_found(format!( @@ -121,6 +121,7 @@ where )) }) .cloned()?; + Ok(meta) } diff --git a/libafl/src/mutators/gramatron.rs b/libafl/src/mutators/gramatron.rs index caac9a9fcd..aacc086b22 100644 --- a/libafl/src/mutators/gramatron.rs +++ b/libafl/src/mutators/gramatron.rs @@ -125,7 +125,7 @@ where other_testcase.add_metadata(meta); } let meta = other_testcase - .metadata() + .metadata_map() .get::() .unwrap(); let other = other_testcase.input().as_ref().unwrap(); diff --git a/libafl/src/mutators/grimoire.rs b/libafl/src/mutators/grimoire.rs index 2ea854cdec..154eb84ff7 100644 --- a/libafl/src/mutators/grimoire.rs +++ b/libafl/src/mutators/grimoire.rs @@ -34,7 +34,10 @@ where let rand2 = state.rand_mut().next() as usize; let other_testcase = state.corpus().get(idx)?.borrow(); - if let Some(other) = other_testcase.metadata().get::() { + if let Some(other) = other_testcase + .metadata_map() + .get::() + { let gen = other.generalized(); for (i, _) in gen @@ -64,7 +67,7 @@ where let rand1 = state.rand_mut().next() as usize; - if let Some(meta) = state.metadata().get::() { + if let Some(meta) = state.metadata_map().get::() { if !meta.tokens().is_empty() { let tok = &meta.tokens()[rand1 % meta.tokens().len()]; if items.last() != Some(&GeneralizedItem::Gap) { @@ -82,7 +85,10 @@ where } let other_testcase = state.corpus().get(idx)?.borrow(); - if let Some(other) = other_testcase.metadata().get::() { + if let Some(other) = other_testcase + .metadata_map() + .get::() + { let gen = other.generalized(); if items.last() == Some(&GeneralizedItem::Gap) && gen.first() == Some(&GeneralizedItem::Gap) @@ -232,7 +238,7 @@ where _stage_idx: i32, ) -> Result { let tokens_len = { - let meta = state.metadata().get::(); + let meta = state.metadata_map().get::(); if let Some(tokens) = meta { if tokens.is_empty() { return Ok(MutationResult::Skipped); @@ -252,7 +258,7 @@ where let stop_at_first = state.rand_mut().below(100) > 50; let mut rand_idx = state.rand_mut().next() as usize; - let meta = state.metadata().get::().unwrap(); + let meta = state.metadata_map().get::().unwrap(); let token_1 = &meta.tokens()[token_find]; let token_2 = &meta.tokens()[token_replace]; diff --git a/libafl/src/mutators/mopt_mutator.rs b/libafl/src/mutators/mopt_mutator.rs index 2b418fff9a..d4e01290b5 100644 --- a/libafl/src/mutators/mopt_mutator.rs +++ b/libafl/src/mutators/mopt_mutator.rs @@ -413,7 +413,7 @@ where let before = self.finds_before; let after = state.corpus().count() + state.solutions().count(); - let mopt = state.metadata_mut().get_mut::().unwrap(); + let mopt = state.metadata_map_mut().get_mut::().unwrap(); let key_module = self.mode; match key_module { MOptMode::Corefuzzing => { @@ -553,7 +553,7 @@ where stage_idx: i32, ) -> Result { let mut r = MutationResult::Skipped; - let mopt = state.metadata_mut().get_mut::().unwrap(); + let mopt = state.metadata_map_mut().get_mut::().unwrap(); for i in 0..mopt.operator_num { mopt.core_operator_cycles_v3[i] = mopt.core_operator_cycles_v2[i]; } @@ -568,7 +568,7 @@ where } state - .metadata_mut() + .metadata_map_mut() .get_mut::() .unwrap() .core_operator_cycles_v2[idx.0] += 1; @@ -585,7 +585,7 @@ where let mut r = MutationResult::Skipped; let swarm_now; { - let mopt = state.metadata_mut().get_mut::().unwrap(); + let mopt = state.metadata_map_mut().get_mut::().unwrap(); swarm_now = mopt.swarm_now; for i in 0..mopt.operator_num { @@ -604,7 +604,7 @@ where } state - .metadata_mut() + .metadata_map_mut() .get_mut::() .unwrap() .pilot_operator_cycles_v2[swarm_now][idx.0] += 1; @@ -646,7 +646,7 @@ where #[inline] fn schedule(&self, state: &mut S, _: &I) -> MutationId { state - .metadata_mut() + .metadata_map_mut() .get_mut::() .unwrap() .select_algorithm() diff --git a/libafl/src/mutators/nautilus.rs b/libafl/src/mutators/nautilus.rs index 687fd5dccd..a9b259a092 100644 --- a/libafl/src/mutators/nautilus.rs +++ b/libafl/src/mutators/nautilus.rs @@ -165,7 +165,7 @@ where _stage_idx: i32, ) -> Result { let meta = state - .metadata() + .metadata_map() .get::() .expect("NautilusChunksMetadata not in the state"); // TODO get rid of tmp diff --git a/libafl/src/mutators/token_mutations.rs b/libafl/src/mutators/token_mutations.rs index 1da5794a9b..1db75c0099 100644 --- a/libafl/src/mutators/token_mutations.rs +++ b/libafl/src/mutators/token_mutations.rs @@ -304,7 +304,7 @@ where ) -> Result { let max_size = state.max_size(); let tokens_len = { - let meta = state.metadata().get::(); + let meta = state.metadata_map().get::(); if meta.is_none() { return Ok(MutationResult::Skipped); } @@ -318,7 +318,7 @@ where let size = input.bytes().len(); let off = state.rand_mut().below((size + 1) as u64) as usize; - let meta = state.metadata().get::().unwrap(); + let meta = state.metadata_map().get::().unwrap(); let token = &meta.tokens()[token_idx]; let mut len = token.len(); @@ -374,7 +374,7 @@ where } let tokens_len = { - let meta = state.metadata().get::(); + let meta = state.metadata_map().get::(); if meta.is_none() { return Ok(MutationResult::Skipped); } @@ -387,7 +387,7 @@ where let off = state.rand_mut().below(size as u64) as usize; - let meta = state.metadata().get::().unwrap(); + let meta = state.metadata_map().get::().unwrap(); let token = &meta.tokens()[token_idx]; let mut len = token.len(); if off + len > size { @@ -437,7 +437,7 @@ where } let cmps_len = { - let meta = state.metadata().get::(); + let meta = state.metadata_map().get::(); if meta.is_none() { return Ok(MutationResult::Skipped); } @@ -452,7 +452,7 @@ where let len = input.bytes().len(); let bytes = input.bytes_mut(); - let meta = state.metadata().get::().unwrap(); + let meta = state.metadata_map().get::().unwrap(); let cmp_values = &meta.list[idx]; let mut result = MutationResult::Skipped; @@ -1077,8 +1077,8 @@ where } let (cmp_len, cmp_meta, taint_meta) = { - let cmp_meta = state.metadata().get::(); - let taint_meta = state.metadata().get::(); + let cmp_meta = state.metadata_map().get::(); + let taint_meta = state.metadata_map().get::(); if cmp_meta.is_none() || taint_meta.is_none() { return Ok(MutationResult::Skipped); } diff --git a/libafl/src/mutators/tuneable.rs b/libafl/src/mutators/tuneable.rs index 2bb0acc9c3..2e122d7ec0 100644 --- a/libafl/src/mutators/tuneable.rs +++ b/libafl/src/mutators/tuneable.rs @@ -57,7 +57,7 @@ impl TuneableScheduledMutatorMetadata { /// Gets the stored metadata, used to alter the [`TuneableScheduledMutator`] behavior pub fn get(state: &S) -> Result<&Self, Error> { state - .metadata() + .metadata_map() .get::() .ok_or_else(|| Error::illegal_state("TuneableScheduledMutator not in use")) } @@ -65,7 +65,7 @@ impl TuneableScheduledMutatorMetadata { /// Gets the stored metadata, used to alter the [`TuneableScheduledMutator`] behavior, mut pub fn get_mut(state: &mut S) -> Result<&mut Self, Error> { state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::illegal_state("TuneableScheduledMutator not in use")) } @@ -228,14 +228,14 @@ where { fn metadata_mut(state: &mut S) -> &mut TuneableScheduledMutatorMetadata { state - .metadata_mut() + .metadata_map_mut() .get_mut::() .unwrap() } fn metadata(state: &S) -> &TuneableScheduledMutatorMetadata { state - .metadata() + .metadata_map() .get::() .unwrap() } diff --git a/libafl/src/observers/cmp.rs b/libafl/src/observers/cmp.rs index 32d668ad77..1f7abae347 100644 --- a/libafl/src/observers/cmp.rs +++ b/libafl/src/observers/cmp.rs @@ -138,11 +138,14 @@ where S: HasMetadata, { #[allow(clippy::option_if_let_else)] // we can't mutate state in a closure - let meta = if let Some(meta) = state.metadata_mut().get_mut::() { + let meta = if let Some(meta) = state.metadata_map_mut().get_mut::() { meta } else { state.add_metadata(CmpValuesMetadata::new()); - state.metadata_mut().get_mut::().unwrap() + state + .metadata_map_mut() + .get_mut::() + .unwrap() }; meta.list.clear(); let count = self.usable_count(); @@ -390,12 +393,13 @@ where S: HasMetadata, { #[allow(clippy::option_if_let_else)] // we can't mutate state in a closure - let meta = if let Some(meta) = state.metadata_mut().get_mut::() { + let meta = if let Some(meta) = state.metadata_map_mut().get_mut::() + { meta } else { state.add_metadata(AFLppCmpValuesMetadata::new()); state - .metadata_mut() + .metadata_map_mut() .get_mut::() .unwrap() }; diff --git a/libafl/src/schedulers/accounting.rs b/libafl/src/schedulers/accounting.rs index 3b6e3bd4ab..92d6549c9e 100644 --- a/libafl/src/schedulers/accounting.rs +++ b/libafl/src/schedulers/accounting.rs @@ -145,7 +145,7 @@ where fn next(&mut self, state: &mut Self::State) -> Result { if state - .metadata() + .metadata_map() .get::() .map_or(false, |x| x.changed) { @@ -207,7 +207,7 @@ where let mut equal_score = false; { - let top_acc = state.metadata().get::().unwrap(); + let top_acc = state.metadata_map().get::().unwrap(); if let Some(old_idx) = top_acc.map.get(&idx) { if top_acc.max_accounting[idx] > self.accounting_map[idx] { @@ -220,7 +220,7 @@ where let mut old = state.corpus().get(*old_idx)?.borrow_mut(); let must_remove = { - let old_meta = old.metadata_mut().get_mut::().ok_or_else(|| { + let old_meta = old.metadata_map_mut().get_mut::().ok_or_else(|| { Error::key_not_found(format!( "AccountingIndexesMetadata, needed by CoverageAccountingScheduler, not found in testcase #{old_idx}" )) @@ -230,13 +230,13 @@ where }; if must_remove { - drop(old.metadata_mut().remove::()); + drop(old.metadata_map_mut().remove::()); } } } let top_acc = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .unwrap(); @@ -255,12 +255,18 @@ where return Ok(()); } - state.corpus().get(idx)?.borrow_mut().metadata_mut().insert( - AccountingIndexesMetadata::with_tcref(indexes, new_favoreds.len() as isize), - ); + state + .corpus() + .get(idx)? + .borrow_mut() + .metadata_map_mut() + .insert(AccountingIndexesMetadata::with_tcref( + indexes, + new_favoreds.len() as isize, + )); let top_acc = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .unwrap(); top_acc.changed = true; @@ -275,7 +281,7 @@ where /// Cull the `Corpus` #[allow(clippy::unused_self)] pub fn accounting_cull(&self, state: &mut CS::State) -> Result<(), Error> { - let Some(top_rated) = state.metadata().get::() else { return Ok(()) }; + let Some(top_rated) = state.metadata_map().get::() else { return Ok(()) }; for (_key, idx) in &top_rated.map { let mut entry = state.corpus().get(*idx)?.borrow_mut(); @@ -292,7 +298,7 @@ where /// Creates a new [`CoverageAccountingScheduler`] that wraps a `base` [`Scheduler`] /// and has a default probability to skip non-faved Testcases of [`DEFAULT_SKIP_NON_FAVORED_PROB`]. pub fn new(state: &mut CS::State, base: CS, accounting_map: &'a [u32]) -> Self { - match state.metadata().get::() { + match state.metadata_map().get::() { Some(meta) => { if meta.max_accounting.len() != accounting_map.len() { state.add_metadata(TopAccountingMetadata::new(accounting_map.len())); @@ -317,7 +323,7 @@ where skip_non_favored_prob: u64, accounting_map: &'a [u32], ) -> Self { - match state.metadata().get::() { + match state.metadata_map().get::() { Some(meta) => { if meta.max_accounting.len() != accounting_map.len() { state.add_metadata(TopAccountingMetadata::new(accounting_map.len())); diff --git a/libafl/src/schedulers/ecofuzz.rs b/libafl/src/schedulers/ecofuzz.rs index 3fc815d8fb..5574074609 100644 --- a/libafl/src/schedulers/ecofuzz.rs +++ b/libafl/src/schedulers/ecofuzz.rs @@ -102,7 +102,7 @@ where let (last_mutation_num, last_corpus_count) = { let meta = state - .metadata() + .metadata_map() .get::() .ok_or_else(|| Error::key_not_found("EcoMetadata not found".to_string()))?; (meta.last_mutation_num, meta.last_corpus_count) @@ -112,7 +112,7 @@ where let mut testcase = state.corpus().get(id)?.borrow_mut(); let meta = testcase - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::key_not_found("EcoTestcaseMetadata not found".to_string()))?; // Set was_fuzzed for the old current @@ -122,7 +122,7 @@ where }; let meta = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::key_not_found("EcoMetadata not found".to_string()))?; @@ -151,7 +151,7 @@ where fn first_iteration(state: &mut S) -> Result<(), Error> { let count = state.corpus().count(); state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::key_not_found("EcoMetadata not found".to_string()))? .initial_corpus_count @@ -174,7 +174,7 @@ where let was_fuzzed = state.corpus().get(id)?.borrow().scheduled_count() > 0; if was_fuzzed { state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::key_not_found("EcoMetadata not found".to_string()))? .state = EcoState::Exploration; @@ -183,7 +183,7 @@ where } state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::key_not_found("EcoMetadata not found".to_string()))? .state = EcoState::Exploitation; @@ -194,7 +194,7 @@ where .corpus() .get(id)? .borrow() - .metadata() + .metadata_map() .get::() .ok_or_else(|| Error::key_not_found("EcoTestcaseMetadata not found".to_string()))? .state; @@ -210,7 +210,7 @@ where .corpus() .get(id)? .borrow_mut() - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| { Error::key_not_found("EcoTestcaseMetadata not found".to_string()) @@ -226,7 +226,7 @@ where .corpus() .get(selection)? .borrow() - .metadata() + .metadata_map() .get::() .ok_or_else(|| Error::key_not_found("EcoTestcaseMetadata not found".to_string()))? .clone(); @@ -234,7 +234,7 @@ where for id in state.corpus().ids() { let testcase = state.corpus().get(id)?.borrow(); let meta = testcase - .metadata() + .metadata_map() .get::() .ok_or_else(|| Error::key_not_found("EcoTestcaseMetadata not found".to_string()))?; @@ -274,7 +274,7 @@ where .corpus() .get(parent_idx)? .borrow_mut() - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| { Error::key_not_found("SchedulerTestcaseMetaData not found".to_string()) @@ -302,7 +302,7 @@ where let executions = *state.executions(); let meta = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::key_not_found("EcoMetadata not found".to_string()))?; @@ -328,7 +328,7 @@ where let mut hash = observer.hash() as usize; let psmeta = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::key_not_found("SchedulerMetadata not found".to_string()))?; @@ -341,7 +341,7 @@ where .corpus() .get(id)? .borrow_mut() - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::key_not_found("EcoTestcaseMetadata not found".to_string()))? .mutation_num += 1; @@ -350,7 +350,7 @@ where .corpus() .get(id)? .borrow() - .metadata() + .metadata_map() .get::() .ok_or_else(|| { Error::key_not_found("SchedulerTestcaseMetaData not found".to_string()) @@ -361,7 +361,7 @@ where .corpus() .get(id)? .borrow_mut() - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| { Error::key_not_found("EcoTestcaseMetadata not found".to_string()) @@ -389,7 +389,7 @@ where .corpus() .get(id)? .borrow_mut() - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::key_not_found("EcoTestcaseMetadata not found".to_string()))? .mutation_num; @@ -397,7 +397,7 @@ where let executions = *state.executions(); let meta = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::key_not_found("EcoMetadata not found".to_string()))?; meta.last_mutation_num = mutation_num; @@ -453,14 +453,14 @@ where let (cur_state, rate) = { let meta = state - .metadata() + .metadata_map() .get::() .ok_or_else(|| Error::key_not_found("EcoMetadata not found".to_string()))?; (meta.state, meta.rate) }; let meta = entry - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::key_not_found("EcoTestcaseMetadata not found".to_string()))?; diff --git a/libafl/src/schedulers/minimizer.rs b/libafl/src/schedulers/minimizer.rs index d925c6cfee..3955250fe1 100644 --- a/libafl/src/schedulers/minimizer.rs +++ b/libafl/src/schedulers/minimizer.rs @@ -101,22 +101,23 @@ where testcase: &Option::Input>>, ) -> Result<(), Error> { self.base.on_remove(state, idx, testcase)?; - let mut entries = if let Some(meta) = state.metadata_mut().get_mut::() { - let entries = meta - .map - .drain_filter(|_, other_idx| *other_idx == idx) - .map(|(entry, _)| entry) - .collect::>(); - entries - } else { - return Ok(()); - }; + let mut entries = + if let Some(meta) = state.metadata_map_mut().get_mut::() { + let entries = meta + .map + .drain_filter(|_, other_idx| *other_idx == idx) + .map(|(entry, _)| entry) + .collect::>(); + entries + } else { + return Ok(()); + }; entries.sort_unstable(); // this should already be sorted, but just in case let mut map = HashMap::new(); for i in state.corpus().ids() { let mut old = state.corpus().get(i)?.borrow_mut(); let factor = F::compute(&mut *old, state)?; - if let Some(old_map) = old.metadata_mut().get_mut::() { + if let Some(old_map) = old.metadata_map_mut().get_mut::() { let mut e_iter = entries.iter(); let mut map_iter = old_map.as_slice().iter(); // ASSERTION: guaranteed to be in order? @@ -150,7 +151,7 @@ where } } } - if let Some(meta) = state.metadata_mut().get_mut::() { + if let Some(meta) = state.metadata_map_mut().get_mut::() { meta.map .extend(map.into_iter().map(|(entry, (_, idx))| (entry, idx))); } @@ -225,7 +226,7 @@ where #[allow(clippy::cast_possible_wrap)] pub fn update_score(&self, state: &mut CS::State, idx: CorpusId) -> Result<(), Error> { // Create a new top rated meta if not existing - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(TopRatedsMetadata::new()); } @@ -233,12 +234,12 @@ where { let mut entry = state.corpus().get(idx)?.borrow_mut(); let factor = F::compute(&mut *entry, state)?; - let meta = entry.metadata_mut().get_mut::().ok_or_else(|| { + let meta = entry.metadata_map_mut().get_mut::().ok_or_else(|| { Error::key_not_found(format!( "Metadata needed for MinimizerScheduler not found in testcase #{idx}" )) })?; - let top_rateds = state.metadata().get::().unwrap(); + let top_rateds = state.metadata_map().get::().unwrap(); for elem in meta.as_slice() { if let Some(old_idx) = top_rateds.map.get(elem) { if *old_idx == idx { @@ -251,7 +252,7 @@ where } let must_remove = { - let old_meta = old.metadata_mut().get_mut::().ok_or_else(|| { + let old_meta = old.metadata_map_mut().get_mut::().ok_or_else(|| { Error::key_not_found(format!( "{} needed for MinimizerScheduler not found in testcase #{old_idx}", type_name::() @@ -262,7 +263,7 @@ where }; if must_remove { - drop(old.metadata_mut().remove::()); + drop(old.metadata_map_mut().remove::()); } } @@ -278,7 +279,7 @@ where .corpus() .get(idx)? .borrow_mut() - .metadata_mut() + .metadata_map_mut() .remove::(), ); return Ok(()); @@ -286,7 +287,7 @@ where for elem in new_favoreds { state - .metadata_mut() + .metadata_map_mut() .get_mut::() .unwrap() .map @@ -298,14 +299,14 @@ where /// Cull the `Corpus` using the `MinimizerScheduler` #[allow(clippy::unused_self)] pub fn cull(&self, state: &mut CS::State) -> Result<(), Error> { - let Some(top_rated) = state.metadata().get::() else { return Ok(()) }; + let Some(top_rated) = state.metadata_map().get::() else { return Ok(()) }; let mut acc = HashSet::new(); for (key, idx) in &top_rated.map { if !acc.contains(key) { let mut entry = state.corpus().get(*idx)?.borrow_mut(); - let meta = entry.metadata().get::().ok_or_else(|| { + let meta = entry.metadata_map().get::().ok_or_else(|| { Error::key_not_found(format!( "{} needed for MinimizerScheduler not found in testcase #{idx}", type_name::() diff --git a/libafl/src/schedulers/powersched.rs b/libafl/src/schedulers/powersched.rs index 3ef37685ac..31d4ff12f7 100644 --- a/libafl/src/schedulers/powersched.rs +++ b/libafl/src/schedulers/powersched.rs @@ -191,7 +191,7 @@ where prev: &Testcase<::Input>, ) -> Result<(), Error> { let prev_meta = prev - .metadata() + .metadata_map() .get::() .ok_or_else(|| { Error::key_not_found("SchedulerTestcaseMetaData not found".to_string()) @@ -206,7 +206,7 @@ where let prev_bitmap_size_log = libm::log2(prev_bitmap_size as f64); let psmeta = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::key_not_found("SchedulerMetadata not found".to_string()))?; @@ -239,7 +239,7 @@ where })?; let prev_meta = prev - .metadata() + .metadata_map() .get::() .ok_or_else(|| { Error::key_not_found("SchedulerTestcaseMetaData not found".to_string()) @@ -251,7 +251,7 @@ where let prev_bitmap_size_log = libm::log2(prev_bitmap_size as f64); let psmeta = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::key_not_found("SchedulerMetadata not found".to_string()))?; @@ -279,7 +279,7 @@ where .corpus() .get(parent_idx)? .borrow() - .metadata() + .metadata_map() .get::() .ok_or_else(|| { Error::key_not_found("SchedulerTestcaseMetaData not found".to_string()) @@ -318,7 +318,7 @@ where let mut hash = observer.hash() as usize; let psmeta = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::key_not_found("SchedulerMetadata not found".to_string()))?; @@ -341,7 +341,7 @@ where next } else { let psmeta = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| { Error::key_not_found("SchedulerMetadata not found".to_string()) @@ -374,7 +374,7 @@ where testcase.set_scheduled_count(scheduled_count + 1); let tcmeta = testcase - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| { Error::key_not_found("SchedulerTestcaseMetaData not found".to_string()) diff --git a/libafl/src/schedulers/probabilistic_sampling.rs b/libafl/src/schedulers/probabilistic_sampling.rs index cacbebd2fd..3e0f906b86 100644 --- a/libafl/src/schedulers/probabilistic_sampling.rs +++ b/libafl/src/schedulers/probabilistic_sampling.rs @@ -77,7 +77,7 @@ where )); } let meta = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .unwrap(); let prob = 1.0 / factor; @@ -107,7 +107,7 @@ where .borrow_mut() .set_parent_id_optional(current_idx); - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(ProbabilityMetadata::new()); } self.store_probability(state, idx) @@ -120,7 +120,7 @@ where Err(Error::empty(String::from("No entries in corpus"))) } else { let rand_prob: f64 = (state.rand_mut().below(100) as f64) / 100.0; - let meta = state.metadata().get::().unwrap(); + let meta = state.metadata_map().get::().unwrap(); let threshold = meta.total_probability * rand_prob; let mut k: f64 = 0.0; let mut ret = *meta.map.keys().last().unwrap(); diff --git a/libafl/src/schedulers/testcase_score.rs b/libafl/src/schedulers/testcase_score.rs index fc91ee6592..2d3c4326bf 100644 --- a/libafl/src/schedulers/testcase_score.rs +++ b/libafl/src/schedulers/testcase_score.rs @@ -67,7 +67,7 @@ where )] fn compute(entry: &mut Testcase, state: &S) -> Result { let psmeta = state - .metadata() + .metadata_map() .get::() .ok_or_else(|| Error::key_not_found("SchedulerMetadata not found".to_string()))?; @@ -80,7 +80,7 @@ where for idx in corpus.ids() { let n_fuzz_entry = if cur_index == idx { entry - .metadata() + .metadata_map() .get::() .ok_or_else(|| { Error::key_not_found( @@ -92,7 +92,7 @@ where corpus .get(idx)? .borrow() - .metadata() + .metadata_map() .get::() .ok_or_else(|| { Error::key_not_found( @@ -129,7 +129,7 @@ where let favored = entry.has_metadata::(); let tcmeta = entry - .metadata() + .metadata_map() .get::() .ok_or_else(|| { Error::key_not_found("SchedulerTestcaseMetaData not found".to_string()) @@ -296,12 +296,12 @@ where fn compute(entry: &mut Testcase, state: &S) -> Result { let mut weight = 1.0; let psmeta = state - .metadata() + .metadata_map() .get::() .ok_or_else(|| Error::key_not_found("SchedulerMetadata not found".to_string()))?; let tcmeta = entry - .metadata() + .metadata_map() .get::() .ok_or_else(|| { Error::key_not_found("SchedulerTestcaseMetaData not found".to_string()) @@ -344,13 +344,13 @@ where weight *= avg_exec_us / q_exec_us; weight *= libm::log2(q_bitmap_size).max(1.0) / avg_bitmap_size; - let tc_ref = match entry.metadata().get::() { + let tc_ref = match entry.metadata_map().get::() { Some(meta) => meta.refcnt() as f64, None => 0.0, }; let avg_top_size = state - .metadata() + .metadata_map() .get::() .ok_or_else(|| Error::key_not_found("TopRatedsMetadata not found".to_string()))? .map() diff --git a/libafl/src/schedulers/tuneable.rs b/libafl/src/schedulers/tuneable.rs index 1d8a74aeaa..37e75985ac 100644 --- a/libafl/src/schedulers/tuneable.rs +++ b/libafl/src/schedulers/tuneable.rs @@ -48,13 +48,16 @@ where fn metadata_mut(state: &mut S) -> &mut TuneableSchedulerMetadata { state - .metadata_mut() + .metadata_map_mut() .get_mut::() .unwrap() } fn metadata(state: &S) -> &TuneableSchedulerMetadata { - state.metadata().get::().unwrap() + state + .metadata_map() + .get::() + .unwrap() } /// Sets the next corpus id to be used diff --git a/libafl/src/schedulers/weighted.rs b/libafl/src/schedulers/weighted.rs index 2e6ebd6c42..5bdcc5d590 100644 --- a/libafl/src/schedulers/weighted.rs +++ b/libafl/src/schedulers/weighted.rs @@ -209,7 +209,7 @@ where } let wsmeta = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| { Error::key_not_found("WeigthedScheduleMetadata not found".to_string()) @@ -249,7 +249,7 @@ where })?; let prev_meta = prev - .metadata() + .metadata_map() .get::() .ok_or_else(|| { Error::key_not_found("SchedulerTestcaseMetaData not found".to_string()) @@ -261,7 +261,7 @@ where let prev_bitmap_size_log = libm::log2(prev_bitmap_size as f64); let psmeta = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::key_not_found("SchedulerMetadata not found".to_string()))?; @@ -282,7 +282,7 @@ where prev: &crate::corpus::Testcase<::Input>, ) -> Result<(), Error> { let prev_meta = prev - .metadata() + .metadata_map() .get::() .ok_or_else(|| { Error::key_not_found("SchedulerTestcaseMetaData not found".to_string()) @@ -297,7 +297,7 @@ where let prev_bitmap_size_log = libm::log2(prev_bitmap_size as f64); let psmeta = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::key_not_found("SchedulerMetadata not found".to_string()))?; @@ -332,7 +332,7 @@ where .corpus() .get(parent_idx)? .borrow_mut() - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| { Error::key_not_found("SchedulerTestcaseMetaData not found".to_string()) @@ -376,7 +376,7 @@ where let mut hash = observer.hash() as usize; let psmeta = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::key_not_found("SchedulerMetadata not found".to_string()))?; @@ -401,7 +401,7 @@ where let probability = state.rand_mut().between(0, 1000000000) as f64 / 1000000000_f64; let wsmeta = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| { Error::key_not_found("WeigthedScheduleMetadata not found".to_string()) @@ -425,7 +425,7 @@ where // Update depth if current_cycles > corpus_counts { let psmeta = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| { Error::key_not_found("SchedulerMetadata not found".to_string()) @@ -454,7 +454,7 @@ where testcase.set_scheduled_count(scheduled_count + 1); let tcmeta = testcase - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| { Error::key_not_found("SchedulerTestcaseMetaData not found".to_string()) diff --git a/libafl/src/stages/calibrate.rs b/libafl/src/stages/calibrate.rs index 5a573c7038..ce9cedca82 100644 --- a/libafl/src/stages/calibrate.rs +++ b/libafl/src/stages/calibrate.rs @@ -199,7 +199,7 @@ where .to_vec(); let history_map = &mut state - .named_metadata_mut() + .named_metadata_map_mut() .get_mut::>(&self.map_name) .unwrap() .history_map; @@ -230,7 +230,7 @@ where // If we see new stable entries executing this new corpus entries, then merge with the existing one if state.has_metadata::() { let existing = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .unwrap(); for item in unstable_entries { @@ -261,7 +261,10 @@ where let bitmap_size = map.count_bytes(); - let psmeta = state.metadata_mut().get_mut::().unwrap(); + let psmeta = state + .metadata_map_mut() + .get_mut::() + .unwrap(); let handicap = psmeta.queue_cycles(); psmeta.set_exec_time(psmeta.exec_time() + total_time); @@ -278,7 +281,7 @@ where // log::trace!("time: {:#?}", testcase.exec_time()); let data = testcase - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| { Error::key_not_found("SchedulerTestcaseMetaData not found".to_string()) @@ -290,7 +293,7 @@ where } // Send the stability event to the broker - if let Some(meta) = state.metadata().get::() { + if let Some(meta) = state.metadata_map().get::() { let unstable_entries = meta.unstable_entries().len(); let map_len = meta.map_len(); mgr.fire( diff --git a/libafl/src/stages/colorization.rs b/libafl/src/stages/colorization.rs index 7692a557e2..4287178e53 100644 --- a/libafl/src/stages/colorization.rs +++ b/libafl/src/stages/colorization.rs @@ -272,7 +272,7 @@ where } } - if let Some(meta) = state.metadata_mut().get_mut::() { + if let Some(meta) = state.metadata_map_mut().get_mut::() { meta.update(input.bytes().to_vec(), res); // println!("meta: {:#?}", meta); diff --git a/libafl/src/stages/concolic.rs b/libafl/src/stages/concolic.rs index bc9e18b44f..a16b2d7777 100644 --- a/libafl/src/stages/concolic.rs +++ b/libafl/src/stages/concolic.rs @@ -61,7 +61,7 @@ where .get(corpus_idx) .unwrap() .borrow_mut() - .metadata_mut() + .metadata_map_mut() .insert(metadata); } Ok(()) @@ -367,14 +367,15 @@ where let testcase = state.corpus().get(corpus_idx)?.clone(); mark_feature_time!(state, PerfFeature::GetInputFromCorpus); - let mutations = if let Some(meta) = testcase.borrow().metadata().get::() { - start_timer!(state); - let mutations = generate_mutations(meta.iter_messages()); - mark_feature_time!(state, PerfFeature::Mutate); - Some(mutations) - } else { - None - }; + let mutations = + if let Some(meta) = testcase.borrow().metadata_map().get::() { + start_timer!(state); + let mutations = generate_mutations(meta.iter_messages()); + mark_feature_time!(state, PerfFeature::Mutate); + Some(mutations) + } else { + None + }; if let Some(mutations) = mutations { let input = { testcase.borrow().input().as_ref().unwrap().clone() }; diff --git a/libafl/src/stages/dump.rs b/libafl/src/stages/dump.rs index 585533fddb..9f980c5ce7 100644 --- a/libafl/src/stages/dump.rs +++ b/libafl/src/stages/dump.rs @@ -57,7 +57,7 @@ where _corpus_idx: CorpusId, ) -> Result<(), Error> { let (mut corpus_idx, mut solutions_idx) = - if let Some(meta) = state.metadata().get::() { + if let Some(meta) = state.metadata_map().get::() { ( meta.last_corpus.and_then(|x| state.corpus().next(x)), meta.last_solution.and_then(|x| state.solutions().next(x)), diff --git a/libafl/src/stages/generalization.rs b/libafl/src/stages/generalization.rs index c51ef85004..96e2446370 100644 --- a/libafl/src/stages/generalization.rs +++ b/libafl/src/stages/generalization.rs @@ -87,7 +87,7 @@ where let payload: Vec<_> = input.bytes().iter().map(|&x| Some(x)).collect(); let original = input.clone(); - let meta = entry.metadata().get::().ok_or_else(|| { + let meta = entry.metadata_map().get::().ok_or_else(|| { Error::key_not_found(format!( "MapNoveltiesMetadata needed for GeneralizationStage not found in testcase #{corpus_idx} (check the arguments of MapFeedback::new(...))" )) @@ -292,7 +292,7 @@ where assert!(meta.generalized().last() == Some(&GeneralizedItem::Gap)); let mut entry = state.corpus().get(corpus_idx)?.borrow_mut(); - entry.metadata_mut().insert(meta); + entry.metadata_map_mut().insert(meta); } } diff --git a/libafl/src/stages/sync.rs b/libafl/src/stages/sync.rs index 376921250d..a661184472 100644 --- a/libafl/src/stages/sync.rs +++ b/libafl/src/stages/sync.rs @@ -71,7 +71,7 @@ where _corpus_idx: CorpusId, ) -> Result<(), Error> { let last = state - .metadata() + .metadata_map() .get::() .map(|m| m.last_time); let path = self.sync_dir.clone(); @@ -80,11 +80,11 @@ where { if last.is_none() { state - .metadata_mut() + .metadata_map_mut() .insert(SyncFromDiskMetadata::new(max_time)); } else { state - .metadata_mut() + .metadata_map_mut() .get_mut::() .unwrap() .last_time = max_time; @@ -254,7 +254,7 @@ where ) -> Result<(), Error> { if self.client.can_convert() { let last_id = state - .metadata() + .metadata_map() .get::() .and_then(|m| m.last_id); @@ -283,11 +283,11 @@ where let last = state.corpus().last(); if last_id.is_none() { state - .metadata_mut() + .metadata_map_mut() .insert(SyncFromBrokerMetadata::new(last)); } else { state - .metadata_mut() + .metadata_map_mut() .get_mut::() .unwrap() .last_id = last; diff --git a/libafl/src/stages/tracing.rs b/libafl/src/stages/tracing.rs index c061b462af..4269b2af82 100644 --- a/libafl/src/stages/tracing.rs +++ b/libafl/src/stages/tracing.rs @@ -178,7 +178,7 @@ where .post_exec_all(state, &unmutated_input, &exit_kind)?; // Second run with the mutated input - let mutated_input = match state.metadata().get::() { + let mutated_input = match state.metadata_map().get::() { Some(meta) => BytesInput::from(meta.input_vec().as_ref()), None => return Err(Error::unknown("No metadata found")), }; diff --git a/libafl/src/stages/tuneable.rs b/libafl/src/stages/tuneable.rs index 9b46933a14..01b9aa0cd6 100644 --- a/libafl/src/stages/tuneable.rs +++ b/libafl/src/stages/tuneable.rs @@ -27,7 +27,7 @@ impl_serdeany!(TuneableMutationalStageMetadata); /// Set the number of iterations to be used by this mutational stage pub fn set_iters(state: &mut S, iters: u64) -> Result<(), Error> { let metadata = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::illegal_state("TuneableMutationslStage not in use")); metadata.map(|metadata| { @@ -38,7 +38,7 @@ pub fn set_iters(state: &mut S, iters: u64) -> Result<(), Error> /// Get the set iterations pub fn get_iters(state: &S) -> Result, Error> { state - .metadata() + .metadata_map() .get::() .ok_or_else(|| Error::illegal_state("TuneableMutationslStage not in use")) .map(|metadata| metadata.iters) @@ -47,7 +47,7 @@ pub fn get_iters(state: &S) -> Result, Error> { /// Reset this to a normal, randomized, stage pub fn reset(state: &mut S) -> Result<(), Error> { state - .metadata_mut() + .metadata_map_mut() .get_mut::() .ok_or_else(|| Error::illegal_state("TuneableMutationslStage not in use")) .map(|metadata| metadata.iters = None) diff --git a/libafl/src/state/mod.rs b/libafl/src/state/mod.rs index 3d0da72fb4..d87a6a9c3c 100644 --- a/libafl/src/state/mod.rs +++ b/libafl/src/state/mod.rs @@ -1,6 +1,11 @@ //! The fuzzer, and state are the core pieces of every good fuzzer -use core::{fmt::Debug, marker::PhantomData, time::Duration}; +use core::{ + cell::{Ref, RefMut}, + fmt::Debug, + marker::PhantomData, + time::Duration, +}; #[cfg(feature = "std")] use std::{ fs, @@ -17,7 +22,7 @@ use crate::{ rands::Rand, serdeany::{NamedSerdeAnyMap, SerdeAny, SerdeAnyMap}, }, - corpus::{Corpus, CorpusId}, + corpus::{Corpus, CorpusId, Testcase}, events::{Event, EventFirer, LogSeverity}, feedbacks::Feedback, fuzzer::{Evaluator, ExecuteInputResult}, @@ -101,9 +106,9 @@ pub trait HasClientPerfMonitor { /// Trait for elements offering metadata pub trait HasMetadata { /// A map, storing all metadata - fn metadata(&self) -> &SerdeAnyMap; + fn metadata_map(&self) -> &SerdeAnyMap; /// A map, storing all metadata (mutable) - fn metadata_mut(&mut self) -> &mut SerdeAnyMap; + fn metadata_map_mut(&mut self) -> &mut SerdeAnyMap; /// Add a metadata to the metadata map #[inline] @@ -111,7 +116,7 @@ pub trait HasMetadata { where M: SerdeAny, { - self.metadata_mut().insert(meta); + self.metadata_map_mut().insert(meta); } /// Check for a metadata @@ -120,16 +125,38 @@ pub trait HasMetadata { where M: SerdeAny, { - self.metadata().get::().is_some() + self.metadata_map().get::().is_some() + } + + /// To get metadata + #[inline] + fn metadata(&self) -> Result<&M, Error> + where + M: SerdeAny, + { + self.metadata_map().get::().ok_or_else(|| { + Error::key_not_found(format!("{} not found", core::any::type_name::())) + }) + } + + /// To get mutable metadata + #[inline] + fn metadata_mut(&mut self) -> Result<&mut M, Error> + where + M: SerdeAny, + { + self.metadata_map_mut().get_mut::().ok_or_else(|| { + Error::key_not_found(format!("{} not found", core::any::type_name::())) + }) } } /// Trait for elements offering named metadata pub trait HasNamedMetadata { /// A map, storing all metadata - fn named_metadata(&self) -> &NamedSerdeAnyMap; + fn named_metadata_map(&self) -> &NamedSerdeAnyMap; /// A map, storing all metadata (mutable) - fn named_metadata_mut(&mut self) -> &mut NamedSerdeAnyMap; + fn named_metadata_map_mut(&mut self) -> &mut NamedSerdeAnyMap; /// Add a metadata to the metadata map #[inline] @@ -137,7 +164,7 @@ pub trait HasNamedMetadata { where M: SerdeAny, { - self.named_metadata_mut().insert(meta, name); + self.named_metadata_map_mut().insert(meta, name); } /// Check for a metadata @@ -146,7 +173,31 @@ pub trait HasNamedMetadata { where M: SerdeAny, { - self.named_metadata().contains::(name) + self.named_metadata_map().contains::(name) + } + + /// To get named metadata + #[inline] + fn named_metadata(&self, name: &str) -> Result<&M, Error> + where + M: SerdeAny, + { + self.named_metadata_map().get::(name).ok_or_else(|| { + Error::key_not_found(format!("{} not found", core::any::type_name::())) + }) + } + + /// To get mutable named metadata + #[inline] + fn named_metadata_mut(&mut self, name: &str) -> Result<&mut M, Error> + where + M: SerdeAny, + { + self.named_metadata_map_mut() + .get_mut::(name) + .ok_or_else(|| { + Error::key_not_found(format!("{} not found", core::any::type_name::())) + }) } } @@ -168,6 +219,22 @@ pub trait HasStartTime { fn start_time_mut(&mut self) -> &mut Duration; } +/// Trait for the testcase +pub trait HasTestcase: HasCorpus { + /// To get the testcase + fn testcase(&self, id: CorpusId) -> Result::Input>>, Error> { + Ok(self.corpus().get(id)?.borrow()) + } + + /// To get mutable testcase + fn testcase_mut( + &mut self, + id: CorpusId, + ) -> Result::Input>>, Error> { + Ok(self.corpus().get(id)?.borrow_mut()) + } +} + /// The state a fuzz run. #[derive(Serialize, Deserialize, Clone, Debug)] #[serde(bound = " @@ -280,13 +347,13 @@ where impl HasMetadata for StdState { /// Get all the metadata into an [`hashbrown::HashMap`] #[inline] - fn metadata(&self) -> &SerdeAnyMap { + fn metadata_map(&self) -> &SerdeAnyMap { &self.metadata } /// Get all the metadata into an [`hashbrown::HashMap`] (mutable) #[inline] - fn metadata_mut(&mut self) -> &mut SerdeAnyMap { + fn metadata_map_mut(&mut self) -> &mut SerdeAnyMap { &mut self.metadata } } @@ -294,13 +361,13 @@ impl HasMetadata for StdState { impl HasNamedMetadata for StdState { /// Get all the metadata into an [`hashbrown::HashMap`] #[inline] - fn named_metadata(&self) -> &NamedSerdeAnyMap { + fn named_metadata_map(&self) -> &NamedSerdeAnyMap { &self.named_metadata } /// Get all the metadata into an [`hashbrown::HashMap`] (mutable) #[inline] - fn named_metadata_mut(&mut self) -> &mut NamedSerdeAnyMap { + fn named_metadata_map_mut(&mut self) -> &mut NamedSerdeAnyMap { &mut self.named_metadata } } @@ -771,11 +838,11 @@ impl HasExecutions for NopState { #[cfg(test)] impl HasMetadata for NopState { - fn metadata(&self) -> &SerdeAnyMap { + fn metadata_map(&self) -> &SerdeAnyMap { &self.metadata } - fn metadata_mut(&mut self) -> &mut SerdeAnyMap { + fn metadata_map_mut(&mut self) -> &mut SerdeAnyMap { &mut self.metadata } } @@ -878,7 +945,7 @@ pub mod pybind { } fn metadata(&mut self) -> PyObject { - let meta = self.inner.as_mut().metadata_mut(); + let meta = self.inner.as_mut().metadata_map_mut(); if !meta.contains::() { Python::with_gil(|py| { let dict: Py = PyDict::new(py).into(); diff --git a/libafl_qemu/src/cmplog.rs b/libafl_qemu/src/cmplog.rs index 3c771b51d0..687ed58c62 100644 --- a/libafl_qemu/src/cmplog.rs +++ b/libafl_qemu/src/cmplog.rs @@ -132,11 +132,11 @@ where } } let state = state.expect("The gen_unique_cmp_ids hook works only for in-process fuzzing"); - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(QemuCmpsMapMetadata::new()); } let meta = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .unwrap(); let id = meta.current_id as usize; diff --git a/libafl_qemu/src/drcov.rs b/libafl_qemu/src/drcov.rs index ceff8404fb..6724794437 100644 --- a/libafl_qemu/src/drcov.rs +++ b/libafl_qemu/src/drcov.rs @@ -214,13 +214,16 @@ where let state = state.expect("The gen_unique_block_ids hook works only for in-process fuzzing"); if state - .metadata_mut() + .metadata_map_mut() .get_mut::() .is_none() { state.add_metadata(QemuDrCovMetadata::new()); } - let meta = state.metadata_mut().get_mut::().unwrap(); + let meta = state + .metadata_map_mut() + .get_mut::() + .unwrap(); match DRCOV_MAP.lock().unwrap().as_mut().unwrap().entry(pc) { Entry::Occupied(e) => { diff --git a/libafl_qemu/src/edges.rs b/libafl_qemu/src/edges.rs index 942fc951e7..927e2f3972 100644 --- a/libafl_qemu/src/edges.rs +++ b/libafl_qemu/src/edges.rs @@ -167,11 +167,11 @@ where } } let state = state.expect("The gen_unique_edge_ids hook works only for in-process fuzzing"); - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(QemuEdgesMapMetadata::new()); } let meta = state - .metadata_mut() + .metadata_map_mut() .get_mut::() .unwrap(); diff --git a/libafl_sugar/src/forkserver.rs b/libafl_sugar/src/forkserver.rs index 9210dd1c62..9fc4a599cb 100644 --- a/libafl_sugar/src/forkserver.rs +++ b/libafl_sugar/src/forkserver.rs @@ -162,7 +162,7 @@ impl<'a, const MAP_SIZE: usize> ForkserverBytesCoverageSugar<'a, MAP_SIZE> { // Create a dictionary if not existing if let Some(tokens_file) = &self.tokens_file { - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(Tokens::from_file(tokens_file)?); } } diff --git a/libafl_sugar/src/inmemory.rs b/libafl_sugar/src/inmemory.rs index 8a2922506a..8bd04d096c 100644 --- a/libafl_sugar/src/inmemory.rs +++ b/libafl_sugar/src/inmemory.rs @@ -181,7 +181,7 @@ where // Create a dictionary if not existing if let Some(tokens_file) = &self.tokens_file { - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(Tokens::from_file(tokens_file)?); } } diff --git a/libafl_sugar/src/qemu.rs b/libafl_sugar/src/qemu.rs index a439edb761..109dd8d232 100644 --- a/libafl_sugar/src/qemu.rs +++ b/libafl_sugar/src/qemu.rs @@ -192,7 +192,7 @@ where // Create a dictionary if not existing if let Some(tokens_file) = &self.tokens_file { - if state.metadata().get::().is_none() { + if state.metadata_map().get::().is_none() { state.add_metadata(Tokens::from_file(tokens_file)?); } }