Skip to content

Commit ee70c78

Browse files
momvartriesentoaster
authored andcommitted
Make exit status interpretable by CommandConfigurator (AFLplusplus#2723)
* Make exit status interpretable by CommandConfigurator * Fix import issues * Fix default implementation for non-unix environment * Make docs only available on unix if the entry is only for unix * Revert "Fix default implementation for non-unix environment" This reverts commit 5457f6f. * Fix the invalid link in the example
1 parent a6ba5a0 commit ee70c78

File tree

3 files changed

+30
-23
lines changed

3 files changed

+30
-23
lines changed

libafl/src/executors/command.rs

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ use typed_builder::TypedBuilder;
3838

3939
use super::HasTimeout;
4040
#[cfg(all(feature = "std", unix))]
41-
use crate::executors::{Executor, ExitKind};
41+
use crate::executors::Executor;
42+
#[cfg(all(feature = "std", any(unix, doc)))]
43+
use crate::executors::ExitKind;
4244
use crate::{
4345
corpus::Corpus,
4446
executors::{hooks::ExecutorHooksTuple, HasObservers},
@@ -337,38 +339,28 @@ where
337339
OT: Debug + ObserversTuple<I, S>,
338340
{
339341
fn execute_input_with_command(&mut self, state: &mut S, input: &I) -> Result<ExitKind, Error> {
340-
use std::os::unix::prelude::ExitStatusExt;
341-
342342
use wait_timeout::ChildExt;
343343

344344
*state.executions_mut() += 1;
345345
self.observers.pre_exec_child_all(state, input)?;
346346

347347
let mut child = self.configurer.spawn_child(input)?;
348348

349-
let res = match child
349+
let exit_kind = child
350350
.wait_timeout(self.configurer.exec_timeout())
351351
.expect("waiting on child failed")
352-
.map(|status| status.signal())
353-
{
354-
// for reference: https://www.man7.org/linux/man-pages/man7/signal.7.html
355-
Some(Some(9)) => Ok(ExitKind::Oom),
356-
Some(Some(_)) => Ok(ExitKind::Crash),
357-
Some(None) => Ok(ExitKind::Ok),
358-
None => {
352+
.map(|status| self.configurer.exit_kind_from_status(&status))
353+
.unwrap_or_else(|| {
359354
// if this fails, there is not much we can do. let's hope it failed because the process finished
360355
// in the meantime.
361356
drop(child.kill());
362357
// finally, try to wait to properly clean up system resources.
363358
drop(child.wait());
364-
Ok(ExitKind::Timeout)
365-
}
366-
};
359+
ExitKind::Timeout
360+
});
367361

368-
if let Ok(exit_kind) = res {
369-
self.observers
370-
.post_exec_child_all(state, input, &exit_kind)?;
371-
}
362+
self.observers
363+
.post_exec_child_all(state, input, &exit_kind)?;
372364

373365
if let Some(h) = &mut self.configurer.stdout_observer() {
374366
let mut stdout = Vec::new();
@@ -392,7 +384,7 @@ where
392384
let obs = observers.index_mut(h);
393385
obs.observe_stderr(&stderr);
394386
}
395-
res
387+
Ok(exit_kind)
396388
}
397389
}
398390

@@ -809,7 +801,7 @@ impl CommandExecutorBuilder {
809801
/// MyExecutor.into_executor(())
810802
/// }
811803
/// ```
812-
#[cfg(all(feature = "std", any(unix, doc)))]
804+
#[cfg(all(feature = "std", unix))]
813805
pub trait CommandConfigurator<I, C = Child>: Sized {
814806
/// Get the stdout
815807
fn stdout_observer(&self) -> Option<Handle<StdOutObserver>> {
@@ -828,6 +820,18 @@ pub trait CommandConfigurator<I, C = Child>: Sized {
828820
/// Set the timeout duration for execution of the child process.
829821
fn exec_timeout_mut(&mut self) -> &mut Duration;
830822

823+
/// Maps the exit status of the child process to an `ExitKind`.
824+
#[inline]
825+
fn exit_kind_from_status(&self, status: &std::process::ExitStatus) -> ExitKind {
826+
use crate::std::os::unix::process::ExitStatusExt;
827+
match status.signal() {
828+
// for reference: https://www.man7.org/linux/man-pages/man7/signal.7.html
829+
Some(9) => ExitKind::Oom,
830+
Some(_) => ExitKind::Crash,
831+
None => ExitKind::Ok,
832+
}
833+
}
834+
831835
/// Create an `Executor` from this `CommandConfigurator`.
832836
fn into_executor<OT, S>(self, observers: OT) -> CommandExecutor<OT, S, Self, (), C>
833837
where

libafl/src/executors/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use alloc::vec::Vec;
55
use core::{fmt::Debug, time::Duration};
66

77
pub use combined::CombinedExecutor;
8-
#[cfg(all(feature = "std", any(unix, doc)))]
8+
#[cfg(all(feature = "std", unix))]
99
pub use command::CommandExecutor;
1010
pub use differential::DiffExecutor;
1111
#[cfg(all(feature = "std", feature = "fork", unix))]
@@ -23,7 +23,7 @@ pub use with_observers::WithObservers;
2323
use crate::{state::UsesState, Error};
2424

2525
pub mod combined;
26-
#[cfg(all(feature = "std", any(unix, doc)))]
26+
#[cfg(all(feature = "std", unix))]
2727
pub mod command;
2828
pub mod differential;
2929
#[cfg(all(feature = "std", feature = "fork", unix))]

libafl/src/observers/stdio.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
//!
33
//! The [`StdOutObserver`] and [`StdErrObserver`] observers look at the stdout of a program
44
//! The executor must explicitly support these observers.
5-
//! For example, they are supported on the [`crate::executors::CommandExecutor`].
5+
#![cfg_attr(
6+
all(feature = "std", unix),
7+
doc = r"For example, they are supported on the [`crate::executors::CommandExecutor`]."
8+
)]
69

710
use alloc::borrow::Cow;
811
use std::vec::Vec;

0 commit comments

Comments
 (0)