From a4f753b0f09406d4bf8bc0baf1251ec2ae3a5e70 Mon Sep 17 00:00:00 2001 From: "Dongjia \"toka\" Zhang" Date: Tue, 30 Jan 2024 17:34:39 +0100 Subject: [PATCH] Merge TimeoutForkserverExecutor into ForkserverExecutor (#1819) * delete timeout forkserver * clippies * name --------- Co-authored-by: Dominik Maier --- fuzzers/forkserver_libafl_cc/src/main.rs | 20 +- fuzzers/forkserver_simple/src/main.rs | 20 +- fuzzers/fuzzbench_forkserver/src/main.rs | 17 +- .../fuzzbench_forkserver_cmplog/src/main.rs | 17 +- libafl/src/executors/forkserver.rs | 342 +++--------------- libafl/src/executors/mod.rs | 2 +- libafl_sugar/src/forkserver.rs | 12 +- 7 files changed, 86 insertions(+), 344 deletions(-) diff --git a/fuzzers/forkserver_libafl_cc/src/main.rs b/fuzzers/forkserver_libafl_cc/src/main.rs index b70dbe3878..e90f048272 100644 --- a/fuzzers/forkserver_libafl_cc/src/main.rs +++ b/fuzzers/forkserver_libafl_cc/src/main.rs @@ -5,10 +5,7 @@ use clap::{self, Parser}; use libafl::{ corpus::{Corpus, InMemoryCorpus, OnDiskCorpus}, events::SimpleEventManager, - executors::{ - forkserver::{ForkserverExecutor, TimeoutForkserverExecutor}, - HasObservers, - }, + executors::{forkserver::ForkserverExecutor, HasObservers}, feedback_and_fast, feedback_or, feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback}, fuzzer::{Fuzzer, StdFuzzer}, @@ -165,31 +162,26 @@ pub fn main() { let args = opt.arguments; let mut tokens = Tokens::new(); - let mut forkserver = ForkserverExecutor::builder() + let mut executor = ForkserverExecutor::builder() .program(opt.executable) .debug_child(debug_child) .shmem_provider(&mut shmem_provider) .autotokens(&mut tokens) .parse_afl_cmdline(args) .coverage_map_size(MAP_SIZE) + .timeout(Duration::from_millis(opt.timeout)) + .kill_signal(opt.signal) .build(tuple_list!(time_observer, edges_observer)) .unwrap(); - if let Some(dynamic_map_size) = forkserver.coverage_map_size() { - forkserver + if let Some(dynamic_map_size) = executor.coverage_map_size() { + executor .observers_mut() .match_name_mut::>>("shared_mem") .unwrap() .truncate(dynamic_map_size); } - let mut executor = TimeoutForkserverExecutor::with_signal( - forkserver, - Duration::from_millis(opt.timeout), - opt.signal, - ) - .expect("Failed to create the executor."); - // In case the corpus is empty (on first run), reset if state.must_load_initial_inputs() { state diff --git a/fuzzers/forkserver_simple/src/main.rs b/fuzzers/forkserver_simple/src/main.rs index 74f0f7be64..a0c752eee1 100644 --- a/fuzzers/forkserver_simple/src/main.rs +++ b/fuzzers/forkserver_simple/src/main.rs @@ -5,10 +5,7 @@ use clap::{self, Parser}; use libafl::{ corpus::{Corpus, InMemoryCorpus, OnDiskCorpus}, events::SimpleEventManager, - executors::{ - forkserver::{ForkserverExecutor, TimeoutForkserverExecutor}, - HasObservers, - }, + executors::{forkserver::ForkserverExecutor, HasObservers}, feedback_and_fast, feedback_or, feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback}, fuzzer::{Fuzzer, StdFuzzer}, @@ -165,31 +162,26 @@ pub fn main() { let args = opt.arguments; let mut tokens = Tokens::new(); - let mut forkserver = ForkserverExecutor::builder() + let mut executor = ForkserverExecutor::builder() .program(opt.executable) .debug_child(debug_child) .shmem_provider(&mut shmem_provider) .autotokens(&mut tokens) .parse_afl_cmdline(args) .coverage_map_size(MAP_SIZE) + .timeout(Duration::from_millis(opt.timeout)) + .kill_signal(opt.signal) .build(tuple_list!(time_observer, edges_observer)) .unwrap(); - if let Some(dynamic_map_size) = forkserver.coverage_map_size() { - forkserver + if let Some(dynamic_map_size) = executor.coverage_map_size() { + executor .observers_mut() .match_name_mut::>>("shared_mem") .unwrap() .truncate(dynamic_map_size); } - let mut executor = TimeoutForkserverExecutor::with_signal( - forkserver, - Duration::from_millis(opt.timeout), - opt.signal, - ) - .expect("Failed to create the executor."); - // In case the corpus is empty (on first run), reset if state.must_load_initial_inputs() { state diff --git a/fuzzers/fuzzbench_forkserver/src/main.rs b/fuzzers/fuzzbench_forkserver/src/main.rs index ca4bcec46e..0e4157cc09 100644 --- a/fuzzers/fuzzbench_forkserver/src/main.rs +++ b/fuzzers/fuzzbench_forkserver/src/main.rs @@ -11,7 +11,7 @@ use clap::{Arg, ArgAction, Command}; use libafl::{ corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus}, events::SimpleEventManager, - executors::forkserver::{ForkserverExecutor, TimeoutForkserverExecutor}, + executors::forkserver::ForkserverExecutor, feedback_or, feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback}, fuzzer::{Fuzzer, StdFuzzer}, @@ -310,20 +310,19 @@ fn fuzz( let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); let mut tokens = Tokens::new(); - let forkserver = ForkserverExecutor::builder() + let mut executor = ForkserverExecutor::builder() .program(executable) .debug_child(debug_child) .shmem_provider(&mut shmem_provider) .autotokens(&mut tokens) .parse_afl_cmdline(arguments) .coverage_map_size(MAP_SIZE) + .timeout(timeout) + .kill_signal(signal) .is_persistent(true) .build_dynamic_map(edges_observer, tuple_list!(time_observer)) .unwrap(); - let mut executor = TimeoutForkserverExecutor::with_signal(forkserver, timeout, signal) - .expect("Failed to create the executor."); - // Read tokens if let Some(tokenfile) = tokenfile { tokens.add_from_file(tokenfile)?; @@ -349,19 +348,17 @@ fn fuzz( let cmplog_observer = StdCmpValuesObserver::new("cmplog", cmpmap, true); - let cmplog_forkserver = ForkserverExecutor::builder() + let cmplog_executor = ForkserverExecutor::builder() .program(exec) .debug_child(debug_child) .shmem_provider(&mut shmem_provider) .parse_afl_cmdline(arguments) .is_persistent(true) + .timeout(timeout * 10) + .kill_signal(signal) .build(tuple_list!(cmplog_observer)) .unwrap(); - let cmplog_executor = - TimeoutForkserverExecutor::with_signal(cmplog_forkserver, timeout * 10, signal) - .expect("Failed to create the executor."); - let tracing = TracingStage::new(cmplog_executor); // Setup a randomic Input2State stage diff --git a/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs b/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs index ec5dde303f..9a3734615d 100644 --- a/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs +++ b/fuzzers/fuzzbench_forkserver_cmplog/src/main.rs @@ -11,7 +11,7 @@ use clap::{Arg, ArgAction, Command}; use libafl::{ corpus::{Corpus, HasCurrentCorpusIdx, InMemoryOnDiskCorpus, OnDiskCorpus}, events::SimpleEventManager, - executors::forkserver::{ForkserverExecutor, TimeoutForkserverExecutor}, + executors::forkserver::ForkserverExecutor, feedback_or, feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback}, fuzzer::{Fuzzer, StdFuzzer}, @@ -314,20 +314,19 @@ fn fuzz( let colorization = ColorizationStage::new(&edges_observer); let mut tokens = Tokens::new(); - let forkserver = ForkserverExecutor::builder() + let mut executor = ForkserverExecutor::builder() .program(executable) .debug_child(debug_child) .shmem_provider(&mut shmem_provider) .autotokens(&mut tokens) .parse_afl_cmdline(arguments) .coverage_map_size(MAP_SIZE) + .timeout(timeout) + .kill_signal(signal) .is_persistent(true) .build_dynamic_map(edges_observer, tuple_list!(time_observer)) .unwrap(); - let mut executor = TimeoutForkserverExecutor::with_signal(forkserver, timeout, signal) - .expect("Failed to create the executor."); - // Read tokens if let Some(tokenfile) = tokenfile { tokens.add_from_file(tokenfile)?; @@ -353,19 +352,17 @@ fn fuzz( let cmplog_observer = AFLppCmpLogObserver::new("cmplog", cmpmap, true); - let cmplog_forkserver = ForkserverExecutor::builder() + let cmplog_executor = ForkserverExecutor::builder() .program(exec) .debug_child(debug_child) .shmem_provider(&mut shmem_provider) .parse_afl_cmdline(arguments) .is_persistent(true) + .timeout(timeout * 10) + .kill_signal(signal) .build(tuple_list!(cmplog_observer)) .unwrap(); - let cmplog_executor = - TimeoutForkserverExecutor::with_signal(cmplog_forkserver, timeout * 10, signal) - .expect("Failed to create the executor."); - let tracing = AFLppCmplogTracingStage::with_cmplog_observer_name(cmplog_executor, "cmplog"); // Setup a randomic Input2State stage diff --git a/libafl/src/executors/forkserver.rs b/libafl/src/executors/forkserver.rs index 449de22f48..f960da63c8 100644 --- a/libafl/src/executors/forkserver.rs +++ b/libafl/src/executors/forkserver.rs @@ -4,7 +4,6 @@ use alloc::{borrow::ToOwned, string::ToString, vec::Vec}; use core::{ fmt::{self, Debug, Formatter}, marker::PhantomData, - sync::atomic::{compiler_fence, Ordering}, time::Duration, }; use std::{ @@ -19,14 +18,14 @@ use libafl_bolts::{ fs::{get_unique_std_input_file, InputFile}, os::{dup2, pipes::Pipe}, shmem::{ShMem, ShMemProvider, UnixShMemProvider}, - tuples::{MatchName, Prepend}, + tuples::Prepend, AsMutSlice, AsSlice, Truncate, }; use nix::{ sys::{ select::{pselect, FdSet}, signal::{kill, SigSet, Signal}, - time::{TimeSpec, TimeValLike}, + time::TimeSpec, wait::waitpid, }, unistd::Pid, @@ -466,175 +465,6 @@ impl Forkserver { } } -/// A struct that has a forkserver -pub trait HasForkserver { - /// The [`ShMemProvider`] used for this forkserver's map - type SP: ShMemProvider; - - /// The forkserver - fn forkserver(&self) -> &Forkserver; - - /// The forkserver, mutable - fn forkserver_mut(&mut self) -> &mut Forkserver; - - /// The file the forkserver is reading from - fn input_file(&self) -> &InputFile; - - /// The file the forkserver is reading from, mutable - fn input_file_mut(&mut self) -> &mut InputFile; - - /// The map of the fuzzer - fn shmem(&self) -> &Option<<::SP as ShMemProvider>::ShMem>; - - /// The map of the fuzzer, mutable - fn shmem_mut(&mut self) -> &mut Option<<::SP as ShMemProvider>::ShMem>; - - /// Whether testcases are expected in shared memory - fn uses_shmem_testcase(&self) -> bool; -} - -/// The timeout forkserver executor that wraps around the standard forkserver executor and sets a timeout before each run. -#[derive(Debug)] -pub struct TimeoutForkserverExecutor { - executor: E, - timeout: TimeSpec, - signal: Signal, -} - -impl TimeoutForkserverExecutor { - /// Create a new [`TimeoutForkserverExecutor`] - pub fn new(executor: E, exec_tmout: Duration) -> Result { - let signal = Signal::SIGKILL; - Self::with_signal(executor, exec_tmout, signal) - } - - /// Create a new [`TimeoutForkserverExecutor`] that sends a user-defined signal to the timed-out process - pub fn with_signal(executor: E, exec_tmout: Duration, signal: Signal) -> Result { - let milli_sec = exec_tmout.as_millis() as i64; - let timeout = TimeSpec::milliseconds(milli_sec); - Ok(Self { - executor, - timeout, - signal, - }) - } -} - -impl Executor for TimeoutForkserverExecutor -where - E: Executor + HasForkserver + HasObservers, - E::Input: HasTargetBytes, - E::State: HasExecutions, - EM: UsesState, - Z: UsesState, -{ - #[inline] - fn run_target( - &mut self, - _fuzzer: &mut Z, - state: &mut Self::State, - _mgr: &mut EM, - input: &Self::Input, - ) -> Result { - *state.executions_mut() += 1; - - let mut exit_kind = ExitKind::Ok; - - let last_run_timed_out = self.executor.forkserver().last_run_timed_out_raw(); - - if self.executor.uses_shmem_testcase() { - debug_assert!( - self.executor.shmem_mut().is_some(), - "The uses_shmem_testcase() bool can only exist when a map is set" - ); - // # Safety - // Struct can never be created when uses_shmem_testcase is true and map is none. - let map = unsafe { self.executor.shmem_mut().as_mut().unwrap_unchecked() }; - let target_bytes = input.target_bytes(); - let mut size = target_bytes.as_slice().len(); - let max_size = map.len() - SHMEM_FUZZ_HDR_SIZE; - if size > max_size { - // Truncate like AFL++ does - size = max_size; - } - let size_in_bytes = size.to_ne_bytes(); - // The first four bytes tells the size of the shmem. - map.as_mut_slice()[..SHMEM_FUZZ_HDR_SIZE] - .copy_from_slice(&size_in_bytes[..SHMEM_FUZZ_HDR_SIZE]); - map.as_mut_slice()[SHMEM_FUZZ_HDR_SIZE..(SHMEM_FUZZ_HDR_SIZE + size)] - .copy_from_slice(&target_bytes.as_slice()[..size]); - } else { - self.executor - .input_file_mut() - .write_buf(input.target_bytes().as_slice())?; - } - - let send_len = self - .executor - .forkserver_mut() - .write_ctl(last_run_timed_out)?; - - self.executor.forkserver_mut().set_last_run_timed_out(false); - - if send_len != 4 { - return Err(Error::unknown( - "Unable to request new process from fork server (OOM?)".to_string(), - )); - } - - let (recv_pid_len, pid) = self.executor.forkserver_mut().read_st()?; - if recv_pid_len != 4 { - return Err(Error::unknown( - "Unable to request new process from fork server (OOM?)".to_string(), - )); - } - - if pid <= 0 { - return Err(Error::unknown( - "Fork server is misbehaving (OOM?)".to_string(), - )); - } - - self.executor - .forkserver_mut() - .set_child_pid(Pid::from_raw(pid)); - - if let Some(status) = self - .executor - .forkserver_mut() - .read_st_timed(&self.timeout)? - { - self.executor.forkserver_mut().set_status(status); - if libc::WIFSIGNALED(self.executor.forkserver().status()) { - exit_kind = ExitKind::Crash; - #[cfg(feature = "regex")] - if let Some(asan_observer) = self - .observers_mut() - .match_name_mut::("AsanBacktraceObserver") - { - asan_observer.parse_asan_output_from_asan_log_file(pid)?; - } - } - } else { - self.executor.forkserver_mut().set_last_run_timed_out(true); - - // We need to kill the child in case he has timed out, or we can't get the correct pid in the next call to self.executor.forkserver_mut().read_st()? - let _ = kill(self.executor.forkserver().child_pid(), self.signal); - let (recv_status_len, _) = self.executor.forkserver_mut().read_st()?; - if recv_status_len != 4 { - return Err(Error::unknown("Could not kill timed-out child".to_string())); - } - exit_kind = ExitKind::Timeout; - } - - if !libc::WIFSTOPPED(self.executor.forkserver().status()) { - self.executor.forkserver_mut().reset_child_pid(); - } - - Ok(exit_kind) - } -} - /// This [`Executor`] can run binaries compiled for AFL/AFL++ that make use of a forkserver. /// Shared memory feature is also available, but you have to set things up in your code. /// Please refer to AFL++'s docs. @@ -650,9 +480,8 @@ where observers: OT, map: Option, phantom: PhantomData, - /// Cache that indicates if we have a `ASan` observer registered. - has_asan_observer: Option, map_size: Option, + timeout: TimeSpec, } impl Debug for ForkserverExecutor @@ -732,6 +561,7 @@ pub struct ForkserverExecutorBuilder<'a, SP> { map_size: Option, real_map_size: i32, kill_signal: Option, + timeout: Option, } impl<'a, SP> ForkserverExecutorBuilder<'a, SP> { @@ -764,6 +594,11 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> { )); } + let timeout: TimeSpec = match self.timeout { + Some(t) => t.into(), + None => Duration::from_millis(5000).into(), + }; + Ok(ForkserverExecutor { target, args: self.arguments.clone(), @@ -773,8 +608,8 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> { observers, map, phantom: PhantomData, - has_asan_observer: None, // initialized on first use map_size: self.map_size, + timeout, }) } @@ -815,6 +650,11 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> { )); } + let timeout: TimeSpec = match self.timeout { + Some(t) => t.into(), + None => Duration::from_millis(5000).into(), + }; + Ok(ForkserverExecutor { target, args: self.arguments.clone(), @@ -824,8 +664,8 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> { observers, map, phantom: PhantomData, - has_asan_observer: None, // initialized on first use map_size: self.map_size, + timeout, }) } @@ -976,6 +816,13 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> { self } + #[must_use] + /// set the timeout for the executor + pub fn timeout(mut self, timeout: Duration) -> Self { + self.timeout = Some(timeout); + self + } + #[must_use] /// Parse afl style command line /// @@ -1177,6 +1024,7 @@ impl<'a> ForkserverExecutorBuilder<'a, UnixShMemProvider> { real_map_size: 0, max_input_size: MAX_INPUT_SIZE_DEFAULT, kill_signal: None, + timeout: None, } } @@ -1201,6 +1049,7 @@ impl<'a> ForkserverExecutorBuilder<'a, UnixShMemProvider> { real_map_size: self.real_map_size, max_input_size: MAX_INPUT_SIZE_DEFAULT, kill_signal: None, + timeout: None, } } } @@ -1229,13 +1078,15 @@ where input: &Self::Input, ) -> Result { *state.executions_mut() += 1; + let mut exit_kind = ExitKind::Ok; - // Write to testcase + let last_run_timed_out = self.forkserver.last_run_timed_out_raw(); + if self.uses_shmem_testcase { debug_assert!( self.map.is_some(), - "The uses_shmem_testcase bool can only exist when a map is set" + "The uses_shmem_testcase() bool can only exist when a map is set" ); // # Safety // Struct can never be created when uses_shmem_testcase is true and map is none. @@ -1257,21 +1108,19 @@ where self.input_file.write_buf(input.target_bytes().as_slice())?; } - // Don't tell the forkserver to spawn a new process before clearing the cov map - compiler_fence(Ordering::SeqCst); + let send_len = self.forkserver.write_ctl(last_run_timed_out)?; + + self.forkserver.set_last_run_timed_out(false); - let send_len = self - .forkserver - .write_ctl(self.forkserver().last_run_timed_out_raw())?; if send_len != 4 { - return Err(Error::illegal_state( + return Err(Error::unknown( "Unable to request new process from fork server (OOM?)".to_string(), )); } let (recv_pid_len, pid) = self.forkserver.read_st()?; if recv_pid_len != 4 { - return Err(Error::illegal_state( + return Err(Error::unknown( "Unable to request new process from fork server (OOM?)".to_string(), )); } @@ -1284,41 +1133,34 @@ where self.forkserver.set_child_pid(Pid::from_raw(pid)); - let (recv_status_len, status) = self.forkserver.read_st()?; - if recv_status_len != 4 { - return Err(Error::unknown( - "Unable to communicate with fork server (OOM?)".to_string(), - )); - } - - self.forkserver.set_status(status); - - if libc::WIFSIGNALED(self.forkserver.status()) { - exit_kind = ExitKind::Crash; - #[cfg(feature = "regex")] - if self.has_asan_observer.is_none() { - self.has_asan_observer = Some( - self.observers() - .match_name::("AsanBacktraceObserver") - .is_some(), - ); - } - #[cfg(feature = "regex")] - if self.has_asan_observer.unwrap() { - self.observers_mut() + if let Some(status) = self.forkserver.read_st_timed(&self.timeout)? { + self.forkserver.set_status(status); + if libc::WIFSIGNALED(self.forkserver().status()) { + exit_kind = ExitKind::Crash; + #[cfg(feature = "regex")] + if let Some(asan_observer) = self + .observers_mut() .match_name_mut::("AsanBacktraceObserver") - .unwrap() - .parse_asan_output_from_asan_log_file(pid)?; + { + asan_observer.parse_asan_output_from_asan_log_file(pid)?; + } } + } else { + self.forkserver.set_last_run_timed_out(true); + + // We need to kill the child in case he has timed out, or we can't get the correct pid in the next call to self.executor.forkserver_mut().read_st()? + let _ = kill(self.forkserver().child_pid(), self.forkserver.kill_signal); + let (recv_status_len, _) = self.forkserver.read_st()?; + if recv_status_len != 4 { + return Err(Error::unknown("Could not kill timed-out child".to_string())); + } + exit_kind = ExitKind::Timeout; } - if !libc::WIFSTOPPED(self.forkserver.status) { + if !libc::WIFSTOPPED(self.forkserver().status()) { self.forkserver.reset_child_pid(); } - // Clear the observer map after the execution is finished - compiler_fence(Ordering::SeqCst); - Ok(exit_kind) } } @@ -1357,80 +1199,6 @@ where } } -impl HasForkserver for ForkserverExecutor -where - OT: ObserversTuple, - S: UsesInput, - S::Input: Input + HasTargetBytes, - SP: ShMemProvider, -{ - type SP = SP; - - #[inline] - fn forkserver(&self) -> &Forkserver { - &self.forkserver - } - - #[inline] - fn forkserver_mut(&mut self) -> &mut Forkserver { - &mut self.forkserver - } - - #[inline] - fn input_file(&self) -> &InputFile { - &self.input_file - } - - #[inline] - fn input_file_mut(&mut self) -> &mut InputFile { - &mut self.input_file - } - - #[inline] - fn shmem(&self) -> &Option { - &self.map - } - - #[inline] - fn shmem_mut(&mut self) -> &mut Option { - &mut self.map - } - - #[inline] - fn uses_shmem_testcase(&self) -> bool { - self.uses_shmem_testcase - } -} - -impl UsesState for TimeoutForkserverExecutor -where - E: UsesState, -{ - type State = E::State; -} - -impl UsesObservers for TimeoutForkserverExecutor -where - E: UsesObservers, -{ - type Observers = E::Observers; -} - -impl HasObservers for TimeoutForkserverExecutor -where - E: HasObservers, -{ - #[inline] - fn observers(&self) -> &Self::Observers { - self.executor.observers() - } - - #[inline] - fn observers_mut(&mut self) -> &mut Self::Observers { - self.executor.observers_mut() - } -} - #[cfg(test)] mod tests { use std::ffi::OsString; diff --git a/libafl/src/executors/mod.rs b/libafl/src/executors/mod.rs index 14bb785540..91b4140ab3 100644 --- a/libafl/src/executors/mod.rs +++ b/libafl/src/executors/mod.rs @@ -9,7 +9,7 @@ pub use combined::CombinedExecutor; pub use command::CommandExecutor; pub use differential::DiffExecutor; #[cfg(all(feature = "std", feature = "fork", unix))] -pub use forkserver::{Forkserver, ForkserverExecutor, TimeoutForkserverExecutor}; +pub use forkserver::{Forkserver, ForkserverExecutor}; pub use inprocess::InProcessExecutor; #[cfg(all(feature = "std", feature = "fork", unix))] pub use inprocess_fork::InProcessForkExecutor; diff --git a/libafl_sugar/src/forkserver.rs b/libafl_sugar/src/forkserver.rs index b3634d306a..74c87ce14f 100644 --- a/libafl_sugar/src/forkserver.rs +++ b/libafl_sugar/src/forkserver.rs @@ -5,7 +5,7 @@ use std::{fs, net::SocketAddr, path::PathBuf, time::Duration}; use libafl::{ corpus::{CachedOnDiskCorpus, Corpus, OnDiskCorpus}, events::{launcher::Launcher, EventConfig, EventRestarter, LlmpRestartingEventManager}, - executors::{forkserver::ForkserverExecutorBuilder, TimeoutForkserverExecutor}, + executors::forkserver::ForkserverExecutorBuilder, feedback_or, feedback_or_fast, feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback}, fuzzer::{Fuzzer, StdFuzzer}, @@ -179,6 +179,7 @@ impl<'a> ForkserverBytesCoverageSugar<'a> { .is_persistent(true) .autotokens(&mut tokens) .coverage_map_size(MAP_SIZE) + .timeout(timeout) .debug_child(self.debug_output) .shmem_provider(&mut shmem_provider_client) .build_dynamic_map(edges_observer, tuple_list!(time_observer)) @@ -189,10 +190,12 @@ impl<'a> ForkserverBytesCoverageSugar<'a> { .is_persistent(true) .autotokens(&mut tokens) .coverage_map_size(MAP_SIZE) + .timeout(timeout) .debug_child(self.debug_output) .build_dynamic_map(edges_observer, tuple_list!(time_observer)) }; + let mut executor = forkserver.unwrap(); if let Some(tokens_file) = &self.tokens_file { // if a token file is provided, load it into our set of tokens tokens.add_from_file(tokens_file)?; @@ -203,13 +206,6 @@ impl<'a> ForkserverBytesCoverageSugar<'a> { state.add_metadata(tokens); } - // Create the executor for an in-process function with one observer for edge coverage and one for the execution time - let mut executor = TimeoutForkserverExecutor::new( - forkserver.expect("Failed to create the executor."), - timeout, - ) - .expect("Failed to create the executor."); - // In case the corpus is empty (on first run), reset if state.must_load_initial_inputs() { if self.input_dirs.is_empty() {