From 992ba8f30dc433d32e9b545a363cd1030a3226fb Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Mon, 4 Mar 2024 11:29:26 +0100 Subject: [PATCH 1/5] impl TransferFeedback --- libafl/src/events/centralized.rs | 8 +++++ libafl/src/events/llmp.rs | 16 ++++++++- libafl/src/events/tcp.rs | 7 ++++ libafl/src/feedbacks/mod.rs | 2 ++ libafl/src/feedbacks/transferred.rs | 56 +++++++++++++++++++++++++++++ libafl/src/observers/mod.rs | 1 + 6 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 libafl/src/feedbacks/transferred.rs diff --git a/libafl/src/events/centralized.rs b/libafl/src/events/centralized.rs index e6034fd881..c628d3f99f 100644 --- a/libafl/src/events/centralized.rs +++ b/libafl/src/events/centralized.rs @@ -28,6 +28,7 @@ use crate::{ EventManagerId, EventProcessor, EventRestarter, HasEventManagerId, LogSeverity, }, executors::{Executor, HasObservers}, + feedbacks::transferred::TransferringMetadata, fuzzer::{EvaluatorObservers, ExecutionProcessor}, inputs::{Input, UsesInput}, observers::ObserversTuple, @@ -663,6 +664,9 @@ where } => { log::info!("Received new Testcase from {client_id:?} ({client_config:?}, forward {forward_id:?})"); + if let Ok(meta) = state.metadata_mut::() { + meta.set_transferring(true); + } let res = if client_config.match_with(&self.configuration()) && observers_buf.is_some() { let observers: E::Observers = @@ -692,6 +696,10 @@ where false, )? }; + if let Ok(meta) = state.metadata_mut::() { + meta.set_transferring(false); + } + if let Some(item) = res.1 { if res.1.is_some() { self.inner.fire( diff --git a/libafl/src/events/llmp.rs b/libafl/src/events/llmp.rs index a8fd02d88f..42dac53e01 100644 --- a/libafl/src/events/llmp.rs +++ b/libafl/src/events/llmp.rs @@ -46,6 +46,7 @@ use crate::{ EventProcessor, EventRestarter, HasCustomBufHandlers, HasEventManagerId, ProgressReporter, }, executors::{Executor, HasObservers}, + feedbacks::transferred::TransferringMetadata, fuzzer::{EvaluatorObservers, ExecutionProcessor}, inputs::{Input, InputConverter, UsesInput}, monitors::Monitor, @@ -590,6 +591,9 @@ where } => { log::info!("Received new Testcase from {client_id:?} ({client_config:?}, forward {forward_id:?})"); + if let Ok(meta) = state.metadata_mut::() { + meta.set_transferring(true); + } let res = if client_config.match_with(&self.configuration) && observers_buf.is_some() { @@ -615,6 +619,9 @@ where state, executor, self, input, false, )? }; + if let Ok(meta) = state.metadata_mut::() { + meta.set_transferring(false); + } if let Some(item) = res.1 { log::info!("Added received Testcase as item #{item}"); } @@ -1451,7 +1458,7 @@ where impl LlmpEventConverter where - S: UsesInput + HasExecutions, + S: UsesInput + HasExecutions + HasMetadata, SP: ShMemProvider + 'static, IC: InputConverter, ICB: InputConverter, @@ -1568,6 +1575,9 @@ where return Ok(()); }; + if let Ok(meta) = state.metadata_mut::() { + meta.set_transferring(true); + } let res = fuzzer.evaluate_input_with_observers::( state, executor, @@ -1575,6 +1585,10 @@ where converter.convert(input)?, false, )?; + if let Ok(meta) = state.metadata_mut::() { + meta.set_transferring(false); + } + if let Some(item) = res.1 { log::info!("Added received Testcase as item #{item}"); } diff --git a/libafl/src/events/tcp.rs b/libafl/src/events/tcp.rs index 45c73ceebf..9d17ea0943 100644 --- a/libafl/src/events/tcp.rs +++ b/libafl/src/events/tcp.rs @@ -44,6 +44,7 @@ use crate::{ EventProcessor, EventRestarter, HasCustomBufHandlers, HasEventManagerId, ProgressReporter, }, executors::{Executor, HasObservers}, + feedbacks::transferred::TransferringMetadata, fuzzer::{EvaluatorObservers, ExecutionProcessor}, inputs::{Input, UsesInput}, monitors::Monitor, @@ -559,6 +560,9 @@ where } => { log::info!("Received new Testcase from {client_id:?} ({client_config:?}, forward {forward_id:?})"); + if let Ok(meta) = state.metadata_mut::() { + meta.set_transferring(true); + } let _res = if client_config.match_with(&self.configuration) && observers_buf.is_some() { @@ -578,6 +582,9 @@ where state, executor, self, input, false, )? }; + if let Ok(meta) = state.metadata_mut::() { + meta.set_transferring(false); + } if let Some(item) = _res.1 { log::info!("Added received Testcase as item #{item}"); } diff --git a/libafl/src/feedbacks/mod.rs b/libafl/src/feedbacks/mod.rs index d7ac970d7e..05f39baa38 100644 --- a/libafl/src/feedbacks/mod.rs +++ b/libafl/src/feedbacks/mod.rs @@ -23,6 +23,8 @@ pub use new_hash_feedback::NewHashFeedbackMetadata; #[cfg(feature = "nautilus")] pub mod nautilus; +pub mod transferred; + use alloc::string::{String, ToString}; use core::{ fmt::{self, Debug, Formatter}, diff --git a/libafl/src/feedbacks/transferred.rs b/libafl/src/feedbacks/transferred.rs new file mode 100644 index 0000000000..99a290714a --- /dev/null +++ b/libafl/src/feedbacks/transferred.rs @@ -0,0 +1,56 @@ +use libafl_bolts::{impl_serdeany, Error, Named}; +use serde::{Deserialize, Serialize}; + +use crate::{ + events::EventFirer, executors::ExitKind, feedbacks::Feedback, observers::ObserversTuple, + state::HasMetadata, +}; + +pub const TRANSFERRED_FEEDBACK_NAME: &str = "transferred_feedback_internal"; + +#[derive(Copy, Clone, Deserialize, Serialize)] +pub struct TransferringMetadata { + transferring: bool, +} + +impl_serdeany!(TransferringMetadata); + +impl TransferringMetadata { + pub fn set_transferring(&mut self, transferring: bool) { + self.transferring = transferring; + } +} + +#[derive(Copy, Clone)] +pub struct TransferredFeedback; + +impl Named for TransferredFeedback { + fn name(&self) -> &str { + TRANSFERRED_FEEDBACK_NAME + } +} + +impl Feedback for TransferredFeedback +where + S: HasMetadata, +{ + fn init_state(&mut self, state: &mut S) -> Result<(), Error> { + state.add_metadata(TransferringMetadata { transferring: true }); + Ok(()) + } + + fn is_interesting( + &mut self, + state: &mut S, + _manager: &mut EM, + _input: &S::Input, + _observers: &OT, + _exit_kind: &ExitKind, + ) -> Result + where + EM: EventFirer, + OT: ObserversTuple, + { + Ok(state.metadata::()?.transferring) + } +} diff --git a/libafl/src/observers/mod.rs b/libafl/src/observers/mod.rs index 69f73d7066..ad7048f4b4 100644 --- a/libafl/src/observers/mod.rs +++ b/libafl/src/observers/mod.rs @@ -19,6 +19,7 @@ pub use stacktrace::*; pub mod concolic; pub mod value; +pub mod transferred; use alloc::{ string::{String, ToString}, From 449d1785da17cdf7984a999f3fe8f1945fdec93e Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Mon, 4 Mar 2024 11:40:24 +0100 Subject: [PATCH 2/5] whoops, fix build --- libafl/src/feedbacks/transferred.rs | 25 ++++++++++++++++++++----- libafl/src/observers/mod.rs | 1 - 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/libafl/src/feedbacks/transferred.rs b/libafl/src/feedbacks/transferred.rs index 99a290714a..d752f563ae 100644 --- a/libafl/src/feedbacks/transferred.rs +++ b/libafl/src/feedbacks/transferred.rs @@ -1,14 +1,26 @@ +//! Feedbacks and associated metadata for detecting whether a given testcase was transferred from +//! another node. + use libafl_bolts::{impl_serdeany, Error, Named}; use serde::{Deserialize, Serialize}; use crate::{ - events::EventFirer, executors::ExitKind, feedbacks::Feedback, observers::ObserversTuple, - state::HasMetadata, + events::EventFirer, + executors::ExitKind, + feedbacks::Feedback, + observers::ObserversTuple, + state::{HasMetadata, State}, }; +/// Constant name of the [`TransferringMetdata`]. pub const TRANSFERRED_FEEDBACK_NAME: &str = "transferred_feedback_internal"; -#[derive(Copy, Clone, Deserialize, Serialize)] +/// Metadata which denotes whether we are currently transferring an input. Implementors of +/// multi-node communication systems (like [`crate::events::LlmpEventManager`]) should wrap any +/// [`crate::EvaluatorObservers::evaluate_input_with_observers`] or +/// [`crate::ExecutionProcessor::process_execution`] calls with setting this metadata to true/false +/// before and after. +#[derive(Copy, Clone, Debug, Deserialize, Serialize)] pub struct TransferringMetadata { transferring: bool, } @@ -16,12 +28,15 @@ pub struct TransferringMetadata { impl_serdeany!(TransferringMetadata); impl TransferringMetadata { + /// Indicate to the metadata that we are currently transferring data. pub fn set_transferring(&mut self, transferring: bool) { self.transferring = transferring; } } -#[derive(Copy, Clone)] +/// Simple feedback which may be used to test whether the testcase was transferred from another node +/// in a multi-node fuzzing arrangement. +#[derive(Copy, Clone, Debug)] pub struct TransferredFeedback; impl Named for TransferredFeedback { @@ -32,7 +47,7 @@ impl Named for TransferredFeedback { impl Feedback for TransferredFeedback where - S: HasMetadata, + S: HasMetadata + State, { fn init_state(&mut self, state: &mut S) -> Result<(), Error> { state.add_metadata(TransferringMetadata { transferring: true }); diff --git a/libafl/src/observers/mod.rs b/libafl/src/observers/mod.rs index ad7048f4b4..69f73d7066 100644 --- a/libafl/src/observers/mod.rs +++ b/libafl/src/observers/mod.rs @@ -19,7 +19,6 @@ pub use stacktrace::*; pub mod concolic; pub mod value; -pub mod transferred; use alloc::{ string::{String, ToString}, From b35d91439464ab5dd0d97a18800cfc4943ce5dc5 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Mon, 4 Mar 2024 11:53:15 +0100 Subject: [PATCH 3/5] fix doc --- libafl/src/feedbacks/transferred.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libafl/src/feedbacks/transferred.rs b/libafl/src/feedbacks/transferred.rs index d752f563ae..86f8cd06e3 100644 --- a/libafl/src/feedbacks/transferred.rs +++ b/libafl/src/feedbacks/transferred.rs @@ -12,7 +12,7 @@ use crate::{ state::{HasMetadata, State}, }; -/// Constant name of the [`TransferringMetdata`]. +/// Constant name of the [`TransferringMetadata`]. pub const TRANSFERRED_FEEDBACK_NAME: &str = "transferred_feedback_internal"; /// Metadata which denotes whether we are currently transferring an input. Implementors of From 59513d73dfc7c4ee412012788ad0dc2dcec04cef Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Mon, 4 Mar 2024 12:28:39 +0100 Subject: [PATCH 4/5] fix build for tcp manager --- libafl/src/events/tcp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libafl/src/events/tcp.rs b/libafl/src/events/tcp.rs index 9d17ea0943..c937c37572 100644 --- a/libafl/src/events/tcp.rs +++ b/libafl/src/events/tcp.rs @@ -458,7 +458,7 @@ where impl TcpEventManager where - S: State + HasExecutions, + S: State + HasExecutions + HasMetadata, { /// Create a manager from a raw TCP client specifying the client id pub fn existing( From b3da7abddc4e5abe9d7cb8b8c90730366e7091b4 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Mon, 4 Mar 2024 13:50:24 +0100 Subject: [PATCH 5/5] fix fr --- libafl/src/events/tcp.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libafl/src/events/tcp.rs b/libafl/src/events/tcp.rs index c937c37572..5e824c9e07 100644 --- a/libafl/src/events/tcp.rs +++ b/libafl/src/events/tcp.rs @@ -688,7 +688,7 @@ where impl EventProcessor for TcpEventManager where - S: State + HasExecutions, + S: State + HasExecutions + HasMetadata, E: HasObservers + Executor, for<'a> E::Observers: Deserialize<'a>, Z: EvaluatorObservers + ExecutionProcessor, @@ -881,7 +881,7 @@ impl EventProcessor for TcpRestartingEventManager where E: HasObservers + Executor, Z>, for<'a> E::Observers: Deserialize<'a>, - S: State + HasExecutions, + S: State + HasExecutions + HasMetadata, SP: ShMemProvider + 'static, Z: EvaluatorObservers + ExecutionProcessor, //CE: CustomEvent, { @@ -985,7 +985,7 @@ pub fn setup_restarting_mgr_tcp( ) -> Result<(Option, TcpRestartingEventManager), Error> where MT: Monitor + Clone, - S: State + HasExecutions, + S: State + HasExecutions + HasMetadata, { TcpRestartingMgr::builder() .shmem_provider(StdShMemProvider::new()?) @@ -1046,7 +1046,7 @@ where impl TcpRestartingMgr where SP: ShMemProvider, - S: State + HasExecutions, + S: State + HasExecutions + HasMetadata, MT: Monitor + Clone, { /// Internal function, returns true when shuttdown is requested by a `SIGINT` signal