From 712c5daeb97e9a407e7fbe58d44b90eeff63aed3 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 12 Jul 2021 13:16:40 +0200 Subject: [PATCH] Reload corpus size after restart (addresses #210) (#220) * reload corpus size after restart (addresses #210) * no_std --- fuzzers/fuzzbench/src/lib.rs | 2 +- libafl/src/events/simple.rs | 62 +++++++++++++++++++++++------------- libafl/src/lib.rs | 9 +++++- 3 files changed, 49 insertions(+), 24 deletions(-) diff --git a/fuzzers/fuzzbench/src/lib.rs b/fuzzers/fuzzbench/src/lib.rs index 04275644e3..adbe850330 100644 --- a/fuzzers/fuzzbench/src/lib.rs +++ b/fuzzers/fuzzbench/src/lib.rs @@ -34,7 +34,7 @@ use libafl::{ token_mutations::I2SRandReplace, tokens_mutations, Tokens, }, - observers::{HitcountsMapObserver, StdMapObserver, TimeObserver}, + observers::{StdMapObserver, TimeObserver}, stages::{StdMutationalStage, TracingStage}, state::{HasCorpus, HasMetadata, StdState}, stats::SimpleStats, diff --git a/libafl/src/events/simple.rs b/libafl/src/events/simple.rs index 72da996d1e..7fa5799e91 100644 --- a/libafl/src/events/simple.rs +++ b/libafl/src/events/simple.rs @@ -8,16 +8,9 @@ use core::{ }; #[cfg(feature = "std")] use serde::{de::DeserializeOwned, Serialize}; - -#[cfg(all(feature = "std", windows))] -use crate::bolts::os::startable_self; -#[cfg(all(feature = "std", unix))] -use crate::bolts::os::{fork, ForkResult}; #[cfg(feature = "std")] -use crate::bolts::{ - llmp::{LlmpReceiver, LlmpSender}, - shmem::ShMemProvider, -}; +use std::convert::TryInto; + use crate::{ bolts::llmp, events::{ @@ -29,6 +22,20 @@ use crate::{ Error, }; +#[cfg(all(feature = "std", windows))] +use crate::bolts::os::startable_self; +#[cfg(all(feature = "std", unix))] +use crate::bolts::os::{fork, ForkResult}; +#[cfg(feature = "std")] +use crate::{ + bolts::{ + llmp::{LlmpReceiver, LlmpSender}, + shmem::ShMemProvider, + }, + corpus::Corpus, + state::{HasCorpus, HasSolutions}, +}; + /// The llmp connection from the actual fuzzer to the process supervising it const _ENV_FUZZER_SENDER: &str = "_AFL_ENV_FUZZER_SENDER"; const _ENV_FUZZER_RECEIVER: &str = "_AFL_ENV_FUZZER_RECEIVER"; @@ -216,8 +223,9 @@ where /// `restarter` will start a new process each time the child crashes or times out. #[cfg(feature = "std")] #[allow(clippy::default_trait_access)] -pub struct SimpleRestartingEventManager +pub struct SimpleRestartingEventManager<'a, C, I, S, SP, ST> where + C: Corpus, I: Input, S: Serialize, SP: ShMemProvider, @@ -228,12 +236,13 @@ where /// [`LlmpSender`] for restarts sender: LlmpSender, /// Phantom data - _phantom: PhantomData<(I, S)>, + _phantom: PhantomData<&'a (C, I, S)>, } #[cfg(feature = "std")] -impl EventFirer for SimpleRestartingEventManager +impl<'a, C, I, S, SP, ST> EventFirer for SimpleRestartingEventManager<'a, C, I, S, SP, ST> where + C: Corpus, I: Input, S: Serialize, SP: ShMemProvider, @@ -245,8 +254,9 @@ where } #[cfg(feature = "std")] -impl EventRestarter for SimpleRestartingEventManager +impl<'a, C, I, S, SP, ST> EventRestarter for SimpleRestartingEventManager<'a, C, I, S, SP, ST> where + C: Corpus, I: Input, S: Serialize, SP: ShMemProvider, @@ -264,8 +274,10 @@ where } #[cfg(feature = "std")] -impl EventProcessor for SimpleRestartingEventManager +impl<'a, C, E, I, S, SP, ST, Z> EventProcessor + for SimpleRestartingEventManager<'a, C, I, S, SP, ST> where + C: Corpus, I: Input, S: Serialize, SP: ShMemProvider, @@ -277,8 +289,10 @@ where } #[cfg(feature = "std")] -impl EventManager for SimpleRestartingEventManager +impl<'a, C, E, I, S, SP, ST, Z> EventManager + for SimpleRestartingEventManager<'a, C, I, S, SP, ST> where + C: Corpus, I: Input, S: Serialize, SP: ShMemProvider, @@ -287,8 +301,9 @@ where } #[cfg(feature = "std")] -impl HasEventManagerId for SimpleRestartingEventManager +impl<'a, C, I, S, SP, ST> HasEventManagerId for SimpleRestartingEventManager<'a, C, I, S, SP, ST> where + C: Corpus, I: Input, S: Serialize, SP: ShMemProvider, @@ -301,10 +316,11 @@ where #[cfg(feature = "std")] #[allow(clippy::type_complexity, clippy::too_many_lines)] -impl SimpleRestartingEventManager +impl<'a, C, I, S, SP, ST> SimpleRestartingEventManager<'a, C, I, S, SP, ST> where + C: Corpus, I: Input, - S: DeserializeOwned + Serialize, + S: DeserializeOwned + Serialize + HasCorpus + HasSolutions, SP: ShMemProvider, ST: Stats, //TODO CE: CustomEvent, { @@ -321,10 +337,7 @@ where /// This [`EventManager`] is simple and single threaded, /// but can still used shared maps to recover from crashes and timeouts. #[allow(clippy::similar_names)] - pub fn launch( - stats: ST, - shmem_provider: &mut SP, - ) -> Result<(Option, SimpleRestartingEventManager), Error> { + pub fn launch(mut stats: ST, shmem_provider: &mut SP) -> Result<(Option, Self), Error> { // We start ourself as child process to actually fuzz let (mut sender, mut receiver) = if std::env::var(_ENV_FUZZER_SENDER).is_err() { // First, create a channel from the fuzzer (sender) to us (receiver) to report its state for restarts. @@ -408,6 +421,11 @@ where sender.reset(); } + // load the corpus size into stats to still display the correct numbers after restart. + let client_stats = stats.client_stats_mut_for(0); + client_stats.update_corpus_size(state.corpus().count().try_into()?); + client_stats.update_objective_size(state.solutions().count().try_into()?); + ( Some(state), SimpleRestartingEventManager::new_launched(stats, sender), diff --git a/libafl/src/lib.rs b/libafl/src/lib.rs index c5405b1069..f865bdea03 100644 --- a/libafl/src/lib.rs +++ b/libafl/src/lib.rs @@ -43,7 +43,7 @@ use alloc::string::String; use core::fmt; #[cfg(feature = "std")] -use std::{env::VarError, io, num::ParseIntError, string::FromUtf8Error}; +use std::{env::VarError, io, num::ParseIntError, num::TryFromIntError, string::FromUtf8Error}; #[cfg(all(unix, feature = "std"))] use nix; @@ -159,6 +159,13 @@ impl From for Error { } } +#[cfg(feature = "std")] +impl From for Error { + fn from(err: TryFromIntError) -> Self { + Self::IllegalState(format!("Expected conversion failed: {:?}", err)) + } +} + // TODO: no_std test #[cfg(feature = "std")] #[cfg(test)]