Skip to content

Commit 5ae19fc

Browse files
authored
Split up HasTimeout trait, use it for command configurator (AFLplusplus#3476)
* Split up HasTimeout trait, use it for command configurator * fmt * fmt
1 parent c738d3c commit 5ae19fc

File tree

18 files changed

+756
-441
lines changed

18 files changed

+756
-441
lines changed

crates/libafl/src/executors/combined.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use libafl_bolts::tuples::RefIndexable;
88
use super::HasTimeout;
99
use crate::{
1010
Error,
11-
executors::{Executor, ExitKind, HasObservers},
11+
executors::{Executor, ExitKind, HasObservers, SetTimeout},
1212
};
1313

1414
/// A [`CombinedExecutor`] wraps a primary executor, forwarding its methods, and a secondary one
@@ -56,12 +56,6 @@ where
5656
A: HasTimeout,
5757
B: HasTimeout,
5858
{
59-
#[inline]
60-
fn set_timeout(&mut self, timeout: Duration) {
61-
self.primary.set_timeout(timeout);
62-
self.secondary.set_timeout(timeout);
63-
}
64-
6559
#[inline]
6660
fn timeout(&self) -> Duration {
6761
assert!(
@@ -72,6 +66,18 @@ where
7266
}
7367
}
7468

69+
impl<A, B> SetTimeout for CombinedExecutor<A, B>
70+
where
71+
A: SetTimeout,
72+
B: SetTimeout,
73+
{
74+
#[inline]
75+
fn set_timeout(&mut self, timeout: Duration) {
76+
self.primary.set_timeout(timeout);
77+
self.secondary.set_timeout(timeout);
78+
}
79+
}
80+
7581
impl<A, B> HasObservers for CombinedExecutor<A, B>
7682
where
7783
A: HasObservers,

crates/libafl/src/executors/command.rs

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ use typed_builder::TypedBuilder;
5757

5858
#[cfg(all(target_family = "unix", feature = "fork"))]
5959
use super::forkserver::ConfigTarget;
60-
use super::{HasTimeout, StdChildArgs, StdChildArgsInner};
60+
use super::{StdChildArgs, StdChildArgsInner};
6161
#[cfg(target_os = "linux")]
6262
use crate::executors::hooks::ExecutorHooksTuple;
6363
use crate::{
6464
Error,
65-
executors::{Executor, ExitKind, HasObservers},
65+
executors::{Executor, ExitKind, HasObservers, HasTimeout, SetTimeout},
6666
inputs::{HasTargetBytes, ToTargetBytes},
6767
observers::{ObserversTuple, StdErrObserver, StdOutObserver},
6868
state::HasExecutions,
@@ -204,19 +204,26 @@ impl CommandConfigurator<Child> for StdCommandConfigurator {
204204
}
205205
}
206206
}
207+
}
207208

