Make CommandExecutor Generic on the specific Input (#2129)
This commit is contained in:
parent
2e81dc6c59
commit
7fe0c576db
@ -15,7 +15,7 @@ use libafl::{
|
|||||||
feedbacks::{CrashFeedback, MaxMapFeedback, NewHashFeedback},
|
feedbacks::{CrashFeedback, MaxMapFeedback, NewHashFeedback},
|
||||||
fuzzer::{Fuzzer, StdFuzzer},
|
fuzzer::{Fuzzer, StdFuzzer},
|
||||||
generators::RandPrintablesGenerator,
|
generators::RandPrintablesGenerator,
|
||||||
inputs::{HasTargetBytes, Input},
|
inputs::{BytesInput, HasTargetBytes},
|
||||||
monitors::SimpleMonitor,
|
monitors::SimpleMonitor,
|
||||||
mutators::scheduled::{havoc_mutations, StdScheduledMutator},
|
mutators::scheduled::{havoc_mutations, StdScheduledMutator},
|
||||||
observers::{get_asan_runtime_flags, AsanBacktraceObserver, StdMapObserver},
|
observers::{get_asan_runtime_flags, AsanBacktraceObserver, StdMapObserver},
|
||||||
@ -85,8 +85,8 @@ pub fn main() {
|
|||||||
shmem_id: ShMemId,
|
shmem_id: ShMemId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommandConfigurator for MyExecutor {
|
impl CommandConfigurator<BytesInput> for MyExecutor {
|
||||||
fn spawn_child<I: Input + HasTargetBytes>(&mut self, input: &I) -> Result<Child, Error> {
|
fn spawn_child(&mut self, input: &BytesInput) -> Result<Child, Error> {
|
||||||
let mut command = Command::new("./test_command");
|
let mut command = Command::new("./test_command");
|
||||||
|
|
||||||
let command = command
|
let command = command
|
||||||
|
@ -43,7 +43,7 @@ use libafl_bolts::{
|
|||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMem, ShMemProvider, StdShMemProvider},
|
shmem::{ShMem, ShMemProvider, StdShMemProvider},
|
||||||
tuples::{tuple_list, Referenceable},
|
tuples::{tuple_list, Referenceable},
|
||||||
AsSliceMut, AsSlice
|
AsSlice, AsSliceMut,
|
||||||
};
|
};
|
||||||
use libafl_targets::{
|
use libafl_targets::{
|
||||||
libfuzzer_initialize, libfuzzer_test_one_input, std_edges_map_observer, CmpLogObserver,
|
libfuzzer_initialize, libfuzzer_test_one_input, std_edges_map_observer, CmpLogObserver,
|
||||||
@ -237,8 +237,8 @@ fn fuzz(
|
|||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct MyCommandConfigurator;
|
pub struct MyCommandConfigurator;
|
||||||
|
|
||||||
impl CommandConfigurator for MyCommandConfigurator {
|
impl CommandConfigurator<BytesInput> for MyCommandConfigurator {
|
||||||
fn spawn_child<I: Input + HasTargetBytes>(&mut self, input: &I) -> Result<Child, Error> {
|
fn spawn_child(&mut self, input: &BytesInput) -> Result<Child, Error> {
|
||||||
input.to_file("cur_input")?;
|
input.to_file("cur_input")?;
|
||||||
|
|
||||||
Ok(Command::new("./target_symcc.out")
|
Ok(Command::new("./target_symcc.out")
|
||||||
|
@ -87,11 +87,11 @@ pub struct StdCommandConfigurator {
|
|||||||
command: Command,
|
command: Command,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommandConfigurator for StdCommandConfigurator {
|
impl<I> CommandConfigurator<I> for StdCommandConfigurator
|
||||||
fn spawn_child<I>(&mut self, input: &I) -> Result<Child, Error>
|
where
|
||||||
where
|
I: HasTargetBytes,
|
||||||
I: Input + HasTargetBytes,
|
{
|
||||||
{
|
fn spawn_child(&mut self, input: &I) -> Result<Child, Error> {
|
||||||
match &mut self.input_location {
|
match &mut self.input_location {
|
||||||
InputLocation::Arg { argnum } => {
|
InputLocation::Arg { argnum } => {
|
||||||
let args = self.command.get_args();
|
let args = self.command.get_args();
|
||||||
@ -217,6 +217,7 @@ impl<OT, S> CommandExecutor<OT, S, StdCommandConfigurator>
|
|||||||
where
|
where
|
||||||
OT: MatchName + ObserversTuple<S>,
|
OT: MatchName + ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
|
S::Input: HasTargetBytes,
|
||||||
{
|
{
|
||||||
/// Creates a new `CommandExecutor`.
|
/// Creates a new `CommandExecutor`.
|
||||||
/// Instead of parsing the Command for `@@`, it will
|
/// 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
|
where
|
||||||
EM: UsesState<State = S>,
|
EM: UsesState<State = S>,
|
||||||
S: State + HasExecutions,
|
S: State + HasExecutions,
|
||||||
S::Input: HasTargetBytes,
|
T: CommandConfigurator<S::Input>,
|
||||||
T: CommandConfigurator,
|
|
||||||
OT: Debug + MatchName + ObserversTuple<S>,
|
OT: Debug + MatchName + ObserversTuple<S>,
|
||||||
Z: UsesState<State = S>,
|
Z: UsesState<State = S>,
|
||||||
{
|
{
|
||||||
@ -567,6 +567,7 @@ impl CommandExecutorBuilder {
|
|||||||
where
|
where
|
||||||
OT: MatchName + ObserversTuple<S>,
|
OT: MatchName + ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
|
S::Input: Input + HasTargetBytes,
|
||||||
{
|
{
|
||||||
let Some(program) = &self.program else {
|
let Some(program) = &self.program else {
|
||||||
return Err(Error::illegal_argument(
|
return Err(Error::illegal_argument(
|
||||||
@ -612,7 +613,12 @@ impl CommandExecutorBuilder {
|
|||||||
timeout: self.timeout,
|
timeout: self.timeout,
|
||||||
command,
|
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(all(feature = "std", unix), doc = " ```")]
|
||||||
#[cfg_attr(not(all(feature = "std", unix)), doc = " ```ignore")]
|
#[cfg_attr(not(all(feature = "std", unix)), doc = " ```ignore")]
|
||||||
/// use std::{io::Write, process::{Stdio, Command, Child}, time::Duration};
|
/// 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;
|
/// use libafl_bolts::AsSlice;
|
||||||
/// #[derive(Debug)]
|
/// #[derive(Debug)]
|
||||||
/// struct MyExecutor;
|
/// struct MyExecutor;
|
||||||
///
|
///
|
||||||
/// impl CommandConfigurator for MyExecutor {
|
/// impl CommandConfigurator<BytesInput> for MyExecutor {
|
||||||
/// fn spawn_child<I: HasTargetBytes>(
|
/// fn spawn_child(
|
||||||
/// &mut self,
|
/// &mut self,
|
||||||
/// input: &I,
|
/// input: &BytesInput,
|
||||||
/// ) -> Result<Child, Error> {
|
/// ) -> Result<Child, Error> {
|
||||||
/// let mut command = Command::new("../if");
|
/// let mut command = Command::new("../if");
|
||||||
/// command
|
/// command
|
||||||
@ -652,19 +658,16 @@ impl CommandExecutorBuilder {
|
|||||||
/// where
|
/// where
|
||||||
/// EM: UsesState,
|
/// EM: UsesState,
|
||||||
/// Z: UsesState<State = EM::State>,
|
/// Z: UsesState<State = EM::State>,
|
||||||
/// EM::State: UsesInput + HasExecutions,
|
/// EM::State: UsesInput<Input = BytesInput> + HasExecutions,
|
||||||
/// EM::Input: HasTargetBytes
|
|
||||||
/// {
|
/// {
|
||||||
/// MyExecutor.into_executor(())
|
/// MyExecutor.into_executor(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
#[cfg(all(feature = "std", any(unix, doc)))]
|
#[cfg(all(feature = "std", any(unix, doc)))]
|
||||||
pub trait CommandConfigurator: Sized {
|
pub trait CommandConfigurator<I>: Sized {
|
||||||
/// Spawns a new process with the given configuration.
|
/// Spawns a new process with the given configuration.
|
||||||
fn spawn_child<I>(&mut self, input: &I) -> Result<Child, Error>
|
fn spawn_child(&mut self, input: &I) -> Result<Child, Error>;
|
||||||
where
|
|
||||||
I: Input + HasTargetBytes;
|
|
||||||
|
|
||||||
/// Provides timeout duration for execution of the child process.
|
/// Provides timeout duration for execution of the child process.
|
||||||
fn exec_timeout(&self) -> Duration;
|
fn exec_timeout(&self) -> Duration;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user