Skip to content

Commit

Permalink
Allow configuring timeout for CommandExecutor
Browse files Browse the repository at this point in the history
  • Loading branch information
arpankapoor committed May 13, 2023
1 parent b9a5405 commit dbac132
Showing 1 changed file with 29 additions and 3 deletions.
32 changes: 29 additions & 3 deletions libafl/src/executors/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ pub struct StdCommandConfigurator {
debug_child: bool,
has_stdout_observer: bool,
has_stderr_observer: bool,
timeout: Duration,
/// true: input gets delivered via stdink
input_location: InputLocation,
/// The Command to execute
Expand Down Expand Up @@ -153,6 +154,10 @@ impl CommandConfigurator for StdCommandConfigurator {
}
}
}

fn exec_timeout(&self) -> Duration {
self.timeout
}
}

/// A `CommandExecutor` is a wrapper around [`std::process::Command`] to execute a target as a child process.
Expand Down Expand Up @@ -219,6 +224,7 @@ where
pub fn from_cmd_with_file<P>(
cmd: &Command,
debug_child: bool,
timeout: Duration,
observers: OT,
path: P,
) -> Result<Self, Error>
Expand Down Expand Up @@ -251,6 +257,7 @@ where
debug_child,
has_stdout_observer,
has_stderr_observer,
timeout,
},
phantom: PhantomData,
})
Expand All @@ -265,6 +272,7 @@ where
args: IT,
observers: OT,
debug_child: bool,
timeout: Duration,
) -> Result<Self, Error>
where
IT: IntoIterator<Item = O>,
Expand All @@ -273,6 +281,7 @@ where
let mut atat_at = None;
let mut builder = CommandExecutorBuilder::new();
builder.debug_child(debug_child);
builder.timeout(timeout);
let afl_delim = OsStr::new("@@");

for (pos, arg) in args.into_iter().enumerate() {
Expand Down Expand Up @@ -325,7 +334,7 @@ where
let mut child = self.configurer.spawn_child(input)?;

let res = match child
.wait_timeout(Duration::from_secs(5))
.wait_timeout(self.configurer.exec_timeout())
.expect("waiting on child failed")
.map(|status| status.signal())
{
Expand Down Expand Up @@ -405,6 +414,7 @@ pub struct CommandExecutorBuilder {
input_location: InputLocation,
cwd: Option<PathBuf>,
envs: Vec<(OsString, OsString)>,
timeout: Duration,
}

impl Default for CommandExecutorBuilder {
Expand All @@ -423,6 +433,7 @@ impl CommandExecutorBuilder {
input_location: InputLocation::StdIn,
cwd: None,
envs: vec![],
timeout: Duration::from_secs(5),
debug_child: false,
}
}
Expand Down Expand Up @@ -541,6 +552,12 @@ impl CommandExecutorBuilder {
self
}

/// Sets the execution timeout duration.
pub fn timeout(&mut self, timeout: Duration) -> &mut CommandExecutorBuilder {
self.timeout = timeout;
self
}

/// Builds the `CommandExecutor`
pub fn build<OT, S>(
&self,
Expand Down Expand Up @@ -591,6 +608,7 @@ impl CommandExecutorBuilder {
has_stdout_observer: observers.observes_stdout(),
has_stderr_observer: observers.observes_stderr(),
input_location: self.input_location.clone(),
timeout: self.timeout,
command,
};
Ok(configurator.into_executor::<OT, S>(observers))
Expand All @@ -601,7 +619,7 @@ impl CommandExecutorBuilder {
/// # Example
#[cfg_attr(all(feature = "std", unix), doc = " ```")]
#[cfg_attr(not(all(feature = "std", unix)), doc = " ```ignore")]
/// use std::{io::Write, process::{Stdio, Command, Child}};
/// use std::{io::Write, process::{Stdio, Command, Child}, time::Duration};
/// use libafl::{Error, bolts::AsSlice, inputs::{HasTargetBytes, Input, UsesInput}, executors::{Executor, command::CommandConfigurator}, state::UsesState};
/// #[derive(Debug)]
/// struct MyExecutor;
Expand All @@ -622,6 +640,10 @@ impl CommandExecutorBuilder {
/// stdin.write_all(input.target_bytes().as_slice())?;
/// Ok(child)
/// }
///
/// fn exec_timeout(&self) -> Duration {
/// Duration::from_secs(5)
/// }
/// }
///
/// fn make_executor<EM, Z>() -> impl Executor<EM, Z>
Expand All @@ -642,6 +664,9 @@ pub trait CommandConfigurator: Sized + Debug {
where
I: Input + HasTargetBytes;

/// Provides timeout duration for execution of the child process.
fn exec_timeout(&self) -> Duration;

/// Create an `Executor` from this `CommandConfigurator`.
fn into_executor<OT, S>(self, observers: OT) -> CommandExecutor<OT, S, Self>
where
Expand Down Expand Up @@ -698,14 +723,15 @@ mod tests {
#[cfg(unix)]
#[cfg_attr(miri, ignore)]
fn test_parse_afl_cmdline() {
use core::time::Duration;
use alloc::string::ToString;

let mut mgr = SimpleEventManager::new(SimpleMonitor::new(|status| {
log::info!("{status}");
}));

let mut executor =
CommandExecutor::parse_afl_cmdline(["file".to_string(), "@@".to_string()], (), true)
CommandExecutor::parse_afl_cmdline(["file".to_string(), "@@".to_string()], (), true, Duration::from_secs(5))
.unwrap();
executor
.run_target(
Expand Down

0 comments on commit dbac132

Please sign in to comment.