From 91ab778f9e8f3fb1ce64a5754c8ae1a61fdecccc Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Fri, 27 Nov 2020 18:30:44 +0100 Subject: [PATCH] testcase clone() --- afl/src/corpus/testcase.rs | 42 +++++++++++++++++++++++++++++++++----- afl/src/events/mod.rs | 13 ++++-------- afl/src/feedbacks/mod.rs | 8 +++++--- 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/afl/src/corpus/testcase.rs b/afl/src/corpus/testcase.rs index d351d50cd1..44d752b9f4 100644 --- a/afl/src/corpus/testcase.rs +++ b/afl/src/corpus/testcase.rs @@ -22,10 +22,33 @@ use crate::AflError; pub trait TestcaseMetadata: Any { /// The name of this metadata - used to find it in the list of avaliable metadatas fn name(&self) -> &'static str; + + fn clone(&self) -> Box; +} + +/// Just a wrapper of Boxed TestcaseMetadata trait object for Clone +#[derive(Serialize, Deserialize)] +pub struct TestcaseMetadataContainer { + meta: Box, +} +impl Clone for TestcaseMetadataContainer { + fn clone(&self) -> Self { + TestcaseMetadataContainer { + meta: self.meta.clone(), + } + } +} +impl TestcaseMetadataContainer { + pub fn meta(&self) -> &Box { + &self.meta + } + pub fn meta_mut(&mut self) -> &mut Box { + &mut self.meta + } } /// An entry in the Testcase Corpus -#[derive(Default, Serialize, Deserialize)] +#[derive(Default, Clone, Serialize, Deserialize)] pub struct Testcase where I: Input, @@ -36,8 +59,9 @@ where filename: Option, /// Accumulated fitness from all the feedbacks fitness: u32, + // TODO find a way to use TypeId /// Map of metadatas associated with this testcase - metadatas: HashMap>, + metadatas: HashMap, } impl Into>> for Testcase @@ -100,12 +124,20 @@ where } /// Get all the metadatas into an HashMap (mutable) - pub fn metadatas(&mut self) -> &mut HashMap> { + pub fn metadatas(&mut self) -> &mut HashMap { &mut self.metadatas } /// Add a metadata - pub fn add_metadata(&mut self, meta: Box) { - self.metadatas.insert(meta.name().to_string(), meta); + pub fn add_metadata(&mut self, meta: TM) + where + TM: TestcaseMetadata + 'static, + { + self.metadatas.insert( + meta.name().to_string(), + TestcaseMetadataContainer { + meta: Box::new(meta), + }, + ); } /// Create a new Testcase instace given an input diff --git a/afl/src/events/mod.rs b/afl/src/events/mod.rs index 9b1f1e12af..bea579f838 100644 --- a/afl/src/events/mod.rs +++ b/afl/src/events/mod.rs @@ -214,22 +214,17 @@ where } fn handle_in_client( - &mut self, + &self, /*client: &dyn EventManager,*/ _state: &mut S, corpus: &mut C, ) -> Result<(), AflError> { - match std::mem::replace( - self, - Event::None { - phantom: PhantomData, - }, - ) { + match self { Event::NewTestcase { sender_id: _, testcase, phantom: _, } => { - corpus.add(testcase); + corpus.add(testcase.clone()); Ok(()) } _ => Err(AflError::Unknown( @@ -322,7 +317,7 @@ where } handled .iter() - .zip(self.events.iter_mut()) + .zip(self.events.iter()) .map(|(x, event)| match x { BrokerEventResult::Forward => event.handle_in_client(state, corpus), // Ignore broker-only events diff --git a/afl/src/feedbacks/mod.rs b/afl/src/feedbacks/mod.rs index 271088cf9c..e484fa69ba 100644 --- a/afl/src/feedbacks/mod.rs +++ b/afl/src/feedbacks/mod.rs @@ -176,6 +176,10 @@ impl TestcaseMetadata for MapNoveltiesMetadata { fn name(&self) -> &'static str { "MapNoveltiesMetadata" } + + fn clone(&self) -> Box { + Box::new(MapNoveltiesMetadata::new(self.novelties.clone())) + } } impl MapNoveltiesMetadata { pub fn novelties(&self) -> &[usize] { @@ -235,9 +239,7 @@ where } fn append_metadata(&mut self, testcase: &mut Testcase) -> Result<(), AflError> { - let meta = Box::new(MapNoveltiesMetadata::new(core::mem::take( - &mut self.novelties, - ))); + let meta = MapNoveltiesMetadata::new(core::mem::take(&mut self.novelties)); testcase.add_metadata(meta); Ok(()) }