From 67f6aecb6b0d621e408f89983465c3e75a507d35 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Thu, 10 Dec 2020 10:06:29 +0100 Subject: [PATCH] serializable observers to --- afl/src/feedbacks/mod.rs | 8 ++-- afl/src/observers/mod.rs | 52 +++++++++++++---------- afl/src/serde_anymap.rs | 89 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 25 deletions(-) diff --git a/afl/src/feedbacks/mod.rs b/afl/src/feedbacks/mod.rs index 39f2d505dd..d187fe95c6 100644 --- a/afl/src/feedbacks/mod.rs +++ b/afl/src/feedbacks/mod.rs @@ -89,7 +89,7 @@ where /// The most common AFL-like feedback type pub struct MapFeedback where - T: Integer + Copy + 'static, + T: Integer + Default + Copy + 'static, R: Reducer, O: MapObserver, { @@ -103,7 +103,7 @@ where impl Feedback for MapFeedback where - T: Integer + Copy + 'static, + T: Integer + Default + Copy + 'static, R: Reducer, O: MapObserver + 'static, I: Input, @@ -137,7 +137,7 @@ where impl MapFeedback where - T: Integer + Copy + Default + 'static, + T: Integer + Default + Copy + 'static, R: Reducer, O: MapObserver, { @@ -153,7 +153,7 @@ where impl MapFeedback where - T: Integer + Copy + 'static, + T: Integer + Default + Copy + 'static, R: Reducer, O: MapObserver, { diff --git a/afl/src/observers/mod.rs b/afl/src/observers/mod.rs index 8ca330ca9e..047d8ed47f 100644 --- a/afl/src/observers/mod.rs +++ b/afl/src/observers/mod.rs @@ -6,7 +6,7 @@ use core::slice::from_raw_parts_mut; use num::Integer; use serde::{Deserialize, Serialize}; -use crate::serde_anymap::{SerdeAny, SliceMut}; +use crate::serde_anymap::{SerdeAny, ArrayMut}; use crate::AflError; // TODO register each observer in the Registry in new() @@ -29,10 +29,12 @@ pub trait Observer: SerdeAny + 'static { crate::create_serde_registry_for_trait!(observer_serde, crate::observers::Observer); + + /// A MapObserver observes the static map, as oftentimes used for afl-like coverage information pub trait MapObserver where - T: Integer + Copy, + T: Default + Copy, { /// Get the map fn map(&self) -> &[T]; @@ -63,19 +65,19 @@ where /// The Map Observer retrieves the state of a map, /// that will get updated by the target. /// A well-known example is the AFL-Style coverage map. -#[derive(Serialize, Deserialize)] +#[derive(Serialize)] pub struct StdMapObserver where - T: Integer + Copy + 'static + serde::Serialize + serde::Deserialize<'static>, + T: Default + Copy+ 'static + serde::Serialize + serde::de::DeserializeOwned, { - map: SliceMut<'static, T>, + map: ArrayMut, initial: T, name: &'static str, } impl Observer for StdMapObserver where - T: Integer + Copy + 'static + serde::Serialize + serde::Deserialize<'static>, +T: Default + Copy+ 'static + serde::Serialize + serde::de::DeserializeOwned, { fn reset(&mut self) -> Result<(), AflError> { self.reset_map() @@ -88,7 +90,7 @@ where impl SerdeAny for StdMapObserver where - T: Integer + Copy + 'static + serde::Serialize + serde::Deserialize<'static>, + T: Default + Copy+ 'static + serde::Serialize + serde::de::DeserializeOwned, { fn as_any(&self) -> &dyn Any { self @@ -100,20 +102,14 @@ where impl MapObserver for StdMapObserver where - T: Integer + Copy + 'static + serde::Serialize + serde::Deserialize<'static>, +T: Default + Copy+ 'static + serde::Serialize + serde::de::DeserializeOwned, { fn map(&self) -> &[T] { - match &self.map { - SliceMut::Ref(r) => r, - SliceMut::Owned(v) => v.as_slice(), - } + self.map.as_slice() } fn map_mut(&mut self) -> &mut [T] { - match &mut self.map { - SliceMut::Ref(r) => r, - SliceMut::Owned(v) => v.as_mut_slice(), - } + self.map.as_mut_slice() } fn initial(&self) -> T { @@ -129,16 +125,29 @@ where } } +impl<'de, T> Deserialize<'de> for StdMapObserver +where + T: Default + Copy+ 'static + serde::Serialize + serde::de::DeserializeOwned, +{ + fn deserialize(de: D) -> Result + where + D: serde::Deserializer<'de>, + { + let mut erased = erased_serde::Deserializer::erase(de); + erased_serde::deserialize(&mut erased).map_err(serde::de::Error::custom) + } +} + impl StdMapObserver where - T: Integer + Copy + 'static + serde::Serialize + serde::Deserialize<'static>, +T: Default + Copy+ 'static + serde::Serialize + serde::de::DeserializeOwned, { /// Creates a new MapObserver pub fn new(name: &'static str, map: &'static mut [T]) -> Self { observer_serde::RegistryBuilder::register::(); - let initial = if map.len() > 0 { map[0] } else { T::zero() }; + let initial = if map.len() > 0 { map[0] } else { T::default() }; Self { - map: SliceMut::Ref(map), + map: ArrayMut::Cptr((map.as_mut_ptr(), map.len())), initial: initial, name: name, } @@ -146,10 +155,11 @@ where /// Creates a new MapObserver from a raw pointer pub fn new_from_ptr(name: &'static str, map_ptr: *mut T, len: usize) -> Self { + observer_serde::RegistryBuilder::register::(); unsafe { - let initial = if len > 0 { *map_ptr } else { T::zero() }; + let initial = if len > 0 { *map_ptr } else { T::default() }; StdMapObserver { - map: SliceMut::Ref(from_raw_parts_mut(map_ptr, len)), + map: ArrayMut::Cptr((map_ptr, len)), initial: initial, name: name, } diff --git a/afl/src/serde_anymap.rs b/afl/src/serde_anymap.rs index 6960d36741..48b586387f 100644 --- a/afl/src/serde_anymap.rs +++ b/afl/src/serde_anymap.rs @@ -509,3 +509,92 @@ where Deserialize::deserialize(deserializer).map(SliceMut::Owned) } } + +pub enum Array { + Cptr((*const T, usize)), + Owned(Vec), +} + +impl serde::Serialize for Array { + fn serialize(&self, se: S) -> Result + where + S: serde::Serializer, + { + self.as_slice().serialize(se) + } +} + +impl<'de, T: Sized + serde::Serialize> Deserialize<'de> for Array +where + Vec: Deserialize<'de>, +{ + fn deserialize(de: D) -> Result + where + D: serde::Deserializer<'de>, + { + Deserialize::deserialize(de).map(Array::Owned) + } +} + +impl Array { + pub fn as_slice(&self) -> &[T] { + match self { + Array::Cptr(p) => { + unsafe { core::slice::from_raw_parts(p.0, p.1) } + }, + Array::Owned(v) => { + v.as_slice() + } + } + } +} + +pub enum ArrayMut { + Cptr((*mut T, usize)), + Owned(Vec), +} + +impl serde::Serialize for ArrayMut { + fn serialize(&self, se: S) -> Result + where + S: serde::Serializer, + { + self.as_slice().serialize(se) + } +} + +impl<'de, T: Sized + serde::Serialize> Deserialize<'de> for ArrayMut +where + Vec: Deserialize<'de>, +{ + fn deserialize(de: D) -> Result + where + D: serde::Deserializer<'de>, + { + Deserialize::deserialize(de).map(ArrayMut::Owned) + } +} + +impl ArrayMut { + pub fn as_slice(&self) -> &[T] { + match self { + ArrayMut::Cptr(p) => { + unsafe { core::slice::from_raw_parts(p.0, p.1) } + }, + ArrayMut::Owned(v) => { + v.as_slice() + } + } + } + + pub fn as_mut_slice(&mut self) -> &mut [T] { + match self { + ArrayMut::Cptr(p) => { + unsafe { core::slice::from_raw_parts_mut(p.0, p.1) } + }, + ArrayMut::Owned(v) => { + v.as_mut_slice() + } + } + } +} \ No newline at end of file