parent
67aa5b12c1
commit
4c17da00b0
@ -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<SP>(
|
||||
signal: Signal,
|
||||
_info: &mut siginfo_t,
|
||||
|
@ -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"))]
|
||||
|
@ -223,6 +223,11 @@ impl Tokens {
|
||||
pub fn tokens(&self) -> &[Vec<u8>] {
|
||||
&self.tokens_vec
|
||||
}
|
||||
|
||||
/// Returns an iterator over the tokens.
|
||||
pub fn iter(&self) -> Iter<'_, Vec<u8>> {
|
||||
<&Self as IntoIterator>::into_iter(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign for Tokens {
|
||||
|
@ -381,66 +381,6 @@ impl<W: Write + Seek> MessageFileWriter<W> {
|
||||
}
|
||||
}
|
||||
|
||||
#[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<ShMemCursor<<StdShMemProvider as ShMemProvider>::ShMem>>
|
||||
/// A writer that will write messages to a shared memory buffer.
|
||||
pub type StdShMemMessageFileWriter =
|
||||
MessageFileWriter<ShMemCursor<<StdShMemProvider as ShMemProvider>::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());
|
||||
}
|
||||
}
|
||||
|
@ -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<M>
|
||||
where
|
||||
M: Named + Serialize + serde::de::DeserializeOwned,
|
||||
M: Serialize + serde::de::DeserializeOwned,
|
||||
&'it M: IntoIterator<Item = &'it u8>,
|
||||
{
|
||||
type Item = &'it u8;
|
||||
@ -1425,7 +1491,7 @@ where
|
||||
|
||||
impl<'it, M> IntoIterator for &'it mut HitcountsMapObserver<M>
|
||||
where
|
||||
M: Named + Serialize + serde::de::DeserializeOwned,
|
||||
M: Serialize + serde::de::DeserializeOwned,
|
||||
&'it mut M: IntoIterator<Item = &'it mut u8>,
|
||||
{
|
||||
type Item = &'it mut u8;
|
||||
@ -1436,6 +1502,28 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> HitcountsMapObserver<M>
|
||||
where
|
||||
M: Serialize + serde::de::DeserializeOwned,
|
||||
for<'it> &'it M: IntoIterator<Item = &'it u8>,
|
||||
{
|
||||
/// Returns an iterator over the map.
|
||||
pub fn iter(&self) -> <&M as IntoIterator>::IntoIter {
|
||||
<&Self as IntoIterator>::into_iter(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> HitcountsMapObserver<M>
|
||||
where
|
||||
M: Serialize + serde::de::DeserializeOwned,
|
||||
for<'it> &'it mut M: IntoIterator<Item = &'it mut u8>,
|
||||
{
|
||||
/// 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<M, OTA, OTB, S> DifferentialObserver<OTA, OTB, S> for HitcountsMapObserver<M>
|
||||
where
|
||||
M: DifferentialObserver<OTA, OTB, S>
|
||||
@ -1639,7 +1727,7 @@ where
|
||||
|
||||
impl<'it, M> IntoIterator for &'it HitcountsIterableMapObserver<M>
|
||||
where
|
||||
M: Named + Serialize + serde::de::DeserializeOwned,
|
||||
M: Serialize + serde::de::DeserializeOwned,
|
||||
&'it M: IntoIterator<Item = &'it u8>,
|
||||
{
|
||||
type Item = &'it u8;
|
||||
@ -1652,7 +1740,7 @@ where
|
||||
|
||||
impl<'it, M> IntoIterator for &'it mut HitcountsIterableMapObserver<M>
|
||||
where
|
||||
M: Named + Serialize + serde::de::DeserializeOwned,
|
||||
M: Serialize + serde::de::DeserializeOwned,
|
||||
&'it mut M: IntoIterator<Item = &'it mut u8>,
|
||||
{
|
||||
type Item = &'it mut u8;
|
||||
@ -1663,6 +1751,28 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> HitcountsIterableMapObserver<M>
|
||||
where
|
||||
M: Serialize + serde::de::DeserializeOwned,
|
||||
for<'it> &'it M: IntoIterator<Item = &'it u8>,
|
||||
{
|
||||
/// Returns an iterator over the map.
|
||||
pub fn iter(&self) -> <&M as IntoIterator>::IntoIter {
|
||||
<&Self as IntoIterator>::into_iter(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> HitcountsIterableMapObserver<M>
|
||||
where
|
||||
M: Serialize + serde::de::DeserializeOwned,
|
||||
for<'it> &'it mut M: IntoIterator<Item = &'it mut u8>,
|
||||
{
|
||||
/// 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<M, OTA, OTB, S> DifferentialObserver<OTA, OTB, S> for HitcountsIterableMapObserver<M>
|
||||
where
|
||||
M: MapObserver<Entry = u8> + Observer<S> + DifferentialObserver<OTA, OTB, S>,
|
||||
@ -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<OTA, OTB, S> for MultiMapObserver<'a, T, true>
|
||||
where
|
||||
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
@ -2071,6 +2196,21 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> OwnedMapObserver<T>
|
||||
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<T> MapObserver for OwnedMapObserver<T>
|
||||
where
|
||||
T: Bounded
|
||||
|
@ -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,
|
||||
|
@ -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<u64> {
|
||||
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<u64> {
|
||||
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()))
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -340,6 +340,20 @@ mod observers {
|
||||
}
|
||||
}
|
||||
|
||||
impl<const DIFFERENTIAL: bool> CountersMultiMapObserver<DIFFERENTIAL> {
|
||||
/// 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<OTA, OTB, S> DifferentialObserver<OTA, OTB, S> for CountersMultiMapObserver<true>
|
||||
where
|
||||
Self: MapObserver,
|
||||
|
Loading…
x
Reference in New Issue
Block a user