From d7825851e906d362a96c522b202dc49503558c87 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Thu, 16 Nov 2023 20:06:27 +0100 Subject: [PATCH] Fix SimpleRestartingMonitor after restart (#1669) * Fix SimpleRestartingMonitor after restart * a * a * a * a * a * a * a * a * a * ci --------- Co-authored-by: toka --- libafl/src/events/simple.rs | 36 ++++++++++-------- libafl/src/monitors/disk.rs | 13 ++++++- libafl/src/monitors/mod.rs | 37 +++++++++++++++---- libafl/src/monitors/multi.rs | 7 +++- libafl/src/monitors/prometheus.rs | 7 +++- libafl/src/monitors/tui/mod.rs | 7 +++- libafl_targets/src/libfuzzer/observers/mod.rs | 3 +- 7 files changed, 82 insertions(+), 28 deletions(-) diff --git a/libafl/src/events/simple.rs b/libafl/src/events/simple.rs index bf98aae22c..137b800e50 100644 --- a/libafl/src/events/simple.rs +++ b/libafl/src/events/simple.rs @@ -9,9 +9,12 @@ use alloc::{ use core::ffi::c_void; #[cfg(all(unix, feature = "std"))] use core::ptr::write_volatile; -#[cfg(feature = "std")] -use core::sync::atomic::{compiler_fence, Ordering}; use core::{fmt::Debug, marker::PhantomData}; +#[cfg(feature = "std")] +use core::{ + sync::atomic::{compiler_fence, Ordering}, + time::Duration, +}; #[cfg(all(feature = "std", any(windows, not(feature = "fork"))))] use libafl_bolts::os::startable_self; @@ -28,12 +31,6 @@ use serde::{de::DeserializeOwned, Serialize}; use super::{CustomBufEventResult, CustomBufHandlerFn, HasCustomBufHandlers, ProgressReporter}; #[cfg(all(unix, feature = "std"))] use crate::events::{shutdown_handler, SHUTDOWN_SIGHANDLER_DATA}; -#[cfg(feature = "std")] -use crate::{ - corpus::Corpus, - monitors::SimplePrintingMonitor, - state::{HasCorpus, HasSolutions}, -}; use crate::{ events::{ BrokerEventResult, Event, EventFirer, EventManager, EventManagerId, EventProcessor, @@ -44,6 +41,11 @@ use crate::{ state::{HasClientPerfMonitor, HasExecutions, HasLastReportTime, HasMetadata, UsesState}, Error, }; +#[cfg(feature = "std")] +use crate::{ + monitors::{ClientStats, SimplePrintingMonitor}, + state::{HasCorpus, HasSolutions}, +}; /// The llmp connection from the actual fuzzer to the process supervising it const _ENV_FUZZER_SENDER: &str = "_AFL_ENV_FUZZER_SENDER"; @@ -343,6 +345,7 @@ where #[cfg(feature = "std")] impl EventRestarter for SimpleRestartingEventManager where + MT: Monitor, S: UsesInput + Serialize, SP: ShMemProvider, { @@ -350,7 +353,11 @@ where fn on_restart(&mut self, state: &mut S) -> Result<(), Error> { // First, reset the page to 0 so the next iteration can read read from the beginning of this page self.staterestorer.reset(); - self.staterestorer.save(state) + self.staterestorer.save(&( + state, + self.simple_event_mgr.monitor.start_time(), + self.simple_event_mgr.monitor.client_stats(), + )) } fn send_exiting(&mut self) -> Result<(), Error> { @@ -539,7 +546,7 @@ where }; // If we're restarting, deserialize the old state. - let (state, mgr) = match staterestorer.restore::()? { + let (state, mgr) = match staterestorer.restore::<(S, Duration, Vec)>()? { None => { log::info!("First run. Let's set it all up"); // Mgr to send and receive msgs from/to all other fuzzer instances @@ -549,15 +556,14 @@ where ) } // Restoring from a previous run, deserialize state and corpus. - Some(state) => { + Some((state, start_time, clients_stats)) => { log::info!("Subsequent run. Loaded previous state."); // We reset the staterestorer, the next staterestorer and receiver (after crash) will reuse the page from the initial message. staterestorer.reset(); - // load the corpus size into monitor to still display the correct numbers after restart. - let client_stats = monitor.client_stats_mut_for(ClientId(0)); - client_stats.update_corpus_size(state.corpus().count().try_into()?); - client_stats.update_objective_size(state.solutions().count().try_into()?); + // reload the state of the monitor to display the correct stats after restarts + monitor.set_start_time(start_time); + *monitor.client_stats_mut() = clients_stats; ( Some(state), diff --git a/libafl/src/monitors/disk.rs b/libafl/src/monitors/disk.rs index c4674b355c..6275d24dc0 100644 --- a/libafl/src/monitors/disk.rs +++ b/libafl/src/monitors/disk.rs @@ -39,10 +39,15 @@ where } /// Time this fuzzing run stated - fn start_time(&mut self) -> Duration { + fn start_time(&self) -> Duration { self.base.start_time() } + /// Set creation time + fn set_start_time(&mut self, time: Duration) { + self.base.set_start_time(time); + } + fn display(&mut self, event_msg: String, sender_id: ClientId) { let cur_time = current_time(); @@ -184,10 +189,14 @@ where self.base.client_stats() } - fn start_time(&mut self) -> Duration { + fn start_time(&self) -> Duration { self.base.start_time() } + fn set_start_time(&mut self, time: Duration) { + self.base.set_start_time(time); + } + fn display(&mut self, event_msg: String, sender_id: ClientId) { if (self.log_record)(&mut self.base) { let file = OpenOptions::new() diff --git a/libafl/src/monitors/mod.rs b/libafl/src/monitors/mod.rs index 366ceb1f02..eba5a8e291 100644 --- a/libafl/src/monitors/mod.rs +++ b/libafl/src/monitors/mod.rs @@ -82,7 +82,7 @@ fn prettify_float(value: f64) -> String { } /// A simple struct to keep track of client monitor -#[derive(Debug, Clone, Default, Serialize)] +#[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct ClientStats { // monitor (maybe we need a separated struct?) /// The corpus size for this client @@ -235,7 +235,10 @@ pub trait Monitor { fn client_stats(&self) -> &[ClientStats]; /// Creation time - fn start_time(&mut self) -> Duration; + fn start_time(&self) -> Duration; + + /// Set creation time + fn set_start_time(&mut self, time: Duration); /// Show the monitor to the user fn display(&mut self, event_msg: String, sender_id: ClientId); @@ -311,10 +314,15 @@ impl Monitor for NopMonitor { } /// Time this fuzzing run stated - fn start_time(&mut self) -> Duration { + fn start_time(&self) -> Duration { self.start_time } + /// Time this fuzzing run stated + fn set_start_time(&mut self, time: Duration) { + self.start_time = time; + } + fn display(&mut self, _event_msg: String, _sender_id: ClientId) {} } @@ -375,10 +383,15 @@ impl Monitor for SimplePrintingMonitor { } /// Time this fuzzing run stated - fn start_time(&mut self) -> Duration { + fn start_time(&self) -> Duration { self.start_time } + /// Time this fuzzing run stated + fn set_start_time(&mut self, time: Duration) { + self.start_time = time; + } + fn display(&mut self, event_msg: String, sender_id: ClientId) { let mut userstats = self.client_stats()[sender_id.0 as usize] .user_monitor @@ -452,10 +465,15 @@ where } /// Time this fuzzing run stated - fn start_time(&mut self) -> Duration { + fn start_time(&self) -> Duration { self.start_time } + /// Set creation time + fn set_start_time(&mut self, time: Duration) { + self.start_time = time; + } + fn display(&mut self, event_msg: String, sender_id: ClientId) { let mut fmt = format!( "[{} #{}] run time: {}, clients: {}, corpus: {}, objectives: {}, executions: {}, exec/sec: {}", @@ -1113,8 +1131,13 @@ pub mod pybind { } /// Time this fuzzing run stated - fn start_time(&mut self) -> Duration { - unwrap_me_mut!(self.wrapper, m, { m.start_time() }) + fn start_time(&self) -> Duration { + unwrap_me!(self.wrapper, m, { m.start_time() }) + } + + /// set start time + fn set_start_time(&mut self, time: Duration) { + unwrap_me_mut!(self.wrapper, m, { m.set_start_time(time) }); } fn display(&mut self, event_msg: String, sender_id: ClientId) { diff --git a/libafl/src/monitors/multi.rs b/libafl/src/monitors/multi.rs index 7fd6edafcf..a6b4801884 100644 --- a/libafl/src/monitors/multi.rs +++ b/libafl/src/monitors/multi.rs @@ -49,8 +49,13 @@ where &self.client_stats } + /// Set creation time + fn set_start_time(&mut self, time: Duration) { + self.start_time = time; + } + /// Time this fuzzing run stated - fn start_time(&mut self) -> Duration { + fn start_time(&self) -> Duration { self.start_time } diff --git a/libafl/src/monitors/prometheus.rs b/libafl/src/monitors/prometheus.rs index 2ffc2e7411..dac42955da 100644 --- a/libafl/src/monitors/prometheus.rs +++ b/libafl/src/monitors/prometheus.rs @@ -88,10 +88,15 @@ where } /// Time this fuzzing run stated - fn start_time(&mut self) -> Duration { + fn start_time(&self) -> Duration { self.start_time } + /// Set creation time + fn set_start_time(&mut self, time: Duration) { + self.start_time = time; + } + #[allow(clippy::cast_sign_loss)] fn display(&mut self, event_msg: String, sender_id: ClientId) { // Update the prometheus metrics diff --git a/libafl/src/monitors/tui/mod.rs b/libafl/src/monitors/tui/mod.rs index 689a7530eb..73206b9052 100644 --- a/libafl/src/monitors/tui/mod.rs +++ b/libafl/src/monitors/tui/mod.rs @@ -346,10 +346,15 @@ impl Monitor for TuiMonitor { } /// Time this fuzzing run stated - fn start_time(&mut self) -> Duration { + fn start_time(&self) -> Duration { self.start_time } + /// Set creation time + fn set_start_time(&mut self, time: Duration) { + self.start_time = time; + } + #[allow(clippy::cast_sign_loss)] fn display(&mut self, event_msg: String, sender_id: ClientId) { let cur_time = current_time(); diff --git a/libafl_targets/src/libfuzzer/observers/mod.rs b/libafl_targets/src/libfuzzer/observers/mod.rs index b6f32e6839..c8677bc080 100644 --- a/libafl_targets/src/libfuzzer/observers/mod.rs +++ b/libafl_targets/src/libfuzzer/observers/mod.rs @@ -1,4 +1,5 @@ +/// oom observer #[cfg(feature = "libfuzzer_oom")] -mod oom; +pub mod oom; #[cfg(feature = "libfuzzer_oom")] pub use oom::*;