From 04c8e96923b2843d795b8a57d9cb05f4fd1d14f5 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Wed, 23 Feb 2022 16:06:22 +0100 Subject: [PATCH] afl_exec_sec feature, disabled by default (#555) --- libafl/Cargo.toml | 1 + libafl/src/monitors/mod.rs | 39 +++++++++++++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/libafl/Cargo.toml b/libafl/Cargo.toml index e5a68c06a6..da4529cbad 100644 --- a/libafl/Cargo.toml +++ b/libafl/Cargo.toml @@ -24,6 +24,7 @@ tui_monitor = ["tui", "crossterm"] # enable TuiMonitor with crossterm cli = ["clap"] # expose bolts::cli qemu_cli = ["cli"] frida_cli = ["cli"] +afl_exec_sec = [] # calculate exec/sec like AFL # features hiding dependencies licensed under GPL gpl = [] diff --git a/libafl/src/monitors/mod.rs b/libafl/src/monitors/mod.rs index ab84cde6fb..79f4b21274 100644 --- a/libafl/src/monitors/mod.rs +++ b/libafl/src/monitors/mod.rs @@ -18,6 +18,7 @@ use serde::{Deserialize, Serialize}; use crate::bolts::{current_time, format_duration_hms}; +#[cfg(feature = "afl_exec_sec")] const CLIENT_STATS_TIME_WINDOW_SECS: u64 = 5; // 5 seconds /// User-defined stat types @@ -62,11 +63,13 @@ pub struct ClientStats { /// The size of the objectives corpus for this client pub objective_size: u64, /// The last reported executions for this client + #[cfg(feature = "afl_exec_sec")] pub last_window_executions: u64, + /// The last executions per sec + #[cfg(feature = "afl_exec_sec")] + pub last_execs_per_sec: f64, /// The last time we got this information pub last_window_time: Duration, - /// The last executions per sec - pub last_execs_per_sec: f32, /// User-defined monitor pub user_monitor: HashMap, /// Client performance statistics @@ -76,6 +79,7 @@ pub struct ClientStats { impl ClientStats { /// We got a new information about executions for this client, insert them. + #[cfg(feature = "afl_exec_sec")] pub fn update_executions(&mut self, executions: u64, cur_time: Duration) { let diff = cur_time .checked_sub(self.last_window_time) @@ -88,6 +92,12 @@ impl ClientStats { self.executions = executions; } + /// We got a new information about executions for this client, insert them. + #[cfg(not(feature = "afl_exec_sec"))] + pub fn update_executions(&mut self, executions: u64, _cur_time: Duration) { + self.executions = executions; + } + /// We got a new information about corpus size for this client, insert them. pub fn update_corpus_size(&mut self, corpus_size: u64) { self.corpus_size = corpus_size; @@ -100,6 +110,7 @@ impl ClientStats { /// Get the calculated executions per second for this client #[allow(clippy::cast_sign_loss, clippy::cast_precision_loss)] + #[cfg(feature = "afl_exec_sec")] pub fn execs_per_sec(&mut self, cur_time: Duration) -> u64 { if self.executions == 0 { return 0; @@ -107,12 +118,12 @@ impl ClientStats { let elapsed = cur_time .checked_sub(self.last_window_time) - .map_or(0, |d| d.as_secs()); - if elapsed == 0 { + .map_or(0.0, |d| d.as_secs_f64()); + if elapsed as u64 == 0 { return self.last_execs_per_sec as u64; } - let cur_avg = ((self.executions - self.last_window_executions) as f32) / (elapsed as f32); + let cur_avg = ((self.executions - self.last_window_executions) as f64) / elapsed; if self.last_window_executions == 0 { self.last_execs_per_sec = cur_avg; return self.last_execs_per_sec as u64; @@ -128,6 +139,24 @@ impl ClientStats { self.last_execs_per_sec as u64 } + /// Get the calculated executions per second for this client + #[allow(clippy::cast_sign_loss, clippy::cast_precision_loss)] + #[cfg(not(feature = "afl_exec_sec"))] + pub fn execs_per_sec(&mut self, cur_time: Duration) -> u64 { + if self.executions == 0 { + return 0; + } + + let elapsed = cur_time + .checked_sub(self.last_window_time) + .map_or(0.0, |d| d.as_secs_f64()); + if elapsed as u64 == 0 { + return 0; + } + + ((self.executions as f64) / elapsed) as u64 + } + /// Update the user-defined stat with name and value pub fn update_user_stats(&mut self, name: String, value: UserStats) { self.user_monitor.insert(name, value);