diff --git a/libafl/src/executors/command.rs b/libafl/src/executors/command.rs index 22978264a5..dc67540d39 100644 --- a/libafl/src/executors/command.rs +++ b/libafl/src/executors/command.rs @@ -164,7 +164,7 @@ where } Ok(cmd.spawn()?) } - InputLocation::StdIn => { + InputLocation::StdIn { input_file: _ } => { let mut handle = self.command.stdin(Stdio::piped()).spawn()?; let mut stdin = handle.stdin.take().unwrap(); match stdin.write_all(input.target_bytes().as_slice()) { @@ -262,7 +262,7 @@ where self.args[*argnum] = cstring_input; } } - InputLocation::StdIn => { + InputLocation::StdIn { input_file: _ } => { let (pipe_read, pipe_write) = pipe().unwrap(); write(pipe_write, &input.target_bytes()).unwrap(); dup2(pipe_read.as_raw_fd(), STDIN_FILENO).unwrap(); @@ -590,7 +590,14 @@ impl CommandExecutorBuilder { let mut command = Command::new(program); match &self.target_inner.input_location { - InputLocation::StdIn => { + InputLocation::StdIn { + input_file: out_file, + } => { + if out_file.is_some() { + return Err(Error::illegal_argument( + "Setting filename for CommandExecutor is not supported!", + )); + } command.stdin(Stdio::piped()); } InputLocation::File { .. } | InputLocation::Arg { .. } => { diff --git a/libafl/src/executors/forkserver.rs b/libafl/src/executors/forkserver.rs index 743da6fc55..6c3640477b 100644 --- a/libafl/src/executors/forkserver.rs +++ b/libafl/src/executors/forkserver.rs @@ -1031,7 +1031,12 @@ where OT: ObserversTuple, { let input_file = match &self.target_inner.input_location { - InputLocation::StdIn => InputFile::create(OsString::from(get_unique_std_input_file()))?, + InputLocation::StdIn { + input_file: out_file, + } => match out_file { + Some(out_file) => out_file.clone(), + None => InputFile::create(OsString::from(get_unique_std_input_file()))?, + }, InputLocation::Arg { argnum: _ } => { return Err(Error::illegal_argument( "forkserver doesn't support argument mutation", diff --git a/libafl_bolts/src/target_args.rs b/libafl_bolts/src/target_args.rs index 0837e66951..0a4080ca39 100644 --- a/libafl_bolts/src/target_args.rs +++ b/libafl_bolts/src/target_args.rs @@ -11,7 +11,7 @@ use crate::fs::{InputFile, get_unique_std_input_file}; /// How to deliver input to an external program /// `StdIn`: The target reads from stdin /// `File`: The target reads from the specified [`InputFile`] -#[derive(Debug, Clone, PartialEq, Eq, Default)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum InputLocation { /// Mutate a commandline argument to deliver an input Arg { @@ -19,8 +19,10 @@ pub enum InputLocation { argnum: usize, }, /// Deliver input via `StdIn` - #[default] - StdIn, + StdIn { + /// The alternative input file + input_file: Option, + }, /// Deliver the input via the specified [`InputFile`] /// You can use specify [`InputFile::create(INPUTFILE_STD)`] to use a default filename. File { @@ -29,6 +31,12 @@ pub enum InputLocation { }, } +impl Default for InputLocation { + fn default() -> Self { + Self::StdIn { input_file: None } + } +} + /// The shared inner structs of trait [`StdTargetArgs`] #[derive(Debug, Clone, Default)] pub struct StdTargetArgsInner { @@ -82,7 +90,10 @@ pub trait StdTargetArgs: Sized { /// If use stdin #[must_use] fn use_stdin(&self) -> bool { - matches!(self.inner().input_location, InputLocation::StdIn) + matches!( + &self.inner().input_location, + InputLocation::StdIn { input_file: _ } + ) } /// Set input @@ -114,7 +125,9 @@ pub trait StdTargetArgs: Sized { assert!( match &moved.inner().input_location { InputLocation::File { out_file } => out_file.path.as_path() == path.as_ref(), - InputLocation::StdIn => true, + InputLocation::StdIn { input_file } => input_file + .as_ref() + .is_none_or(|of| of.path.as_path() == path.as_ref()), InputLocation::Arg { argnum: _ } => false, }, "Already specified an input file under a different name. This is not supported"