From 4c17da00b0783d8e4d758a17891fcc0e75d6c494 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Wed, 11 Oct 2023 21:19:30 +0200 Subject: [PATCH] Clipped Fixxy (#1622) * clippy fix * fix * fix * it works * imports --- libafl/src/events/mod.rs | 1 + libafl/src/executors/inprocess.rs | 1 + libafl/src/mutators/token_mutations.rs | 5 + .../concolic/serialization_format.rs | 120 +++++++------- libafl/src/observers/map.rs | 148 +++++++++++++++++- libafl/src/observers/stacktrace.rs | 1 + libafl/src/observers/value.rs | 10 +- libafl/src/stages/tmin.rs | 14 +- libafl_bolts/src/lib.rs | 11 ++ libafl_bolts/src/ownedref.rs | 13 +- .../symcc_runtime/src/filter/coverage.rs | 4 +- libafl_targets/src/sancov_8bit.rs | 14 ++ 12 files changed, 245 insertions(+), 97 deletions(-) diff --git a/libafl/src/events/mod.rs b/libafl/src/events/mod.rs index 88b310f64b..d7961f1d81 100644 --- a/libafl/src/events/mod.rs +++ b/libafl/src/events/mod.rs @@ -77,6 +77,7 @@ pub type ShutdownFuncPtr = /// /// This will acceess `data` and write to the global `data.staterestorer_ptr` if it's not null. #[cfg(all(unix, feature = "std"))] +#[allow(clippy::needless_pass_by_value)] pub unsafe fn shutdown_handler( signal: Signal, _info: &mut siginfo_t, diff --git a/libafl/src/executors/inprocess.rs b/libafl/src/executors/inprocess.rs index d5ad6f2f31..3dad667167 100644 --- a/libafl/src/executors/inprocess.rs +++ b/libafl/src/executors/inprocess.rs @@ -2,6 +2,7 @@ //! It should usually be paired with extra error-handling, such as a restarting event manager, to be effective. //! //! Needs the `fork` feature flag. +#![allow(clippy::needless_pass_by_value)] use alloc::boxed::Box; #[cfg(all(unix, feature = "std"))] diff --git a/libafl/src/mutators/token_mutations.rs b/libafl/src/mutators/token_mutations.rs index ba3f07eeee..8055ee4556 100644 --- a/libafl/src/mutators/token_mutations.rs +++ b/libafl/src/mutators/token_mutations.rs @@ -223,6 +223,11 @@ impl Tokens { pub fn tokens(&self) -> &[Vec] { &self.tokens_vec } + + /// Returns an iterator over the tokens. + pub fn iter(&self) -> Iter<'_, Vec> { + <&Self as IntoIterator>::into_iter(self) + } } impl AddAssign for Tokens { diff --git a/libafl/src/observers/concolic/serialization_format.rs b/libafl/src/observers/concolic/serialization_format.rs index c6a6032b16..f980baae24 100644 --- a/libafl/src/observers/concolic/serialization_format.rs +++ b/libafl/src/observers/concolic/serialization_format.rs @@ -381,66 +381,6 @@ impl MessageFileWriter { } } -#[cfg(test)] -mod serialization_tests { - use alloc::vec::Vec; - use std::io::Cursor; - - use super::{MessageFileReader, MessageFileWriter, SymExpr}; - - /// This test intends to ensure that the serialization format can efficiently encode the required information. - /// This is mainly useful to fail if any changes should be made in the future that (inadvertently) reduce - /// serialization efficiency. - #[test] - fn efficient_serialization() { - let mut buf = Vec::new(); - { - let mut cursor = Cursor::new(&mut buf); - let mut writer = MessageFileWriter::from_writer(&mut cursor).unwrap(); - let a = writer.write_message(SymExpr::True).unwrap(); - let b = writer.write_message(SymExpr::True).unwrap(); - writer.write_message(SymExpr::And { a, b }).unwrap(); - writer.update_trace_header().unwrap(); - } - let expected_size = 8 + // the header takes 8 bytes to encode the length of the trace - 1 + // tag to create SymExpr::True (a) - 1 + // tag to create SymExpr::True (b) - 1 + // tag to create SymExpr::And - 1 + // reference to a - 1; // reference to b - assert_eq!(buf.len(), expected_size); - } - - /// This test intends to verify that a trace written by [`MessageFileWriter`] can indeed be read back by - /// [`MessageFileReader`]. - #[test] - fn serialization_roundtrip() { - let mut buf = Vec::new(); - { - let mut cursor = Cursor::new(&mut buf); - let mut writer = MessageFileWriter::from_writer(&mut cursor).unwrap(); - let a = writer.write_message(SymExpr::True).unwrap(); - let b = writer.write_message(SymExpr::True).unwrap(); - writer.write_message(SymExpr::And { a, b }).unwrap(); - writer.update_trace_header().unwrap(); - } - let mut reader = MessageFileReader::from_length_prefixed_buffer(&buf).unwrap(); - let (first_bool_id, first_bool) = reader.next_message().unwrap().unwrap(); - assert_eq!(first_bool, SymExpr::True); - let (second_bool_id, second_bool) = reader.next_message().unwrap().unwrap(); - assert_eq!(second_bool, SymExpr::True); - let (_, and) = reader.next_message().unwrap().unwrap(); - assert_eq!( - and, - SymExpr::And { - a: first_bool_id, - b: second_bool_id - } - ); - assert!(reader.next_message().is_none()); - } -} - use libafl_bolts::shmem::{ShMem, ShMemCursor, ShMemProvider, StdShMemProvider}; /// The default environment variable name to use for the shared memory used by the concolic tracing @@ -511,3 +451,63 @@ impl MessageFileWriter::ShMem>> /// A writer that will write messages to a shared memory buffer. pub type StdShMemMessageFileWriter = MessageFileWriter::ShMem>>; + +#[cfg(test)] +mod serialization_tests { + use alloc::vec::Vec; + use std::io::Cursor; + + use super::{MessageFileReader, MessageFileWriter, SymExpr}; + + /// This test intends to ensure that the serialization format can efficiently encode the required information. + /// This is mainly useful to fail if any changes should be made in the future that (inadvertently) reduce + /// serialization efficiency. + #[test] + fn efficient_serialization() { + let mut buf = Vec::new(); + { + let mut cursor = Cursor::new(&mut buf); + let mut writer = MessageFileWriter::from_writer(&mut cursor).unwrap(); + let a = writer.write_message(SymExpr::True).unwrap(); + let b = writer.write_message(SymExpr::True).unwrap(); + writer.write_message(SymExpr::And { a, b }).unwrap(); + writer.update_trace_header().unwrap(); + } + let expected_size = 8 + // the header takes 8 bytes to encode the length of the trace + 1 + // tag to create SymExpr::True (a) + 1 + // tag to create SymExpr::True (b) + 1 + // tag to create SymExpr::And + 1 + // reference to a + 1; // reference to b + assert_eq!(buf.len(), expected_size); + } + + /// This test intends to verify that a trace written by [`MessageFileWriter`] can indeed be read back by + /// [`MessageFileReader`]. + #[test] + fn serialization_roundtrip() { + let mut buf = Vec::new(); + { + let mut cursor = Cursor::new(&mut buf); + let mut writer = MessageFileWriter::from_writer(&mut cursor).unwrap(); + let a = writer.write_message(SymExpr::True).unwrap(); + let b = writer.write_message(SymExpr::True).unwrap(); + writer.write_message(SymExpr::And { a, b }).unwrap(); + writer.update_trace_header().unwrap(); + } + let mut reader = MessageFileReader::from_length_prefixed_buffer(&buf).unwrap(); + let (first_bool_id, first_bool) = reader.next_message().unwrap().unwrap(); + assert_eq!(first_bool, SymExpr::True); + let (second_bool_id, second_bool) = reader.next_message().unwrap().unwrap(); + assert_eq!(second_bool, SymExpr::True); + let (_, and) = reader.next_message().unwrap().unwrap(); + assert_eq!( + and, + SymExpr::And { + a: first_bool_id, + b: second_bool_id + } + ); + assert!(reader.next_message().is_none()); + } +} diff --git a/libafl/src/observers/map.rs b/libafl/src/observers/map.rs index 64a15b9a10..27bc6aa56c 100644 --- a/libafl/src/observers/map.rs +++ b/libafl/src/observers/map.rs @@ -324,6 +324,28 @@ where } } +impl<'a, T, const DIFFERENTIAL: bool> StdMapObserver<'a, T, DIFFERENTIAL> +where + T: Bounded + + PartialEq + + Default + + Copy + + 'static + + Serialize + + serde::de::DeserializeOwned + + Debug, +{ + /// Returns an iterator over the map. + pub fn iter(&self) -> Iter<'_, T> { + <&Self as IntoIterator>::into_iter(self) + } + + /// Returns a mutable iterator over the map. + pub fn iter_mut(&mut self) -> IterMut<'_, T> { + <&mut Self as IntoIterator>::into_iter(self) + } +} + impl<'a, T, const DIFFERENTIAL: bool> MapObserver for StdMapObserver<'a, T, DIFFERENTIAL> where T: Bounded @@ -781,6 +803,28 @@ where } } +impl<'a, T, const N: usize> ConstMapObserver<'a, T, N> +where + T: Bounded + + PartialEq + + Default + + Copy + + 'static + + Serialize + + serde::de::DeserializeOwned + + Debug, +{ + /// Returns an iterator over the map. + pub fn iter(&self) -> Iter<'_, T> { + <&Self as IntoIterator>::into_iter(self) + } + + /// Returns a mutable iterator over the map. + pub fn iter_mut(&mut self) -> IterMut<'_, T> { + <&mut Self as IntoIterator>::into_iter(self) + } +} + impl<'a, T, const N: usize> MapObserver for ConstMapObserver<'a, T, N> where T: Bounded @@ -1054,6 +1098,28 @@ where } } +impl<'a, T> VariableMapObserver<'a, T> +where + T: Bounded + + PartialEq + + Default + + Copy + + 'static + + Serialize + + serde::de::DeserializeOwned + + Debug, +{ + /// Returns an iterator over the map. + pub fn iter(&self) -> Iter<'_, T> { + <&Self as IntoIterator>::into_iter(self) + } + + /// Returns a mutable iterator over the map. + pub fn iter_mut(&mut self) -> IterMut<'_, T> { + <&mut Self as IntoIterator>::into_iter(self) + } +} + impl<'a, T> MapObserver for VariableMapObserver<'a, T> where T: Bounded @@ -1412,7 +1478,7 @@ where impl<'it, M> IntoIterator for &'it HitcountsMapObserver where - M: Named + Serialize + serde::de::DeserializeOwned, + M: Serialize + serde::de::DeserializeOwned, &'it M: IntoIterator, { type Item = &'it u8; @@ -1425,7 +1491,7 @@ where impl<'it, M> IntoIterator for &'it mut HitcountsMapObserver where - M: Named + Serialize + serde::de::DeserializeOwned, + M: Serialize + serde::de::DeserializeOwned, &'it mut M: IntoIterator, { type Item = &'it mut u8; @@ -1436,6 +1502,28 @@ where } } +impl HitcountsMapObserver +where + M: Serialize + serde::de::DeserializeOwned, + for<'it> &'it M: IntoIterator, +{ + /// Returns an iterator over the map. + pub fn iter(&self) -> <&M as IntoIterator>::IntoIter { + <&Self as IntoIterator>::into_iter(self) + } +} + +impl HitcountsMapObserver +where + M: Serialize + serde::de::DeserializeOwned, + for<'it> &'it mut M: IntoIterator, +{ + /// Returns a mutable iterator over the map. + pub fn iter_mut(&mut self) -> <&mut M as IntoIterator>::IntoIter { + <&mut Self as IntoIterator>::into_iter(self) + } +} + impl DifferentialObserver for HitcountsMapObserver where M: DifferentialObserver @@ -1639,7 +1727,7 @@ where impl<'it, M> IntoIterator for &'it HitcountsIterableMapObserver where - M: Named + Serialize + serde::de::DeserializeOwned, + M: Serialize + serde::de::DeserializeOwned, &'it M: IntoIterator, { type Item = &'it u8; @@ -1652,7 +1740,7 @@ where impl<'it, M> IntoIterator for &'it mut HitcountsIterableMapObserver where - M: Named + Serialize + serde::de::DeserializeOwned, + M: Serialize + serde::de::DeserializeOwned, &'it mut M: IntoIterator, { type Item = &'it mut u8; @@ -1663,6 +1751,28 @@ where } } +impl HitcountsIterableMapObserver +where + M: Serialize + serde::de::DeserializeOwned, + for<'it> &'it M: IntoIterator, +{ + /// Returns an iterator over the map. + pub fn iter(&self) -> <&M as IntoIterator>::IntoIter { + <&Self as IntoIterator>::into_iter(self) + } +} + +impl HitcountsIterableMapObserver +where + M: Serialize + serde::de::DeserializeOwned, + for<'it> &'it mut M: IntoIterator, +{ + /// Returns a mutable iterator over the map. + pub fn iter_mut(&mut self) -> <&mut M as IntoIterator>::IntoIter { + <&mut Self as IntoIterator>::into_iter(self) + } +} + impl DifferentialObserver for HitcountsIterableMapObserver where M: MapObserver + Observer + DifferentialObserver, @@ -1967,6 +2077,21 @@ where } } +impl<'a, T, const DIFFERENTIAL: bool> MultiMapObserver<'a, T, DIFFERENTIAL> +where + T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, +{ + /// Returns an iterator over the map. + pub fn iter(&self) -> <&Self as IntoIterator>::IntoIter { + <&Self as IntoIterator>::into_iter(self) + } + + /// Returns a mutable iterator over the map. + pub fn iter_mut(&mut self) -> <&mut Self as IntoIterator>::IntoIter { + <&mut Self as IntoIterator>::into_iter(self) + } +} + impl<'a, T, OTA, OTB, S> DifferentialObserver for MultiMapObserver<'a, T, true> where T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, @@ -2071,6 +2196,21 @@ where } } +impl OwnedMapObserver +where + T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, +{ + /// Returns an iterator over the map. + pub fn iter(&self) -> Iter<'_, T> { + <&Self as IntoIterator>::into_iter(self) + } + + /// Returns a mutable iterator over the map. + pub fn iter_mut(&mut self) -> IterMut<'_, T> { + <&mut Self as IntoIterator>::into_iter(self) + } +} + impl MapObserver for OwnedMapObserver where T: Bounded diff --git a/libafl/src/observers/stacktrace.rs b/libafl/src/observers/stacktrace.rs index ac14252f61..ae63b27981 100644 --- a/libafl/src/observers/stacktrace.rs +++ b/libafl/src/observers/stacktrace.rs @@ -19,6 +19,7 @@ use std::{ use backtrace::Backtrace; use libafl_bolts::{ownedref::OwnedRefMut, Named}; +#[allow(unused_imports)] #[cfg(feature = "casr")] use libcasr::{ asan::AsanStacktrace, diff --git a/libafl/src/observers/value.rs b/libafl/src/observers/value.rs index 4322bf806f..e2ed1cd745 100644 --- a/libafl/src/observers/value.rs +++ b/libafl/src/observers/value.rs @@ -7,7 +7,7 @@ use alloc::{ use core::{ cell::{Ref, RefCell}, fmt::Debug, - hash::{BuildHasher, Hash, Hasher}, + hash::Hash, ops::Deref, }; @@ -96,9 +96,7 @@ where T: Debug + Serialize + serde::de::DeserializeOwned, { fn hash(&self) -> Option { - let mut s = RandomState::with_seeds(1, 2, 3, 4).build_hasher(); - Hash::hash(self.value.as_ref(), &mut s); - Some(s.finish()) + Some(RandomState::with_seeds(1, 2, 3, 4).hash_one(self.value.as_ref())) } } @@ -180,8 +178,6 @@ where T: Debug + Serialize + serde::de::DeserializeOwned, { fn hash(&self) -> Option { - let mut s = RandomState::with_seeds(1, 2, 3, 4).build_hasher(); - self.value.as_ref().borrow().hash(&mut s); - Some(s.finish()) + Some(RandomState::with_seeds(1, 2, 3, 4).hash_one(&*self.value.as_ref().borrow())) } } diff --git a/libafl/src/stages/tmin.rs b/libafl/src/stages/tmin.rs index d9f1a0755f..c532904cae 100644 --- a/libafl/src/stages/tmin.rs +++ b/libafl/src/stages/tmin.rs @@ -1,11 +1,7 @@ //! The [`TMinMutationalStage`] is a stage which will attempt to minimize corpus entries. use alloc::string::{String, ToString}; -use core::{ - fmt::Debug, - hash::{BuildHasher, Hash, Hasher}, - marker::PhantomData, -}; +use core::{fmt::Debug, hash::Hash, marker::PhantomData}; use ahash::RandomState; use libafl_bolts::{HasLen, Named}; @@ -73,9 +69,7 @@ where start_timer!(state); let mut base = state.corpus().cloned_input_for_id(base_corpus_idx)?; - let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); - base.hash(&mut hasher); - let base_hash = hasher.finish(); + let base_hash = RandomState::with_seeds(0, 0, 0, 0).hash_one(&base); mark_feature_time!(state, PerfFeature::GetInputFromCorpus); fuzzer.execute_input(state, executor, manager, &base)?; @@ -151,9 +145,7 @@ where i = next_i; } - let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); - base.hash(&mut hasher); - let new_hash = hasher.finish(); + let new_hash = RandomState::with_seeds(0, 0, 0, 0).hash_one(&base); if base_hash != new_hash { let exit_kind = fuzzer.execute_input(state, executor, manager, &base)?; let observers = executor.observers(); diff --git a/libafl_bolts/src/lib.rs b/libafl_bolts/src/lib.rs index a1cc6518c0..cf3950f4cf 100644 --- a/libafl_bolts/src/lib.rs +++ b/libafl_bolts/src/lib.rs @@ -556,6 +556,17 @@ pub unsafe extern "C" fn external_current_millis() -> u64 { 1000 } +/// Trait to convert into an Owned type +pub trait IntoOwned { + /// Returns if the current type is an owned type. + #[must_use] + fn is_owned(&self) -> bool; + + /// Transfer the current type into an owned type. + #[must_use] + fn into_owned(self) -> Self; +} + /// Can be converted to a slice pub trait AsSlice { /// Type of the entries in this slice diff --git a/libafl_bolts/src/ownedref.rs b/libafl_bolts/src/ownedref.rs index fee5f7885b..de9c592838 100644 --- a/libafl_bolts/src/ownedref.rs +++ b/libafl_bolts/src/ownedref.rs @@ -10,18 +10,7 @@ use core::{clone::Clone, fmt::Debug, slice}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use crate::{AsMutSlice, AsSlice, Truncate}; - -/// Trait to convert into an Owned type -pub trait IntoOwned { - /// Returns if the current type is an owned type. - #[must_use] - fn is_owned(&self) -> bool; - - /// Transfer the current type into an owned type. - #[must_use] - fn into_owned(self) -> Self; -} +use crate::{AsMutSlice, AsSlice, IntoOwned, Truncate}; impl<'a, T> Truncate for &'a [T] { fn truncate(&mut self, len: usize) { diff --git a/libafl_concolic/symcc_runtime/src/filter/coverage.rs b/libafl_concolic/symcc_runtime/src/filter/coverage.rs index c20e0993f6..8d5c1cc56e 100644 --- a/libafl_concolic/symcc_runtime/src/filter/coverage.rs +++ b/libafl_concolic/symcc_runtime/src/filter/coverage.rs @@ -189,10 +189,8 @@ where } fn register_location_on_hitmap(&mut self, location: usize) { - let mut hasher = self.build_hasher.build_hasher(); - location.hash(&mut hasher); #[allow(clippy::cast_possible_truncation)] // we cannot have more than usize elements.. - let hash = (hasher.finish() % usize::MAX as u64) as usize; + let hash = (self.build_hasher.hash_one(location) % usize::MAX as u64) as usize; let val = unsafe { // SAFETY: the index is modulo by the length, therefore it is always in bounds let len = self.hitcounts_map.len(); diff --git a/libafl_targets/src/sancov_8bit.rs b/libafl_targets/src/sancov_8bit.rs index 2a6b4b4ddc..94636d9401 100644 --- a/libafl_targets/src/sancov_8bit.rs +++ b/libafl_targets/src/sancov_8bit.rs @@ -340,6 +340,20 @@ mod observers { } } + impl CountersMultiMapObserver { + /// Returns an iterator over the map. + #[must_use] + pub fn iter(&self) -> <&Self as IntoIterator>::IntoIter { + <&Self as IntoIterator>::into_iter(self) + } + + /// Returns a mutable iterator over the map. + #[must_use] + pub fn iter_mut(&mut self) -> <&mut Self as IntoIterator>::IntoIter { + <&mut Self as IntoIterator>::into_iter(self) + } + } + impl DifferentialObserver for CountersMultiMapObserver where Self: MapObserver,