From 9a1173d4a656094d6494582a2531b182615bfbe0 Mon Sep 17 00:00:00 2001 From: "Dongjia \"toka\" Zhang" Date: Tue, 21 Nov 2023 23:54:19 +0100 Subject: [PATCH] scalability monitor 2nd (#1685) * tekito * monitor * fix * all * ci * ci --- .../libfuzzer_libpng_centralized/Cargo.toml | 2 +- libafl/Cargo.toml | 2 +- libafl/src/events/centralized.rs | 63 ++++++++++--------- libafl/src/events/launcher.rs | 2 +- libafl/src/events/mod.rs | 20 ++++++ libafl/src/stages/concolic.rs | 2 +- libafl/src/state/mod.rs | 21 +++++-- 7 files changed, 72 insertions(+), 40 deletions(-) diff --git a/fuzzers/libfuzzer_libpng_centralized/Cargo.toml b/fuzzers/libfuzzer_libpng_centralized/Cargo.toml index 2209c4585d..be829ddc5d 100644 --- a/fuzzers/libfuzzer_libpng_centralized/Cargo.toml +++ b/fuzzers/libfuzzer_libpng_centralized/Cargo.toml @@ -19,7 +19,7 @@ cc = { version = "1.0", features = ["parallel"] } which = "4.4" [dependencies] -libafl = { path = "../../libafl/", features = ["std", "derive", "rand_trait", "fork", "prelude", "gzip", "regex"] } +libafl = { path = "../../libafl/", features = ["std", "derive", "rand_trait", "fork", "prelude", "gzip", "regex", "scalability_introspection"] } libafl_bolts = { path = "../../libafl_bolts/" } libafl_targets = { path = "../../libafl_targets/", features = ["sancov_pcguard_hitcounts", "libfuzzer"] } # TODO Include it only when building cc diff --git a/libafl/Cargo.toml b/libafl/Cargo.toml index 6572692380..af91597ac5 100644 --- a/libafl/Cargo.toml +++ b/libafl/Cargo.toml @@ -30,7 +30,7 @@ std = ["serde_json", "serde_json/std", "nix", "serde/std", "bincode", "wait-time introspection = [] ## Collects stats about scalability -scalability_introspecition = [] +scalability_introspection = [] ## Will build the `pyo3` bindings python = ["pyo3", "concat-idents", "libafl_bolts/python"] diff --git a/libafl/src/events/centralized.rs b/libafl/src/events/centralized.rs index c0ecf669b3..2381aa6960 100644 --- a/libafl/src/events/centralized.rs +++ b/libafl/src/events/centralized.rs @@ -20,6 +20,8 @@ use serde::{Deserialize, Serialize}; use super::{CustomBufEventResult, HasCustomBufHandlers, ProgressReporter}; #[cfg(feature = "llmp_compression")] use crate::events::llmp::COMPRESS_THRESHOLD; +#[cfg(feature = "scalability_introspection")] +use crate::state::HasScalabilityMonitor; use crate::{ events::{ llmp::EventStatsCollector, BrokerEventResult, Event, EventConfig, EventFirer, EventManager, @@ -652,34 +654,36 @@ where } => { log::info!("Received new Testcase from {client_id:?} ({client_config:?}, forward {forward_id:?})"); - #[cfg(feature = "scalability_introspection")] - println!( - "{} {}", - state.scalability_monitor().testcase_with_observers, - state.scalability_monitor().testcase_without_observers - ); - let res = if client_config.match_with(&self.configuration()) - && observers_buf.is_some() - { - let observers: E::Observers = - postcard::from_bytes(observers_buf.as_ref().unwrap())?; - #[cfg(feature = "scalability_introspection")] - { - state.scalability_monitor_mut().testcase_with_observers += 1; - } - fuzzer.process_execution(state, self, input, &observers, &exit_kind, true)? - } else { - #[cfg(feature = "scalability_introspection")] - { - state.scalability_monitor_mut().testcase_without_observers += 1; - } - let res = fuzzer.evaluate_input_with_observers::( - state, - executor, - self, - input.clone(), - false, - )?; + let res = + if client_config.match_with(&self.configuration()) && observers_buf.is_some() { + let observers: E::Observers = + postcard::from_bytes(observers_buf.as_ref().unwrap())?; + #[cfg(feature = "scalability_introspection")] + { + state.scalability_monitor_mut().testcase_with_observers += 1; + } + fuzzer.process_execution( + state, + self, + input.clone(), + &observers, + &exit_kind, + false, + )? + } else { + #[cfg(feature = "scalability_introspection")] + { + state.scalability_monitor_mut().testcase_without_observers += 1; + } + fuzzer.evaluate_input_with_observers::( + state, + executor, + self, + input.clone(), + false, + )? + }; + if let Some(item) = res.1 { if res.1.is_some() { self.inner.fire( state, @@ -695,9 +699,6 @@ where }, )?; } - res - }; - if let Some(item) = res.1 { log::info!("Added received Testcase as item #{item}"); } Ok(()) diff --git a/libafl/src/events/launcher.rs b/libafl/src/events/launcher.rs index a91d3408c2..4434325478 100644 --- a/libafl/src/events/launcher.rs +++ b/libafl/src/events/launcher.rs @@ -579,7 +579,7 @@ where mgr, self.shmem_provider.clone(), self.centralized_broker_port, - id == 0, + index == 1, )?; return (self.run_client.take().unwrap())(state, c_mgr, *bind_to); diff --git a/libafl/src/events/mod.rs b/libafl/src/events/mod.rs index e1979757dc..e6dab1eaea 100644 --- a/libafl/src/events/mod.rs +++ b/libafl/src/events/mod.rs @@ -15,6 +15,8 @@ pub mod llmp; #[cfg(feature = "tcp_manager")] #[allow(clippy::ignored_unit_patterns)] pub mod tcp; +#[cfg(feature = "scalability_introspection")] +use alloc::string::ToString; use alloc::{boxed::Box, string::String, vec::Vec}; #[cfg(all(unix, feature = "std"))] use core::ffi::c_void; @@ -48,6 +50,8 @@ use crate::{ state::{HasExecutions, HasLastReportTime, HasMetadata, State}, Error, }; +#[cfg(feature = "scalability_introspection")] +use crate::{monitors::UserStats::Number, state::HasScalabilityMonitor}; /// Check if ctrl-c is sent with this struct #[cfg(all(unix, feature = "std"))] @@ -525,6 +529,22 @@ where )?; } + // If we are measuring scalability stuff.. + #[cfg(feature = "scalability_introspection")] + { + let imported_with_observer = state.scalability_monitor().testcase_with_observers; + let imported_without_observer = state.scalability_monitor().testcase_without_observers; + + self.fire( + state, + Event::UpdateUserStats { + name: "total imported".to_string(), + value: Number((imported_with_observer + imported_without_observer) as u64), + phantom: PhantomData, + }, + )?; + } + *state.last_report_time_mut() = Some(cur); Ok(()) diff --git a/libafl/src/stages/concolic.rs b/libafl/src/stages/concolic.rs index bd3e6e23da..e6dba49c5c 100644 --- a/libafl/src/stages/concolic.rs +++ b/libafl/src/stages/concolic.rs @@ -8,7 +8,7 @@ use alloc::{borrow::ToOwned, string::ToString, vec::Vec}; use core::marker::PhantomData; use super::{Stage, TracingStage}; -#[cfg(feature = "introspection")] +#[cfg(all(feature = "introspection", feature = "concolic_mutation"))] use crate::state::HasClientPerfMonitor; #[cfg(feature = "concolic_mutation")] use crate::state::State; diff --git a/libafl/src/state/mod.rs b/libafl/src/state/mod.rs index ecfb130655..3beeb54c5c 100644 --- a/libafl/src/state/mod.rs +++ b/libafl/src/state/mod.rs @@ -123,20 +123,20 @@ impl MaybeHasClientPerfMonitor for T {} impl MaybeHasClientPerfMonitor for T where T: HasClientPerfMonitor {} /// Intermediate trait for `HasScalabilityMonitor` -#[cfg(feature = "scalability_monitor")] +#[cfg(feature = "scalability_introspection")] pub trait MaybeHasScalabilityMonitor: HasScalabilityMonitor {} /// Intermediate trait for `HasScalabilityMonitor` -#[cfg(not(feature = "scalability_monitor"))] +#[cfg(not(feature = "scalability_introspection"))] pub trait MaybeHasScalabilityMonitor {} -#[cfg(not(feature = "scalability_monitor"))] +#[cfg(not(feature = "scalability_introspection"))] impl MaybeHasScalabilityMonitor for T {} -#[cfg(feature = "scalability_monitor")] +#[cfg(feature = "scalability_introspection")] impl MaybeHasScalabilityMonitor for T where T: HasScalabilityMonitor {} /// Trait for offering a [`ScalabilityMonitor`] -#[cfg(feature = "scalability_monitor")] +#[cfg(feature = "scalability_introspection")] pub trait HasScalabilityMonitor { /// Ref to [`ScalabilityMonitor`] fn scalability_monitor(&self) -> &ScalabilityMonitor; @@ -1011,6 +1011,17 @@ impl HasClientPerfMonitor for NopState { } } +#[cfg(feature = "scalability_introspection")] +impl HasScalabilityMonitor for NopState { + fn scalability_monitor(&self) -> &ScalabilityMonitor { + unimplemented!(); + } + + fn scalability_monitor_mut(&mut self) -> &mut ScalabilityMonitor { + unimplemented!(); + } +} + #[cfg(feature = "python")] #[allow(missing_docs)] /// `State` Python bindings