From 5abb1b12fe026ec4875c64bf5731371658e78bf7 Mon Sep 17 00:00:00 2001 From: Mohammad Omidvar Date: Mon, 25 Nov 2024 17:36:32 +0000 Subject: [PATCH 1/6] Make exit status interpretable by CommandConfigurator --- libafl/src/executors/command.rs | 40 ++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/libafl/src/executors/command.rs b/libafl/src/executors/command.rs index 7e98568d10..0c27e81681 100644 --- a/libafl/src/executors/command.rs +++ b/libafl/src/executors/command.rs @@ -5,8 +5,8 @@ use core::{ marker::PhantomData, ops::IndexMut, }; -#[cfg(unix)] -use std::os::unix::ffi::OsStrExt; +#[cfg(all(feature = "std", unix))] +use std::os::unix::{ffi::OsStrExt, process::ExitStatusExt}; #[cfg(all(feature = "std", target_os = "linux"))] use std::{ ffi::{CStr, CString}, @@ -337,8 +337,6 @@ where OT: Debug + ObserversTuple, { fn execute_input_with_command(&mut self, state: &mut S, input: &I) -> Result { - use std::os::unix::prelude::ExitStatusExt; - use wait_timeout::ChildExt; *state.executions_mut() += 1; @@ -346,29 +344,21 @@ where let mut child = self.configurer.spawn_child(input)?; - let res = match child + let exit_kind = child .wait_timeout(self.configurer.exec_timeout()) .expect("waiting on child failed") - .map(|status| status.signal()) - { - // for reference: https://www.man7.org/linux/man-pages/man7/signal.7.html - Some(Some(9)) => Ok(ExitKind::Oom), - Some(Some(_)) => Ok(ExitKind::Crash), - Some(None) => Ok(ExitKind::Ok), - None => { + .map(|status| self.configurer.exit_kind_from_status(&status)) + .unwrap_or_else(|| { // if this fails, there is not much we can do. let's hope it failed because the process finished // in the meantime. drop(child.kill()); // finally, try to wait to properly clean up system resources. drop(child.wait()); - Ok(ExitKind::Timeout) - } - }; + ExitKind::Timeout + }); - if let Ok(exit_kind) = res { - self.observers - .post_exec_child_all(state, input, &exit_kind)?; - } + self.observers + .post_exec_child_all(state, input, &exit_kind)?; if let Some(h) = &mut self.configurer.stdout_observer() { let mut stdout = Vec::new(); @@ -392,7 +382,7 @@ where let obs = observers.index_mut(h); obs.observe_stderr(&stderr); } - res + Ok(exit_kind) } } @@ -828,6 +818,16 @@ pub trait CommandConfigurator: Sized { /// Set the timeout duration for execution of the child process. fn exec_timeout_mut(&mut self) -> &mut Duration; + /// Maps the exit status of the child process to an `ExitKind`. + fn exit_kind_from_status(&self, status: &std::process::ExitStatus) -> ExitKind { + match status.signal() { + // for reference: https://www.man7.org/linux/man-pages/man7/signal.7.html + Some(9) => ExitKind::Oom, + Some(_) => ExitKind::Crash, + None => ExitKind::Ok, + } + } + /// Create an `Executor` from this `CommandConfigurator`. fn into_executor(self, observers: OT) -> CommandExecutor where From bcd7d710292168589dd34f0b2ed40898d0c75d22 Mon Sep 17 00:00:00 2001 From: Mohammad Omidvar Date: Mon, 25 Nov 2024 19:05:33 +0000 Subject: [PATCH 2/6] Fix import issues --- libafl/src/executors/command.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libafl/src/executors/command.rs b/libafl/src/executors/command.rs index 0c27e81681..5eb5f08767 100644 --- a/libafl/src/executors/command.rs +++ b/libafl/src/executors/command.rs @@ -5,8 +5,8 @@ use core::{ marker::PhantomData, ops::IndexMut, }; -#[cfg(all(feature = "std", unix))] -use std::os::unix::{ffi::OsStrExt, process::ExitStatusExt}; +#[cfg(unix)] +use std::os::unix::ffi::OsStrExt; #[cfg(all(feature = "std", target_os = "linux"))] use std::{ ffi::{CStr, CString}, @@ -38,7 +38,9 @@ use typed_builder::TypedBuilder; use super::HasTimeout; #[cfg(all(feature = "std", unix))] -use crate::executors::{Executor, ExitKind}; +use crate::executors::Executor; +#[cfg(all(feature = "std", any(unix, doc)))] +use crate::executors::ExitKind; use crate::{ corpus::Corpus, executors::{hooks::ExecutorHooksTuple, HasObservers}, @@ -819,7 +821,9 @@ pub trait CommandConfigurator: Sized { fn exec_timeout_mut(&mut self) -> &mut Duration; /// Maps the exit status of the child process to an `ExitKind`. + #[inline] fn exit_kind_from_status(&self, status: &std::process::ExitStatus) -> ExitKind { + use crate::std::os::unix::process::ExitStatusExt; match status.signal() { // for reference: https://www.man7.org/linux/man-pages/man7/signal.7.html Some(9) => ExitKind::Oom, From 5457f6f7376c2a3a4d4c8459de46d6b54bb0d44f Mon Sep 17 00:00:00 2001 From: Mohammad Omidvar Date: Tue, 26 Nov 2024 17:46:06 +0000 Subject: [PATCH 3/6] Fix default implementation for non-unix environment --- libafl/src/executors/command.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/libafl/src/executors/command.rs b/libafl/src/executors/command.rs index 5eb5f08767..557913eb75 100644 --- a/libafl/src/executors/command.rs +++ b/libafl/src/executors/command.rs @@ -823,12 +823,21 @@ pub trait CommandConfigurator: Sized { /// Maps the exit status of the child process to an `ExitKind`. #[inline] fn exit_kind_from_status(&self, status: &std::process::ExitStatus) -> ExitKind { - use crate::std::os::unix::process::ExitStatusExt; - match status.signal() { - // for reference: https://www.man7.org/linux/man-pages/man7/signal.7.html - Some(9) => ExitKind::Oom, - Some(_) => ExitKind::Crash, - None => ExitKind::Ok, + #[cfg(unix)] + { + use crate::std::os::unix::process::ExitStatusExt; + match status.signal() { + // for reference: https://www.man7.org/linux/man-pages/man7/signal.7.html + Some(9) => ExitKind::Oom, + Some(_) => ExitKind::Crash, + None => ExitKind::Ok, + } + } + #[cfg(not(unix))] + { + unimplemented!( + "Provide a default implementation when `CommandConfigurator` becomes available for non-unix targets." + ) } } From 1528faf1c0c8538bc52653b12d7e034159e6cd81 Mon Sep 17 00:00:00 2001 From: Mohammad Omidvar Date: Tue, 26 Nov 2024 19:02:09 +0000 Subject: [PATCH 4/6] Make docs only available on unix if the entry is only for unix --- libafl/src/executors/command.rs | 2 +- libafl/src/executors/mod.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libafl/src/executors/command.rs b/libafl/src/executors/command.rs index 557913eb75..1051a1576b 100644 --- a/libafl/src/executors/command.rs +++ b/libafl/src/executors/command.rs @@ -801,7 +801,7 @@ impl CommandExecutorBuilder { /// MyExecutor.into_executor(()) /// } /// ``` -#[cfg(all(feature = "std", any(unix, doc)))] +#[cfg(all(feature = "std", unix))] pub trait CommandConfigurator: Sized { /// Get the stdout fn stdout_observer(&self) -> Option> { diff --git a/libafl/src/executors/mod.rs b/libafl/src/executors/mod.rs index 993a85fe2e..d8c9c345e3 100644 --- a/libafl/src/executors/mod.rs +++ b/libafl/src/executors/mod.rs @@ -5,7 +5,7 @@ use alloc::vec::Vec; use core::{fmt::Debug, time::Duration}; pub use combined::CombinedExecutor; -#[cfg(all(feature = "std", any(unix, doc)))] +#[cfg(all(feature = "std", unix))] pub use command::CommandExecutor; pub use differential::DiffExecutor; #[cfg(all(feature = "std", feature = "fork", unix))] @@ -23,7 +23,7 @@ pub use with_observers::WithObservers; use crate::{observers::ObserversTuple, state::UsesState, Error}; pub mod combined; -#[cfg(all(feature = "std", any(unix, doc)))] +#[cfg(all(feature = "std", unix))] pub mod command; pub mod differential; #[cfg(all(feature = "std", feature = "fork", unix))] From 624126c4fcb278df842db8c9a7c7a986a17cfec8 Mon Sep 17 00:00:00 2001 From: Mohammad Omidvar Date: Tue, 26 Nov 2024 19:03:36 +0000 Subject: [PATCH 5/6] Revert "Fix default implementation for non-unix environment" This reverts commit 5457f6f7376c2a3a4d4c8459de46d6b54bb0d44f. --- libafl/src/executors/command.rs | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/libafl/src/executors/command.rs b/libafl/src/executors/command.rs index 1051a1576b..ac1fe6d07f 100644 --- a/libafl/src/executors/command.rs +++ b/libafl/src/executors/command.rs @@ -823,21 +823,12 @@ pub trait CommandConfigurator: Sized { /// Maps the exit status of the child process to an `ExitKind`. #[inline] fn exit_kind_from_status(&self, status: &std::process::ExitStatus) -> ExitKind { - #[cfg(unix)] - { - use crate::std::os::unix::process::ExitStatusExt; - match status.signal() { - // for reference: https://www.man7.org/linux/man-pages/man7/signal.7.html - Some(9) => ExitKind::Oom, - Some(_) => ExitKind::Crash, - None => ExitKind::Ok, - } - } - #[cfg(not(unix))] - { - unimplemented!( - "Provide a default implementation when `CommandConfigurator` becomes available for non-unix targets." - ) + use crate::std::os::unix::process::ExitStatusExt; + match status.signal() { + // for reference: https://www.man7.org/linux/man-pages/man7/signal.7.html + Some(9) => ExitKind::Oom, + Some(_) => ExitKind::Crash, + None => ExitKind::Ok, } } From 89a2ec4f28ed1cd71c487082b3ce2101e301f8ff Mon Sep 17 00:00:00 2001 From: Mohammad Omidvar Date: Wed, 27 Nov 2024 17:44:12 +0000 Subject: [PATCH 6/6] Fix the invalid link in the example --- libafl/src/observers/stdio.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libafl/src/observers/stdio.rs b/libafl/src/observers/stdio.rs index 950e38d5c7..bab111c9d4 100644 --- a/libafl/src/observers/stdio.rs +++ b/libafl/src/observers/stdio.rs @@ -2,7 +2,10 @@ //! //! The [`StdOutObserver`] and [`StdErrObserver`] observers look at the stdout of a program //! The executor must explicitly support these observers. -//! For example, they are supported on the [`crate::executors::CommandExecutor`]. +#![cfg_attr( + all(feature = "std", unix), + doc = r"For example, they are supported on the [`crate::executors::CommandExecutor`]." +)] use alloc::borrow::Cow; use std::vec::Vec;