208-
fn exec_timeout(&self) -> Duration {
209+
impl HasTimeout for StdCommandConfigurator {
210+
fn timeout(&self) -> Duration {
209211
self.timeout
210212
}
211-
fn exec_timeout_mut(&mut self) -> &mut Duration {
212-
&mut self.timeout
213+
}
214+
215+
impl SetTimeout for StdCommandConfigurator {
216+
fn set_timeout(&mut self, timeout: Duration) {
217+
self.timeout = timeout;
213218
}
214219
}
215220

216221
/// Linux specific [`CommandConfigurator`] that leverages `ptrace`
217222
///
218223
/// This configurator was primarily developed to be used in conjunction with
219224
/// [`crate::executors::hooks::intel_pt::IntelPTHook`]
225+
///
226+
/// Use `PTraceCommandConfigurator::builder().timeout` to set an initial timeout
220227
#[cfg(all(feature = "intel_pt", target_os = "linux"))]
221228
#[derive(Debug, Clone, PartialEq, Eq, TypedBuilder)]
222229
pub struct PTraceCommandConfigurator {
@@ -300,15 +307,13 @@ impl CommandConfigurator<Pid> for PTraceCommandConfigurator {
300307
Err(e) => Err(Error::unknown(format!("Fork failed: {e}"))),
301308
}
302309
}
310+
}
303311

304-
fn exec_timeout(&self) -> Duration {
312+
#[cfg(all(feature = "intel_pt", target_os = "linux"))]
313+
impl HasTimeout for PTraceCommandConfigurator {
314+
fn timeout(&self) -> Duration {
305315
Duration::from_secs(u64::from(self.timeout))
306316
}
307-
308-
/// Use [`PTraceCommandConfigurator::builder()`](PTraceCommandConfigurator) instead
309-
fn exec_timeout_mut(&mut self) -> &mut Duration {
310-
unimplemented!("Use [`PTraceCommandConfigurator::builder().timeout`] instead")
311-
}
312317
}
313318

314319
/// A `CommandExecutor` is a wrapper around [`Command`] to execute a target as a child process.
@@ -372,7 +377,7 @@ impl<C, HT, I, OT, S, T> CommandExecutor<C, HT, I, OT, S, T> {
372377
impl<HT, I, OT, S, T> CommandExecutor<Child, HT, I, OT, S, T>
373378
where
374379
S: HasExecutions,
375-
T: CommandConfigurator<Child> + Debug,
380+
T: CommandConfigurator<Child> + HasTimeout + Debug,
376381
OT: ObserversTuple<I, S>,
377382
{
378383
fn execute_input_with_command<TB: ToTargetBytes<I>>(
@@ -390,7 +395,7 @@ where
390395
.spawn_child(target_bytes_converter.to_target_bytes(input))?;
391396

392397
let exit_kind = child
393-
.wait_timeout(self.configurator.exec_timeout())
398+
.wait_timeout(self.configurator.timeout())
394399
.expect("waiting on child failed")
395400
.map(|status| self.configurator.exit_kind_from_status(&status))
396401
.unwrap_or_else(|| {
@@ -431,7 +436,7 @@ where
431436
impl<EM, HT, I, OT, S, T, Z> Executor<EM, I, S, Z> for CommandExecutor<Child, HT, I, OT, S, T>
432437
where
433438
S: HasExecutions,
434-
T: CommandConfigurator<Child> + Debug,
439+
T: CommandConfigurator<Child> + HasTimeout + Debug,
435440
OT: MatchName + ObserversTuple<I, S>,
436441
Z: ToTargetBytes<I>,
437442
{
@@ -449,16 +454,21 @@ where
449454
// this only works on unix because of the reliance on checking the process signal for detecting OOM
450455
impl<C, HT, I, OT, S, T> HasTimeout for CommandExecutor<C, HT, I, OT, S, T>
451456
where
452-
T: CommandConfigurator<C>,
457+
T: HasTimeout,
453458
{
454459
#[inline]
455460
fn timeout(&self) -> Duration {
456-
self.configurator.exec_timeout()
461+
self.configurator.timeout()
457462
}
463+
}
458464

465+
impl<C, HT, I, OT, S, T> SetTimeout for CommandExecutor<C, HT, I, OT, S, T>
466+
where
467+
T: SetTimeout,
468+
{
459469
#[inline]
460470
fn set_timeout(&mut self, timeout: Duration) {
461-
*self.configurator.exec_timeout_mut() = timeout;
471+
self.configurator.set_timeout(timeout);
462472
}
463473
}
464474

@@ -742,7 +752,7 @@ impl CommandExecutorBuilder {
742752
/// use libafl::{
743753
/// Error, HasTargetBytesConverter,
744754
/// corpus::Corpus,
745-
/// executors::{Executor, command::CommandConfigurator},
755+
/// executors::{Executor, HasTimeout, command::CommandConfigurator},
746756
/// inputs::{BytesInput, HasTargetBytes, Input, ToTargetBytes},
747757
/// state::HasExecutions,
748758
/// };
@@ -763,13 +773,12 @@ impl CommandExecutorBuilder {
763773
/// stdin.write_all(&target_bytes)?;
764774
/// Ok(child)
765775
/// }
776+
/// }
766777
///
767-
/// fn exec_timeout(&self) -> Duration {
778+
/// impl HasTimeout for MyExecutor {
779+
/// fn timeout(&self) -> Duration {
768780
/// Duration::from_secs(5)
769781
/// }
770-
/// fn exec_timeout_mut(&mut self) -> &mut Duration {
771-
/// todo!()
772-
/// }
773782
/// }
774783
///
775784
/// fn make_executor<EM, S, Z>() -> impl Executor<EM, BytesInput, S, Z>
@@ -793,11 +802,6 @@ pub trait CommandConfigurator<C>: Sized {
793802
/// Spawns a new process with the given configuration.
794803
fn spawn_child(&mut self, target_bytes: OwnedSlice<'_, u8>) -> Result<C, Error>;
795804

796-
/// Provides timeout duration for execution of the child process.
797-
fn exec_timeout(&self) -> Duration;
798-
/// Set the timeout duration for execution of the child process.
799-
fn exec_timeout_mut(&mut self) -> &mut Duration;
800-
801805
/// Maps the exit status of the child process to an `ExitKind`.
802806
#[cfg(unix)]
803807
#[inline]

crates/libafl/src/executors/differential.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use serde::{Deserialize, Serialize};
1919
use super::HasTimeout;
2020
use crate::{
2121
Error,
22-
executors::{Executor, ExitKind, HasObservers},
22+
executors::{Executor, ExitKind, HasObservers, SetTimeout},
2323
observers::{DifferentialObserversTuple, ObserversTuple},
2424
};
2525

@@ -117,12 +117,6 @@ where
117117
A: HasTimeout,
118118
B: HasTimeout,
119119
{
120-
#[inline]
121-
fn set_timeout(&mut self, timeout: core::time::Duration) {
122-
self.primary.set_timeout(timeout);
123-
self.secondary.set_timeout(timeout);
124-
}
125-
126120
#[inline]
127121
fn timeout(&self) -> core::time::Duration {
128122
assert!(
@@ -133,6 +127,18 @@ where
133127
}
134128
}
135129

130+
impl<A, B, DOT, I, OTA, OTB, S> SetTimeout for DiffExecutor<A, B, DOT, I, OTA, OTB, S>
131+
where
132+
A: SetTimeout,
133+
B: SetTimeout,
134+
{
135+
#[inline]
136+
fn set_timeout(&mut self, timeout: core::time::Duration) {
137+
self.primary.set_timeout(timeout);
138+
self.secondary.set_timeout(timeout);
139+
}
140+
}
141+
136142
/// Proxy the observers of the inner executors
137143
#[derive(Serialize, Deserialize, Debug)]
138144
#[serde(

crates/libafl/src/executors/forkserver.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use crate::observers::{
4646
};
4747
use crate::{
4848
Error,
49-
executors::{Executor, ExitKind, HasObservers},
49+
executors::{Executor, ExitKind, HasObservers, SetTimeout},
5050
inputs::{Input, ToTargetBytes},
5151
mutators::Tokens,
5252
observers::{MapObserver, Observer, ObserversTuple},
@@ -1543,7 +1543,9 @@ impl<I, OT, S, SHM> HasTimeout for ForkserverExecutor<I, OT, S, SHM> {
15431543
fn timeout(&self) -> Duration {
15441544
self.timeout.into()
15451545
}
1546+
}
15461547

1548+
impl<I, OT, S, SHM> SetTimeout for ForkserverExecutor<I, OT, S, SHM> {
15471549
#[inline]
15481550
fn set_timeout(&mut self, timeout: Duration) {
15491551
self.timeout = TimeSpec::from_duration(timeout);

crates/libafl/src/executors/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,14 @@ pub trait Executor<EM, I, S, Z> {
136136
) -> Result<ExitKind, Error>;
137137
}
138138

139-
/// A trait that allows to get/set an `Executor`'s timeout thresold
139+
/// A trait that allows to get an `Executor`'s timeout threshold
140140
pub trait HasTimeout {
141141
/// Get a timeout
142142
fn timeout(&self) -> Duration;
143+
}
143144

145+
/// A trait that allows to set an `Executor`'s timeout threshold
146+
pub trait SetTimeout {
144147
/// Set timeout
145148
fn set_timeout(&mut self, timeout: Duration);
146149
}

crates/libafl/src/executors/nop.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use core::time::Duration;
55
use libafl_bolts::tuples::RefIndexable;
66

77
use super::{Executor, ExitKind, HasObservers, HasTimeout};
8+
use crate::executors::SetTimeout;
89

910
/// [`NopExecutor`] is an executor that does nothing
1011
pub type NopExecutor = ConstantExecutor<()>;
@@ -64,7 +65,9 @@ impl<OT> HasTimeout for ConstantExecutor<OT> {
6465
fn timeout(&self) -> Duration {
6566
self.tm
6667
}
68+
}
6769

70+
impl<OT> SetTimeout for ConstantExecutor<OT> {
6871
fn set_timeout(&mut self, timeout: Duration) {
6972
self.tm = timeout;
7073
}

crates/libafl/src/executors/sand.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use libafl_bolts::{
1616
use super::{Executor, ExecutorsTuple, ExitKind, HasObservers, HasTimeout};
1717
use crate::{
1818
HasNamedMetadata,
19+
executors::SetTimeout,
1920
observers::{MapObserver, classify_counts},
2021
};
2122

@@ -105,7 +106,12 @@ where
105106
fn timeout(&self) -> core::time::Duration {
106107
self.executor.timeout()
107108
}
109+
}
108110

111+
impl<E, ET, C, O> SetTimeout for SANDExecutor<E, ET, C, O>
112+
where
113+
E: SetTimeout,
114+
{
109115
fn set_timeout(&mut self, timeout: core::time::Duration) {
110116
self.executor.set_timeout(timeout);
111117
}

crates/libafl/src/executors/shadow.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use core::{
88

99
use libafl_bolts::tuples::RefIndexable;
1010

11-
use super::HasTimeout;
11+
use super::{HasTimeout, SetTimeout};
1212
use crate::{
1313
Error,
1414
executors::{Executor, ExitKind, HasObservers},
@@ -96,16 +96,22 @@ impl<E, I, S, SOT> HasTimeout for ShadowExecutor<E, I, S, SOT>
9696
where
9797
E: HasTimeout,
9898
{
99-
#[inline]
100-
fn set_timeout(&mut self, timeout: Duration) {
101-
self.executor.set_timeout(timeout);
102-
}
10399
#[inline]
104100
fn timeout(&self) -> Duration {
105101
self.executor.timeout()
106102
}
107103
}
108104

105+
impl<E, I, S, SOT> SetTimeout for ShadowExecutor<E, I, S, SOT>
106+
where
107+
E: SetTimeout,
108+
{
109+
#[inline]
110+
fn set_timeout(&mut self, timeout: Duration) {
111+
self.executor.set_timeout(timeout);
112+
}
113+
}
114+
109115
impl<E, I, S, SOT> HasObservers for ShadowExecutor<E, I, S, SOT>
110116
where
111117
E: HasObservers,

crates/libafl/src/stages/verify_timeouts.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize, de::DeserializeOwned};
1111

1212
use crate::{
1313
Evaluator, HasMetadata,
14-
executors::{Executor, HasObservers, HasTimeout},
14+
executors::{Executor, HasObservers, SetTimeout},
1515
inputs::BytesInput,
1616
observers::ObserversTuple,
1717
stages::{Restartable, Stage},
@@ -82,7 +82,7 @@ impl<I> TimeoutsToVerify<I> {
8282
impl<E, EM, I, S, Z> Stage<E, EM, S, Z> for VerifyTimeoutsStage<E, I, S>
8383
where
8484
E::Observers: ObserversTuple<I, S>,
85-
E: Executor<EM, I, S, Z> + HasObservers + HasTimeout,
85+
E: Executor<EM, I, S, Z> + HasObservers + SetTimeout,
8686
Z: Evaluator<E, EM, I, S>,
8787
S: HasMetadata,
8888
I: Debug + Serialize + DeserializeOwned + Default + 'static + Clone,

crates/libafl_nyx/src/executor.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::{
66

77
use libafl::{
88
Error,
9-
executors::{Executor, ExitKind, HasObservers, HasTimeout},
9+
executors::{Executor, ExitKind, HasObservers, HasTimeout, SetTimeout},
1010
inputs::HasTargetBytes,
1111
observers::{ObserversTuple, StdOutObserver},
1212
state::HasExecutions,
@@ -148,7 +148,9 @@ impl<S, OT> HasTimeout for NyxExecutor<S, OT> {
148148
fn timeout(&self) -> core::time::Duration {
149149
self.helper.timeout
150150
}
151+
}
151152

153+
impl<S, OT> SetTimeout for NyxExecutor<S, OT> {
152154
fn set_timeout(&mut self, timeout: core::time::Duration) {
153155
let micros = 1000000;
154156
let mut timeout_secs = timeout.as_secs();

0 commit comments

Comments
 (0)