Make CommandExecutor Generic on the specific Input (#2129)

This commit is contained in:
Valentin Huber 2024-05-02 21:39:06 +02:00 committed by GitHub
parent 2e81dc6c59
commit 7fe0c576db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 24 deletions

View File

@ -15,7 +15,7 @@ use libafl::{
feedbacks::{CrashFeedback, MaxMapFeedback, NewHashFeedback},
fuzzer::{Fuzzer, StdFuzzer},
generators::RandPrintablesGenerator,
inputs::{HasTargetBytes, Input},
inputs::{BytesInput, HasTargetBytes},
monitors::SimpleMonitor,
mutators::scheduled::{havoc_mutations, StdScheduledMutator},
observers::{get_asan_runtime_flags, AsanBacktraceObserver, StdMapObserver},
@ -85,8 +85,8 @@ pub fn main() {
shmem_id: ShMemId,
}
impl CommandConfigurator for MyExecutor {
fn spawn_child<I: Input + HasTargetBytes>(&mut self, input: &I) -> Result<Child, Error> {
impl CommandConfigurator<BytesInput> for MyExecutor {
fn spawn_child(&mut self, input: &BytesInput) -> Result<Child, Error> {
let mut command = Command::new("./test_command");
let command = command

View File

@ -43,7 +43,7 @@ use libafl_bolts::{
rands::StdRand,
shmem::{ShMem, ShMemProvider, StdShMemProvider},
tuples::{tuple_list, Referenceable},
AsSliceMut, AsSlice
AsSlice, AsSliceMut,
};
use libafl_targets::{
libfuzzer_initialize, libfuzzer_test_one_input, std_edges_map_observer, CmpLogObserver,
@ -237,8 +237,8 @@ fn fuzz(
#[derive(Default, Debug)]
pub struct MyCommandConfigurator;
impl CommandConfigurator for MyCommandConfigurator {
fn spawn_child<I: Input + HasTargetBytes>(&mut self, input: &I) -> Result<Child, Error> {
impl CommandConfigurator<BytesInput> for MyCommandConfigurator {
fn spawn_child(&mut self, input: &BytesInput) -> Result<Child, Error> {
input.to_file("cur_input")?;
Ok(Command::new("./target_symcc.out")

View File

@ -87,11 +87,11 @@ pub struct StdCommandConfigurator {
command: Command,
}
impl CommandConfigurator for StdCommandConfigurator {
fn spawn_child<I>(&mut self, input: &I) -> Result<Child, Error>
impl<I> CommandConfigurator<I> for StdCommandConfigurator
where
I: Input + HasTargetBytes,
I: HasTargetBytes,
{
fn spawn_child(&mut self, input: &I) -> Result<Child, Error> {
match &mut self.input_location {
InputLocation::Arg { argnum } => {
let args = self.command.get_args();
@ -217,6 +217,7 @@ impl<OT, S> CommandExecutor<OT, S, StdCommandConfigurator>
where
OT: MatchName + ObserversTuple<S>,
S: UsesInput,
S::Input: HasTargetBytes,
{
/// Creates a new `CommandExecutor`.
/// Instead of parsing the Command for `@@`, it will
@ -314,8 +315,7 @@ impl<EM, OT, S, T, Z> Executor<EM, Z> for CommandExecutor<OT, S, T>
where
EM: UsesState<State = S>,
S: State + HasExecutions,
S::Input: HasTargetBytes,
T: CommandConfigurator,
T: CommandConfigurator<S::Input>,
OT: Debug + MatchName + ObserversTuple<S>,
Z: UsesState<State = S>,
{
@ -567,6 +567,7 @@ impl CommandExecutorBuilder {
where
OT: MatchName + ObserversTuple<S>,
S: UsesInput,
S::Input: Input + HasTargetBytes,
{
let Some(program) = &self.program else {
return Err(Error::illegal_argument(
@ -612,7 +613,12 @@ impl CommandExecutorBuilder {
timeout: self.timeout,
command,
};
Ok(configurator.into_executor::<OT, S>(observers))
Ok(
<StdCommandConfigurator as CommandConfigurator<S::Input>>::into_executor::<OT, S>(
configurator,
observers,
),
)
}
}
@ -621,15 +627,15 @@ impl CommandExecutorBuilder {
#[cfg_attr(all(feature = "std", unix), doc = " ```")]
#[cfg_attr(not(all(feature = "std", unix)), doc = " ```ignore")]
/// use std::{io::Write, process::{Stdio, Command, Child}, time::Duration};
/// use libafl::{Error, inputs::{HasTargetBytes, Input, UsesInput}, executors::{Executor, command::CommandConfigurator}, state::{UsesState, HasExecutions}};
/// use libafl::{Error, inputs::{BytesInput, HasTargetBytes, Input, UsesInput}, executors::{Executor, command::CommandConfigurator}, state::{UsesState, HasExecutions}};
/// use libafl_bolts::AsSlice;
/// #[derive(Debug)]
/// struct MyExecutor;
///
/// impl CommandConfigurator for MyExecutor {
/// fn spawn_child<I: HasTargetBytes>(
/// impl CommandConfigurator<BytesInput> for MyExecutor {
/// fn spawn_child(
/// &mut self,
/// input: &I,
/// input: &BytesInput,
/// ) -> Result<Child, Error> {
/// let mut command = Command::new("../if");
/// command
@ -652,19 +658,16 @@ impl CommandExecutorBuilder {
/// where
/// EM: UsesState,
/// Z: UsesState<State = EM::State>,
/// EM::State: UsesInput + HasExecutions,
/// EM::Input: HasTargetBytes
/// EM::State: UsesInput<Input = BytesInput> + HasExecutions,
/// {
/// MyExecutor.into_executor(())
/// }
/// ```
#[cfg(all(feature = "std", any(unix, doc)))]
pub trait CommandConfigurator: Sized {
pub trait CommandConfigurator<I>: Sized {
/// Spawns a new process with the given configuration.
fn spawn_child<I>(&mut self, input: &I) -> Result<Child, Error>
where
I: Input + HasTargetBytes;
fn spawn_child(&mut self, input: &I) -> Result<Child, Error>;
/// Provides timeout duration for execution of the child process.
fn exec_timeout(&self) -> Duration;