No uses for EventManager (#2831)
* the first step of the last step * wip * 99% done * 99.9% done * 99.99 * Hello from windows * aaa * 99.999 * aa * 1 * 2 * 3 * 4 * 5 * plz * plzplzplz --------- Co-authored-by: Your Name <you@example.com>
This commit is contained in:
parent
ba09cb0706
commit
435ca021cc
@ -11,6 +11,10 @@
|
|||||||
- Related: `EmulatorBuilder` uses a single function to provide a `Qemu` initializer: `EmulatorBuilder::qemu_parameters`. For now, it can be either a `Vec<String>` or a `QemuConfig` instance.
|
- Related: `EmulatorBuilder` uses a single function to provide a `Qemu` initializer: `EmulatorBuilder::qemu_parameters`. For now, it can be either a `Vec<String>` or a `QemuConfig` instance.
|
||||||
- Related: Qemu's `AsanModule` does not need any special call to `Qemu` init methods anymore. It is now possible to simply initialize `AsanModule` (or `AsanGuestModule`) with a reference to the environment as parameter.
|
- Related: Qemu's `AsanModule` does not need any special call to `Qemu` init methods anymore. It is now possible to simply initialize `AsanModule` (or `AsanGuestModule`) with a reference to the environment as parameter.
|
||||||
- `CustomBufHandlers` has been deleted. Please use `EventManagerHooksTuple` from now on.
|
- `CustomBufHandlers` has been deleted. Please use `EventManagerHooksTuple` from now on.
|
||||||
|
- The `UsesState` and `UsesInput` traits have been removed in favor of regular Generics.
|
||||||
|
- For the structs/traits that used to use `UsesState`, we bring back the generic for the state.
|
||||||
|
- For `UsesState`, you can access to the input type through `HasCorpus` and `Corpus` traits
|
||||||
|
|
||||||
# 0.14.0 -> 0.14.1
|
# 0.14.0 -> 0.14.1
|
||||||
- Removed `with_observers` from `Executor` trait.
|
- Removed `with_observers` from `Executor` trait.
|
||||||
- `MmapShMemProvider::new_shmem_persistent` has been removed in favour of `MmapShMem::persist`. You probably want to do something like this: `let shmem = MmapShMemProvider::new()?.new_shmem(size)?.persist()?;`
|
- `MmapShMemProvider::new_shmem_persistent` has been removed in favour of `MmapShMem::persist`. You probably want to do something like this: `let shmem = MmapShMemProvider::new()?.new_shmem(size)?.persist()?;`
|
||||||
|
@ -14,12 +14,12 @@ use libafl::{
|
|||||||
feedbacks::{CrashFeedback, MaxMapFeedback},
|
feedbacks::{CrashFeedback, MaxMapFeedback},
|
||||||
fuzzer::{Fuzzer, StdFuzzer},
|
fuzzer::{Fuzzer, StdFuzzer},
|
||||||
generators::RandPrintablesGenerator,
|
generators::RandPrintablesGenerator,
|
||||||
inputs::{HasTargetBytes, UsesInput},
|
inputs::HasTargetBytes,
|
||||||
mutators::{havoc_mutations::havoc_mutations, scheduled::StdScheduledMutator},
|
mutators::{havoc_mutations::havoc_mutations, scheduled::StdScheduledMutator},
|
||||||
observers::StdMapObserver,
|
observers::StdMapObserver,
|
||||||
schedulers::QueueScheduler,
|
schedulers::QueueScheduler,
|
||||||
stages::{mutational::StdMutationalStage, AflStatsStage, CalibrationStage},
|
stages::{mutational::StdMutationalStage, AflStatsStage, CalibrationStage},
|
||||||
state::{HasCorpus, HasExecutions, StdState, UsesState},
|
state::{HasCorpus, HasExecutions, StdState},
|
||||||
};
|
};
|
||||||
use libafl_bolts::{current_nanos, nonzero, rands::StdRand, tuples::tuple_list, AsSlice};
|
use libafl_bolts::{current_nanos, nonzero, rands::StdRand, tuples::tuple_list, AsSlice};
|
||||||
|
|
||||||
@ -49,8 +49,7 @@ impl<S> CustomExecutor<S> {
|
|||||||
|
|
||||||
impl<EM, S, Z> Executor<EM, <S::Corpus as Corpus>::Input, S, Z> for CustomExecutor<S>
|
impl<EM, S, Z> Executor<EM, <S::Corpus as Corpus>::Input, S, Z> for CustomExecutor<S>
|
||||||
where
|
where
|
||||||
EM: UsesState<State = S>,
|
S: HasCorpus + HasExecutions,
|
||||||
S: HasCorpus + HasExecutions + UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
<S::Corpus as Corpus>::Input: HasTargetBytes,
|
<S::Corpus as Corpus>::Input: HasTargetBytes,
|
||||||
{
|
{
|
||||||
fn run_target(
|
fn run_target(
|
||||||
|
@ -7,7 +7,7 @@ use std::{env, fmt::Write, io, path::PathBuf, process, ptr::NonNull};
|
|||||||
use clap::{builder::Str, Parser};
|
use clap::{builder::Str, Parser};
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{Corpus, InMemoryOnDiskCorpus, NopCorpus},
|
corpus::{Corpus, InMemoryOnDiskCorpus, NopCorpus},
|
||||||
events::{EventRestarter, SimpleRestartingEventManager},
|
events::{EventRestarter, ManagerExit, SimpleRestartingEventManager},
|
||||||
executors::ExitKind,
|
executors::ExitKind,
|
||||||
feedbacks::MaxMapFeedback,
|
feedbacks::MaxMapFeedback,
|
||||||
fuzzer::StdFuzzer,
|
fuzzer::StdFuzzer,
|
||||||
|
@ -10,7 +10,7 @@ use libafl::{
|
|||||||
corpus::{Corpus, InMemoryCorpus},
|
corpus::{Corpus, InMemoryCorpus},
|
||||||
events::{
|
events::{
|
||||||
launcher::Launcher, ClientDescription, EventConfig, EventRestarter,
|
launcher::Launcher, ClientDescription, EventConfig, EventRestarter,
|
||||||
LlmpRestartingEventManager,
|
LlmpRestartingEventManager, ManagerExit,
|
||||||
},
|
},
|
||||||
executors::ExitKind,
|
executors::ExitKind,
|
||||||
fuzzer::StdFuzzer,
|
fuzzer::StdFuzzer,
|
||||||
|
@ -8,8 +8,7 @@ use std::{
|
|||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
executors::{Executor, ExitKind, HasObservers, HasTimeout},
|
executors::{Executor, ExitKind, HasObservers, HasTimeout},
|
||||||
inputs::UsesInput,
|
state::HasCorpus,
|
||||||
state::{HasCorpus, UsesState},
|
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
use libafl_bolts::tuples::RefIndexable;
|
use libafl_bolts::tuples::RefIndexable;
|
||||||
@ -263,7 +262,7 @@ pub enum SupportedExecutors<S, OT, FSV, NYX> {
|
|||||||
impl<S, OT, FSV, NYX, EM, Z> Executor<EM, <S::Corpus as Corpus>::Input, S, Z>
|
impl<S, OT, FSV, NYX, EM, Z> Executor<EM, <S::Corpus as Corpus>::Input, S, Z>
|
||||||
for SupportedExecutors<S, OT, FSV, NYX>
|
for SupportedExecutors<S, OT, FSV, NYX>
|
||||||
where
|
where
|
||||||
S: HasCorpus + UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
S: HasCorpus,
|
||||||
EM: UsesState<State = S>,
|
EM: UsesState<State = S>,
|
||||||
NYX: Executor<EM, <S::Corpus as Corpus>::Input, S, Z>,
|
NYX: Executor<EM, <S::Corpus as Corpus>::Input, S, Z>,
|
||||||
FSV: Executor<EM, <S::Corpus as Corpus>::Input, S, Z>,
|
FSV: Executor<EM, <S::Corpus as Corpus>::Input, S, Z>,
|
||||||
@ -340,8 +339,7 @@ pub enum SupportedExecutors<S, OT, FSV> {
|
|||||||
impl<S, OT, FSV, EM, Z> Executor<EM, <S::Corpus as Corpus>::Input, S, Z>
|
impl<S, OT, FSV, EM, Z> Executor<EM, <S::Corpus as Corpus>::Input, S, Z>
|
||||||
for SupportedExecutors<S, OT, FSV>
|
for SupportedExecutors<S, OT, FSV>
|
||||||
where
|
where
|
||||||
S: HasCorpus + UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
S: HasCorpus,
|
||||||
EM: UsesState<State = S>,
|
|
||||||
FSV: Executor<EM, <S::Corpus as Corpus>::Input, S, Z>,
|
FSV: Executor<EM, <S::Corpus as Corpus>::Input, S, Z>,
|
||||||
{
|
{
|
||||||
fn run_target(
|
fn run_target(
|
||||||
@ -349,7 +347,7 @@ where
|
|||||||
fuzzer: &mut Z,
|
fuzzer: &mut Z,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
mgr: &mut EM,
|
mgr: &mut EM,
|
||||||
input: &S::Input,
|
input: &<S::Corpus as Corpus>::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
match self {
|
match self {
|
||||||
Self::Forkserver(fsrv, _) => fsrv.run_target(fuzzer, state, mgr, input),
|
Self::Forkserver(fsrv, _) => fsrv.run_target(fuzzer, state, mgr, input),
|
||||||
|
@ -22,7 +22,7 @@ use libafl::{
|
|||||||
CaptureTimeoutFeedback, ConstFeedback, CrashFeedback, MaxMapFeedback, TimeFeedback,
|
CaptureTimeoutFeedback, ConstFeedback, CrashFeedback, MaxMapFeedback, TimeFeedback,
|
||||||
},
|
},
|
||||||
fuzzer::StdFuzzer,
|
fuzzer::StdFuzzer,
|
||||||
inputs::{BytesInput, NopTargetBytesConverter, UsesInput},
|
inputs::{BytesInput, NopTargetBytesConverter},
|
||||||
mutators::{havoc_mutations, tokens_mutations, AFLppRedQueen, StdScheduledMutator, Tokens},
|
mutators::{havoc_mutations, tokens_mutations, AFLppRedQueen, StdScheduledMutator, Tokens},
|
||||||
observers::{CanTrack, HitcountsMapObserver, StdMapObserver, TimeObserver},
|
observers::{CanTrack, HitcountsMapObserver, StdMapObserver, TimeObserver},
|
||||||
schedulers::{
|
schedulers::{
|
||||||
@ -83,7 +83,7 @@ type LibaflFuzzManager = CentralizedEventManager<
|
|||||||
StdShMemProvider,
|
StdShMemProvider,
|
||||||
>;
|
>;
|
||||||
#[cfg(feature = "fuzzbench")]
|
#[cfg(feature = "fuzzbench")]
|
||||||
type LibaflFuzzManager<F> = SimpleEventManager<SimpleMonitor<F>, LibaflFuzzState>;
|
type LibaflFuzzManager<F> = SimpleEventManager<BytesInput, SimpleMonitor<F>, LibaflFuzzState>;
|
||||||
|
|
||||||
macro_rules! define_run_client {
|
macro_rules! define_run_client {
|
||||||
($state: ident, $mgr: ident, $fuzzer_dir: ident, $core_id: ident, $opt:ident, $is_main_node: ident, $body:block) => {
|
($state: ident, $mgr: ident, $fuzzer_dir: ident, $core_id: ident, $opt:ident, $is_main_node: ident, $body:block) => {
|
||||||
@ -658,9 +658,9 @@ pub fn run_fuzzer_with_stages<E, EM, S, ST, Z>(
|
|||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
Z: Fuzzer<E, EM, S, ST>,
|
Z: Fuzzer<E, EM, S, ST>,
|
||||||
EM: ProgressReporter<State = S>,
|
EM: ProgressReporter<S>,
|
||||||
ST: StagesTuple<E, EM, S, Z>,
|
ST: StagesTuple<E, EM, S, Z>,
|
||||||
S: HasLastReportTime + HasExecutions + HasMetadata + UsesInput,
|
S: HasLastReportTime + HasExecutions + HasMetadata,
|
||||||
{
|
{
|
||||||
if opt.bench_just_one {
|
if opt.bench_just_one {
|
||||||
fuzzer.fuzz_loop_for(stages, executor, state, mgr, 1)?;
|
fuzzer.fuzz_loop_for(stages, executor, state, mgr, 1)?;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use libafl::{
|
use libafl::{
|
||||||
|
corpus::Corpus,
|
||||||
events::{Event, EventManagerHook},
|
events::{Event, EventManagerHook},
|
||||||
state::{State, Stoppable},
|
state::{HasCorpus, Stoppable},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
use libafl_bolts::ClientId;
|
use libafl_bolts::ClientId;
|
||||||
@ -10,15 +11,15 @@ pub struct LibAflFuzzEventHook {
|
|||||||
exit_on_solution: bool,
|
exit_on_solution: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> EventManagerHook<S> for LibAflFuzzEventHook
|
impl<S> EventManagerHook<<S::Corpus as Corpus>::Input, S> for LibAflFuzzEventHook
|
||||||
where
|
where
|
||||||
S: State + Stoppable,
|
S: HasCorpus + Stoppable,
|
||||||
{
|
{
|
||||||
fn pre_exec(
|
fn pre_exec(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
_client_id: ClientId,
|
_client_id: ClientId,
|
||||||
event: &Event<S::Input>,
|
event: &Event<<S::Corpus as Corpus>::Input>,
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
if self.exit_on_solution && matches!(event, Event::Objective { .. }) {
|
if self.exit_on_solution && matches!(event, Event::Objective { .. }) {
|
||||||
// TODO: dump state
|
// TODO: dump state
|
||||||
|
@ -4,7 +4,7 @@ use core::time::Duration;
|
|||||||
use std::{env, path::PathBuf, process};
|
use std::{env, path::PathBuf, process};
|
||||||
|
|
||||||
#[cfg(not(feature = "nyx"))]
|
#[cfg(not(feature = "nyx"))]
|
||||||
use libafl::state::{HasExecutions, State};
|
use libafl::state::HasExecutions;
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
|
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
|
||||||
events::{launcher::Launcher, EventConfig},
|
events::{launcher::Launcher, EventConfig},
|
||||||
@ -80,7 +80,7 @@ fn get_emulator<C, ET, I, S>(
|
|||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S>,
|
ET: EmulatorModuleTuple<I, S>,
|
||||||
I: HasTargetBytes + Unpin,
|
I: HasTargetBytes + Unpin,
|
||||||
S: State + HasExecutions + Unpin,
|
S: HasExecutions + Unpin,
|
||||||
{
|
{
|
||||||
// Allow linux process address space addresses as feedback
|
// Allow linux process address space addresses as feedback
|
||||||
modules.allow_address_range_all(LINUX_PROCESS_ADDRESS_RANGE);
|
modules.allow_address_range_all(LINUX_PROCESS_ADDRESS_RANGE);
|
||||||
|
@ -4,7 +4,7 @@ use core::time::Duration;
|
|||||||
use std::{env, path::PathBuf, process};
|
use std::{env, path::PathBuf, process};
|
||||||
|
|
||||||
#[cfg(not(feature = "nyx"))]
|
#[cfg(not(feature = "nyx"))]
|
||||||
use libafl::state::{HasExecutions, State};
|
use libafl::state::HasExecutions;
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
|
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
|
||||||
events::{launcher::Launcher, EventConfig},
|
events::{launcher::Launcher, EventConfig},
|
||||||
@ -80,7 +80,7 @@ fn get_emulator<C, ET, I, S>(
|
|||||||
where
|
where
|
||||||
ET: EmulatorModuleTuple<I, S>,
|
ET: EmulatorModuleTuple<I, S>,
|
||||||
I: HasTargetBytes + Unpin,
|
I: HasTargetBytes + Unpin,
|
||||||
S: State + HasExecutions + Unpin,
|
S: HasExecutions + Unpin,
|
||||||
{
|
{
|
||||||
// Allow linux process address space addresses as feedback
|
// Allow linux process address space addresses as feedback
|
||||||
modules.allow_address_range_all(LINUX_PROCESS_ADDRESS_RANGE);
|
modules.allow_address_range_all(LINUX_PROCESS_ADDRESS_RANGE);
|
||||||
|
@ -30,7 +30,6 @@ libafl = { path = "../../../libafl", features = [
|
|||||||
"prelude",
|
"prelude",
|
||||||
"gzip",
|
"gzip",
|
||||||
"regex",
|
"regex",
|
||||||
"scalability_introspection",
|
|
||||||
] }
|
] }
|
||||||
libafl_bolts = { path = "../../../libafl_bolts", features = [
|
libafl_bolts = { path = "../../../libafl_bolts", features = [
|
||||||
"errors_backtrace",
|
"errors_backtrace",
|
||||||
|
@ -7,7 +7,10 @@ use std::{env, path::PathBuf};
|
|||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{minimizer::StdCorpusMinimizer, Corpus, InMemoryCorpus, OnDiskCorpus},
|
corpus::{minimizer::StdCorpusMinimizer, Corpus, InMemoryCorpus, OnDiskCorpus},
|
||||||
events::{setup_restarting_mgr_std, EventConfig, EventFirer, EventRestarter, LogSeverity},
|
events::{
|
||||||
|
setup_restarting_mgr_std, EventConfig, EventFirer, EventRestarter,
|
||||||
|
LlmpRestartingEventManager, LogSeverity,
|
||||||
|
},
|
||||||
executors::{inprocess::InProcessExecutor, ExitKind},
|
executors::{inprocess::InProcessExecutor, ExitKind},
|
||||||
feedback_or, feedback_or_fast,
|
feedback_or, feedback_or_fast,
|
||||||
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
||||||
@ -216,10 +219,20 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
|
|||||||
|
|
||||||
let orig_size = state.corpus().count();
|
let orig_size = state.corpus().count();
|
||||||
let msg = "Started distillation...".to_string();
|
let msg = "Started distillation...".to_string();
|
||||||
restarting_mgr.log(&mut state, LogSeverity::Info, msg)?;
|
<LlmpRestartingEventManager<_, _, _> as EventFirer<BytesInput, _>>::log(
|
||||||
|
&mut restarting_mgr,
|
||||||
|
&mut state,
|
||||||
|
LogSeverity::Info,
|
||||||
|
msg,
|
||||||
|
)?;
|
||||||
minimizer.minimize(&mut fuzzer, &mut executor, &mut restarting_mgr, &mut state)?;
|
minimizer.minimize(&mut fuzzer, &mut executor, &mut restarting_mgr, &mut state)?;
|
||||||
let msg = format!("Distilled out {} cases", orig_size - state.corpus().count());
|
let msg = format!("Distilled out {} cases", orig_size - state.corpus().count());
|
||||||
restarting_mgr.log(&mut state, LogSeverity::Info, msg)?;
|
<LlmpRestartingEventManager<_, _, _> as EventFirer<BytesInput, _>>::log(
|
||||||
|
&mut restarting_mgr,
|
||||||
|
&mut state,
|
||||||
|
LogSeverity::Info,
|
||||||
|
msg,
|
||||||
|
)?;
|
||||||
|
|
||||||
// It's important, that we store the state before restarting!
|
// It's important, that we store the state before restarting!
|
||||||
// Else, the parent will not respawn a new child and quit.
|
// Else, the parent will not respawn a new child and quit.
|
||||||
|
@ -43,7 +43,6 @@ libafl = { path = "../../../libafl", default-features = false, features = [
|
|||||||
"prelude",
|
"prelude",
|
||||||
"gzip",
|
"gzip",
|
||||||
"regex",
|
"regex",
|
||||||
"scalability_introspection",
|
|
||||||
"multi_machine",
|
"multi_machine",
|
||||||
"errors_backtrace",
|
"errors_backtrace",
|
||||||
] }
|
] }
|
||||||
|
@ -71,9 +71,6 @@ value_bloom_feedback = ["fastbloom", "fastbloom/serde"]
|
|||||||
## Collects performance statistics of the fuzzing pipeline and displays it on `Monitor` components
|
## Collects performance statistics of the fuzzing pipeline and displays it on `Monitor` components
|
||||||
introspection = []
|
introspection = []
|
||||||
|
|
||||||
## Collects stats about scalability
|
|
||||||
scalability_introspection = []
|
|
||||||
|
|
||||||
## Expose `libafl::prelude` for access without additional using directives
|
## Expose `libafl::prelude` for access without additional using directives
|
||||||
prelude = ["libafl_bolts/prelude"]
|
prelude = ["libafl_bolts/prelude"]
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ use crate::{
|
|||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
events::{Event, EventFirer, LogSeverity},
|
events::{Event, EventFirer, LogSeverity},
|
||||||
executors::{Executor, HasObservers},
|
executors::{Executor, HasObservers},
|
||||||
inputs::{Input, UsesInput},
|
inputs::Input,
|
||||||
monitors::{AggregatorOps, UserStats, UserStatsValue},
|
monitors::{AggregatorOps, UserStats, UserStatsValue},
|
||||||
observers::{MapObserver, ObserversTuple},
|
observers::{MapObserver, ObserversTuple},
|
||||||
schedulers::{LenTimeMulTestcaseScore, RemovableScheduler, Scheduler, TestcaseScore},
|
schedulers::{LenTimeMulTestcaseScore, RemovableScheduler, Scheduler, TestcaseScore},
|
||||||
@ -56,7 +56,7 @@ impl<C, E, O, S, T, TS> MapCorpusMinimizer<C, E, O, S, T, TS>
|
|||||||
where
|
where
|
||||||
for<'a> O: MapObserver<Entry = T> + AsIter<'a, Item = T>,
|
for<'a> O: MapObserver<Entry = T> + AsIter<'a, Item = T>,
|
||||||
C: AsRef<O>,
|
C: AsRef<O>,
|
||||||
S: HasMetadata + HasCorpus + HasExecutions + UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
S: HasMetadata + HasCorpus + HasExecutions,
|
||||||
<S::Corpus as Corpus>::Input: Input,
|
<S::Corpus as Corpus>::Input: Input,
|
||||||
T: Copy + Hash + Eq,
|
T: Copy + Hash + Eq,
|
||||||
TS: TestcaseScore<S>,
|
TS: TestcaseScore<S>,
|
||||||
@ -75,7 +75,7 @@ where
|
|||||||
E::Observers: ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
E::Observers: ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
CS: Scheduler<<S::Corpus as Corpus>::Input, S>
|
CS: Scheduler<<S::Corpus as Corpus>::Input, S>
|
||||||
+ RemovableScheduler<<S::Corpus as Corpus>::Input, S>,
|
+ RemovableScheduler<<S::Corpus as Corpus>::Input, S>,
|
||||||
EM: EventFirer<State = S>,
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
Z: HasScheduler<<S::Corpus as Corpus>::Input, S, Scheduler = CS>,
|
Z: HasScheduler<<S::Corpus as Corpus>::Input, S, Scheduler = CS>,
|
||||||
{
|
{
|
||||||
// don't delete this else it won't work after restart
|
// don't delete this else it won't work after restart
|
||||||
|
@ -8,13 +8,11 @@ use libafl_bolts::{
|
|||||||
shmem::ShMemProvider,
|
shmem::ShMemProvider,
|
||||||
ClientId, Error,
|
ClientId, Error,
|
||||||
};
|
};
|
||||||
|
use serde::de::DeserializeOwned;
|
||||||
|
|
||||||
#[cfg(feature = "llmp_compression")]
|
#[cfg(feature = "llmp_compression")]
|
||||||
use crate::events::COMPRESS_THRESHOLD;
|
use crate::events::COMPRESS_THRESHOLD;
|
||||||
use crate::{
|
use crate::events::{BrokerEventResult, Event, _LLMP_TAG_TO_MAIN};
|
||||||
events::{BrokerEventResult, Event, _LLMP_TAG_TO_MAIN},
|
|
||||||
inputs::Input,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// An LLMP-backed event manager for scalable multi-processed fuzzing
|
/// An LLMP-backed event manager for scalable multi-processed fuzzing
|
||||||
pub struct CentralizedLlmpHook<I> {
|
pub struct CentralizedLlmpHook<I> {
|
||||||
@ -25,7 +23,7 @@ pub struct CentralizedLlmpHook<I> {
|
|||||||
|
|
||||||
impl<I, SP> LlmpHook<SP> for CentralizedLlmpHook<I>
|
impl<I, SP> LlmpHook<SP> for CentralizedLlmpHook<I>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: DeserializeOwned,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
fn on_new_message(
|
fn on_new_message(
|
||||||
@ -75,10 +73,7 @@ impl<I> Debug for CentralizedLlmpHook<I> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I> CentralizedLlmpHook<I>
|
impl<I> CentralizedLlmpHook<I> {
|
||||||
where
|
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
/// Create an event broker from a raw broker.
|
/// Create an event broker from a raw broker.
|
||||||
pub fn new() -> Result<Self, Error> {
|
pub fn new() -> Result<Self, Error> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
@ -14,6 +14,7 @@ use libafl_bolts::{
|
|||||||
shmem::ShMemProvider,
|
shmem::ShMemProvider,
|
||||||
ClientId, Error,
|
ClientId, Error,
|
||||||
};
|
};
|
||||||
|
use serde::Serialize;
|
||||||
use tokio::{
|
use tokio::{
|
||||||
net::ToSocketAddrs,
|
net::ToSocketAddrs,
|
||||||
runtime::Runtime,
|
runtime::Runtime,
|
||||||
@ -70,10 +71,7 @@ impl<T> NullLock<T> {
|
|||||||
/// It is responsible for receiving messages from other neighbours.
|
/// It is responsible for receiving messages from other neighbours.
|
||||||
/// Please check [`crate::events::multi_machine`] for more information.
|
/// Please check [`crate::events::multi_machine`] for more information.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TcpMultiMachineLlmpSenderHook<A, I>
|
pub struct TcpMultiMachineLlmpSenderHook<A, I> {
|
||||||
where
|
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
/// the actual state of the broker hook
|
/// the actual state of the broker hook
|
||||||
shared_state: Arc<RwLock<TcpMultiMachineState<A>>>,
|
shared_state: Arc<RwLock<TcpMultiMachineState<A>>>,
|
||||||
/// the tokio runtime used to interact with other machines. Keep it outside to avoid locking it.
|
/// the tokio runtime used to interact with other machines. Keep it outside to avoid locking it.
|
||||||
@ -85,10 +83,7 @@ where
|
|||||||
/// It is responsible for receiving messages from other neighbours.
|
/// It is responsible for receiving messages from other neighbours.
|
||||||
/// Please check [`crate::events::multi_machine`] for more information.
|
/// Please check [`crate::events::multi_machine`] for more information.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TcpMultiMachineLlmpReceiverHook<A, I>
|
pub struct TcpMultiMachineLlmpReceiverHook<A, I> {
|
||||||
where
|
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
/// the actual state of the broker hook
|
/// the actual state of the broker hook
|
||||||
shared_state: Arc<RwLock<TcpMultiMachineState<A>>>,
|
shared_state: Arc<RwLock<TcpMultiMachineState<A>>>,
|
||||||
/// the tokio runtime used to interact with other machines. Keep it outside to avoid locking it.
|
/// the tokio runtime used to interact with other machines. Keep it outside to avoid locking it.
|
||||||
@ -96,11 +91,7 @@ where
|
|||||||
phantom: PhantomData<I>,
|
phantom: PhantomData<I>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, I> TcpMultiMachineLlmpSenderHook<A, I>
|
impl<A, I> TcpMultiMachineLlmpSenderHook<A, I> {
|
||||||
where
|
|
||||||
A: Clone + Display + ToSocketAddrs + Send + Sync + 'static,
|
|
||||||
I: Input + Send + Sync + 'static,
|
|
||||||
{
|
|
||||||
/// Should not be created alone. Use [`TcpMultiMachineHooksBuilder`] instead.
|
/// Should not be created alone. Use [`TcpMultiMachineHooksBuilder`] instead.
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
shared_state: Arc<RwLock<TcpMultiMachineState<A>>>,
|
shared_state: Arc<RwLock<TcpMultiMachineState<A>>>,
|
||||||
@ -117,7 +108,7 @@ where
|
|||||||
impl<A, I> TcpMultiMachineLlmpReceiverHook<A, I>
|
impl<A, I> TcpMultiMachineLlmpReceiverHook<A, I>
|
||||||
where
|
where
|
||||||
A: Clone + Display + ToSocketAddrs + Send + Sync + 'static,
|
A: Clone + Display + ToSocketAddrs + Send + Sync + 'static,
|
||||||
I: Input + Send + Sync + 'static,
|
I: Serialize,
|
||||||
{
|
{
|
||||||
/// Should not be created alone. Use [`TcpMultiMachineHooksBuilder`] instead.
|
/// Should not be created alone. Use [`TcpMultiMachineHooksBuilder`] instead.
|
||||||
///
|
///
|
||||||
@ -160,9 +151,9 @@ where
|
|||||||
|
|
||||||
impl<A, I, SP> LlmpHook<SP> for TcpMultiMachineLlmpSenderHook<A, I>
|
impl<A, I, SP> LlmpHook<SP> for TcpMultiMachineLlmpSenderHook<A, I>
|
||||||
where
|
where
|
||||||
A: Clone + Debug + Display + ToSocketAddrs + Send + Sync + 'static,
|
I: Input,
|
||||||
|
A: Clone + Display + ToSocketAddrs + Send + Sync + 'static,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
I: Input + Send + Sync + 'static,
|
|
||||||
{
|
{
|
||||||
/// check for received messages, and forward them alongside the incoming message to inner.
|
/// check for received messages, and forward them alongside the incoming message to inner.
|
||||||
fn on_new_message(
|
fn on_new_message(
|
||||||
@ -222,9 +213,9 @@ where
|
|||||||
|
|
||||||
impl<A, I, SP> LlmpHook<SP> for TcpMultiMachineLlmpReceiverHook<A, I>
|
impl<A, I, SP> LlmpHook<SP> for TcpMultiMachineLlmpReceiverHook<A, I>
|
||||||
where
|
where
|
||||||
A: Clone + Debug + Display + ToSocketAddrs + Send + Sync + 'static,
|
I: Input,
|
||||||
|
A: Clone + Display + ToSocketAddrs + Send + Sync + 'static,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
I: Input + Send + Sync + 'static,
|
|
||||||
{
|
{
|
||||||
/// check for received messages, and forward them alongside the incoming message to inner.
|
/// check for received messages, and forward them alongside the incoming message to inner.
|
||||||
fn on_new_message(
|
fn on_new_message(
|
||||||
|
@ -9,12 +9,12 @@ use libafl_bolts::{
|
|||||||
shmem::ShMemProvider,
|
shmem::ShMemProvider,
|
||||||
ClientId,
|
ClientId,
|
||||||
};
|
};
|
||||||
|
use serde::de::DeserializeOwned;
|
||||||
|
|
||||||
#[cfg(feature = "llmp_compression")]
|
#[cfg(feature = "llmp_compression")]
|
||||||
use crate::events::llmp::COMPRESS_THRESHOLD;
|
use crate::events::llmp::COMPRESS_THRESHOLD;
|
||||||
use crate::{
|
use crate::{
|
||||||
events::{llmp::LLMP_TAG_EVENT_TO_BOTH, BrokerEventResult, Event},
|
events::{llmp::LLMP_TAG_EVENT_TO_BOTH, BrokerEventResult, Event},
|
||||||
inputs::Input,
|
|
||||||
monitors::Monitor,
|
monitors::Monitor,
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
@ -42,9 +42,9 @@ pub struct StdLlmpEventHook<I, MT> {
|
|||||||
|
|
||||||
impl<I, MT, SP> LlmpHook<SP> for StdLlmpEventHook<I, MT>
|
impl<I, MT, SP> LlmpHook<SP> for StdLlmpEventHook<I, MT>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: DeserializeOwned,
|
||||||
MT: Monitor,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
|
MT: Monitor,
|
||||||
{
|
{
|
||||||
fn on_new_message(
|
fn on_new_message(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -90,7 +90,6 @@ where
|
|||||||
|
|
||||||
impl<I, MT> StdLlmpEventHook<I, MT>
|
impl<I, MT> StdLlmpEventHook<I, MT>
|
||||||
where
|
where
|
||||||
I: Input,
|
|
||||||
MT: Monitor,
|
MT: Monitor,
|
||||||
{
|
{
|
||||||
/// Create an event broker from a raw broker.
|
/// Create an event broker from a raw broker.
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
// 4. The "main broker", the gathers the stats from the fuzzer clients and broadcast the newly found testcases from the main evaluator.
|
// 4. The "main broker", the gathers the stats from the fuzzer clients and broadcast the newly found testcases from the main evaluator.
|
||||||
|
|
||||||
use alloc::{string::String, vec::Vec};
|
use alloc::{string::String, vec::Vec};
|
||||||
use core::{fmt::Debug, time::Duration};
|
use core::{fmt::Debug, marker::PhantomData, time::Duration};
|
||||||
use std::{marker::PhantomData, process};
|
use std::process;
|
||||||
|
|
||||||
#[cfg(feature = "llmp_compression")]
|
#[cfg(feature = "llmp_compression")]
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
@ -19,27 +19,30 @@ use libafl_bolts::{
|
|||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
llmp::{LlmpClient, LlmpClientDescription, Tag},
|
llmp::{LlmpClient, LlmpClientDescription, Tag},
|
||||||
shmem::{NopShMemProvider, ShMemProvider},
|
shmem::{NopShMemProvider, ShMemProvider},
|
||||||
tuples::Handle,
|
tuples::{Handle, MatchNameRef},
|
||||||
ClientId,
|
ClientId,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
|
|
||||||
use super::NopEventManager;
|
use super::{CanSerializeObserver, ManagerExit, NopEventManager};
|
||||||
#[cfg(feature = "llmp_compression")]
|
#[cfg(feature = "llmp_compression")]
|
||||||
use crate::events::llmp::COMPRESS_THRESHOLD;
|
use crate::events::llmp::COMPRESS_THRESHOLD;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
common::HasMetadata,
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
events::{
|
events::{
|
||||||
AdaptiveSerializer, Event, EventConfig, EventFirer, EventManager, EventManagerHooksTuple,
|
serialize_observers_adaptive, std_maybe_report_progress, std_report_progress,
|
||||||
EventManagerId, EventProcessor, EventRestarter, HasEventManagerId, LogSeverity,
|
AdaptiveSerializer, Event, EventConfig, EventFirer, EventManagerHooksTuple, EventManagerId,
|
||||||
ProgressReporter,
|
EventProcessor, EventRestarter, HasEventManagerId, LogSeverity, ProgressReporter,
|
||||||
},
|
},
|
||||||
executors::{Executor, HasObservers},
|
executors::HasObservers,
|
||||||
fuzzer::{EvaluatorObservers, ExecutionProcessor},
|
fuzzer::{EvaluatorObservers, ExecutionProcessor},
|
||||||
inputs::{Input, NopInput, UsesInput},
|
inputs::{Input, NopInput},
|
||||||
observers::{ObserversTuple, TimeObserver},
|
observers::TimeObserver,
|
||||||
state::{HasCorpus, HasExecutions, HasLastReportTime, NopState, State, Stoppable, UsesState},
|
state::{
|
||||||
Error, HasMetadata,
|
HasCorpus, HasExecutions, HasLastReportTime, MaybeHasClientPerfMonitor, NopState, Stoppable,
|
||||||
|
},
|
||||||
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) const _LLMP_TAG_TO_MAIN: Tag = Tag(0x3453453);
|
pub(crate) const _LLMP_TAG_TO_MAIN: Tag = Tag(0x3453453);
|
||||||
@ -48,9 +51,6 @@ pub(crate) const _LLMP_TAG_TO_MAIN: Tag = Tag(0x3453453);
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CentralizedEventManager<EM, EMH, S, SP>
|
pub struct CentralizedEventManager<EM, EMH, S, SP>
|
||||||
where
|
where
|
||||||
EM: UsesState<State = S>,
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
inner: EM,
|
inner: EM,
|
||||||
@ -64,14 +64,7 @@ where
|
|||||||
phantom: PhantomData<S>,
|
phantom: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl
|
impl CentralizedEventManager<NopEventManager, (), NopState<NopInput>, NopShMemProvider> {
|
||||||
CentralizedEventManager<
|
|
||||||
NopEventManager<NopState<NopInput>>,
|
|
||||||
(),
|
|
||||||
NopState<NopInput>,
|
|
||||||
NopShMemProvider,
|
|
||||||
>
|
|
||||||
{
|
|
||||||
/// Creates a builder for [`CentralizedEventManager`]
|
/// Creates a builder for [`CentralizedEventManager`]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn builder() -> CentralizedEventManagerBuilder {
|
pub fn builder() -> CentralizedEventManagerBuilder {
|
||||||
@ -113,9 +106,6 @@ impl CentralizedEventManagerBuilder {
|
|||||||
time_obs: Option<Handle<TimeObserver>>,
|
time_obs: Option<Handle<TimeObserver>>,
|
||||||
) -> Result<CentralizedEventManager<EM, EMH, S, SP>, Error>
|
) -> Result<CentralizedEventManager<EM, EMH, S, SP>, Error>
|
||||||
where
|
where
|
||||||
EM: UsesState<State = S>,
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
Ok(CentralizedEventManager {
|
Ok(CentralizedEventManager {
|
||||||
@ -143,22 +133,10 @@ impl CentralizedEventManagerBuilder {
|
|||||||
time_obs: Option<Handle<TimeObserver>>,
|
time_obs: Option<Handle<TimeObserver>>,
|
||||||
) -> Result<CentralizedEventManager<EM, EMH, S, SP>, Error>
|
) -> Result<CentralizedEventManager<EM, EMH, S, SP>, Error>
|
||||||
where
|
where
|
||||||
EM: UsesState<State = S>,
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
let client = LlmpClient::create_attach_to_tcp(shmem_provider, port)?;
|
let client = LlmpClient::create_attach_to_tcp(shmem_provider, port)?;
|
||||||
Ok(CentralizedEventManager {
|
Self::build_from_client(self, inner, hooks, client, time_obs)
|
||||||
inner,
|
|
||||||
hooks,
|
|
||||||
client,
|
|
||||||
#[cfg(feature = "llmp_compression")]
|
|
||||||
compressor: GzipCompressor::with_threshold(COMPRESS_THRESHOLD),
|
|
||||||
time_ref: time_obs,
|
|
||||||
is_main: self.is_main,
|
|
||||||
phantom: PhantomData,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If a client respawns, it may reuse the existing connection, previously
|
/// If a client respawns, it may reuse the existing connection, previously
|
||||||
@ -172,21 +150,10 @@ impl CentralizedEventManagerBuilder {
|
|||||||
time_obs: Option<Handle<TimeObserver>>,
|
time_obs: Option<Handle<TimeObserver>>,
|
||||||
) -> Result<CentralizedEventManager<EM, EMH, S, SP>, Error>
|
) -> Result<CentralizedEventManager<EM, EMH, S, SP>, Error>
|
||||||
where
|
where
|
||||||
EM: UsesState<State = S>,
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
Ok(CentralizedEventManager {
|
let client = LlmpClient::on_existing_from_env(shmem_provider, env_name)?;
|
||||||
inner,
|
Self::build_from_client(self, inner, hooks, client, time_obs)
|
||||||
hooks,
|
|
||||||
client: LlmpClient::on_existing_from_env(shmem_provider, env_name)?,
|
|
||||||
#[cfg(feature = "llmp_compression")]
|
|
||||||
compressor: GzipCompressor::with_threshold(COMPRESS_THRESHOLD),
|
|
||||||
time_ref: time_obs,
|
|
||||||
is_main: self.is_main,
|
|
||||||
phantom: PhantomData,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an existing client from description
|
/// Create an existing client from description
|
||||||
@ -199,38 +166,16 @@ impl CentralizedEventManagerBuilder {
|
|||||||
time_obs: Option<Handle<TimeObserver>>,
|
time_obs: Option<Handle<TimeObserver>>,
|
||||||
) -> Result<CentralizedEventManager<EM, EMH, S, SP>, Error>
|
) -> Result<CentralizedEventManager<EM, EMH, S, SP>, Error>
|
||||||
where
|
where
|
||||||
EM: UsesState<State = S>,
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
Ok(CentralizedEventManager {
|
let client = LlmpClient::existing_client_from_description(shmem_provider, description)?;
|
||||||
inner,
|
Self::build_from_client(self, inner, hooks, client, time_obs)
|
||||||
hooks,
|
|
||||||
client: LlmpClient::existing_client_from_description(shmem_provider, description)?,
|
|
||||||
#[cfg(feature = "llmp_compression")]
|
|
||||||
compressor: GzipCompressor::with_threshold(COMPRESS_THRESHOLD),
|
|
||||||
time_ref: time_obs,
|
|
||||||
is_main: self.is_main,
|
|
||||||
phantom: PhantomData,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<EM, EMH, S, SP> UsesState for CentralizedEventManager<EM, EMH, S, SP>
|
|
||||||
where
|
|
||||||
EM: UsesState<State = S>,
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
|
||||||
{
|
|
||||||
type State = EM::State;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<EM, EMH, S, SP> AdaptiveSerializer for CentralizedEventManager<EM, EMH, S, SP>
|
impl<EM, EMH, S, SP> AdaptiveSerializer for CentralizedEventManager<EM, EMH, S, SP>
|
||||||
where
|
where
|
||||||
EM: AdaptiveSerializer + UsesState<State = S>,
|
EM: AdaptiveSerializer,
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
fn serialization_time(&self) -> Duration {
|
fn serialization_time(&self) -> Duration {
|
||||||
@ -264,13 +209,14 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EM, EMH, S, SP> EventFirer for CentralizedEventManager<EM, EMH, S, SP>
|
impl<EM, EMH, S, SP> EventFirer<<S::Corpus as Corpus>::Input, S>
|
||||||
|
for CentralizedEventManager<EM, EMH, S, SP>
|
||||||
where
|
where
|
||||||
EM: AdaptiveSerializer + EventFirer<State = S> + HasEventManagerId,
|
EM: HasEventManagerId + EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
EMH: EventManagerHooksTuple<S>,
|
EMH: EventManagerHooksTuple<<<S as HasCorpus>::Corpus as Corpus>::Input, S>,
|
||||||
S: State + HasCorpus,
|
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
|
S: HasCorpus + Stoppable,
|
||||||
|
<<S as HasCorpus>::Corpus as Corpus>::Input: Input,
|
||||||
{
|
{
|
||||||
fn should_send(&self) -> bool {
|
fn should_send(&self) -> bool {
|
||||||
self.inner.should_send()
|
self.inner.should_send()
|
||||||
@ -279,8 +225,8 @@ where
|
|||||||
#[expect(clippy::match_same_arms)]
|
#[expect(clippy::match_same_arms)]
|
||||||
fn fire(
|
fn fire(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut Self::State,
|
state: &mut S,
|
||||||
mut event: Event<<Self::State as UsesInput>::Input>,
|
mut event: Event<<S::Corpus as Corpus>::Input>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
if !self.is_main {
|
if !self.is_main {
|
||||||
// secondary node
|
// secondary node
|
||||||
@ -312,45 +258,52 @@ where
|
|||||||
|
|
||||||
fn log(
|
fn log(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut Self::State,
|
state: &mut S,
|
||||||
severity_level: LogSeverity,
|
severity_level: LogSeverity,
|
||||||
message: String,
|
message: String,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
self.inner.log(state, severity_level, message)
|
self.inner.log(state, severity_level, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_observers<OT>(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error>
|
|
||||||
where
|
|
||||||
OT: ObserversTuple<Self::Input, Self::State> + Serialize,
|
|
||||||
{
|
|
||||||
const SERIALIZE_TIME_FACTOR: u32 = 4; // twice as much as the normal llmp em's value cuz it does this job twice.
|
|
||||||
const SERIALIZE_PERCENTAGE_THRESHOLD: usize = 80;
|
|
||||||
self.inner.serialize_observers_adaptive(
|
|
||||||
observers,
|
|
||||||
SERIALIZE_TIME_FACTOR,
|
|
||||||
SERIALIZE_PERCENTAGE_THRESHOLD,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn configuration(&self) -> EventConfig {
|
fn configuration(&self) -> EventConfig {
|
||||||
self.inner.configuration()
|
self.inner.configuration()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EM, EMH, S, SP> EventRestarter for CentralizedEventManager<EM, EMH, S, SP>
|
impl<EM, EMH, S, SP> EventRestarter<S> for CentralizedEventManager<EM, EMH, S, SP>
|
||||||
where
|
where
|
||||||
EM: EventRestarter<State = S>,
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
|
EM: EventRestarter<S>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn on_restart(&mut self, state: &mut Self::State) -> Result<(), Error> {
|
fn on_restart(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
self.client.await_safe_to_unmap_blocking();
|
self.client.await_safe_to_unmap_blocking();
|
||||||
self.inner.on_restart(state)?;
|
self.inner.on_restart(state)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<EM, EMH, OT, S, SP> CanSerializeObserver<OT> for CentralizedEventManager<EM, EMH, S, SP>
|
||||||
|
where
|
||||||
|
EM: AdaptiveSerializer,
|
||||||
|
SP: ShMemProvider,
|
||||||
|
OT: Serialize + MatchNameRef,
|
||||||
|
{
|
||||||
|
fn serialize_observers(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error> {
|
||||||
|
serialize_observers_adaptive::<EM, OT>(
|
||||||
|
&mut self.inner,
|
||||||
|
observers,
|
||||||
|
4, // twice as much as the normal llmp em's value cuz it does this job twice.
|
||||||
|
80,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<EM, EMH, S, SP> ManagerExit for CentralizedEventManager<EM, EMH, S, SP>
|
||||||
|
where
|
||||||
|
EM: ManagerExit,
|
||||||
|
SP: ShMemProvider,
|
||||||
|
{
|
||||||
fn send_exiting(&mut self) -> Result<(), Error> {
|
fn send_exiting(&mut self) -> Result<(), Error> {
|
||||||
self.client.sender_mut().send_exiting()?;
|
self.client.sender_mut().send_exiting()?;
|
||||||
self.inner.send_exiting()
|
self.inner.send_exiting()
|
||||||
@ -363,27 +316,19 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, EM, EMH, S, SP, Z> EventProcessor<E, Z> for CentralizedEventManager<EM, EMH, S, SP>
|
impl<E, EM, EMH, S, SP, Z> EventProcessor<E, S, Z> for CentralizedEventManager<EM, EMH, S, SP>
|
||||||
where
|
where
|
||||||
EM: AdaptiveSerializer + EventProcessor<E, Z> + EventFirer<State = S> + HasEventManagerId,
|
E: HasObservers,
|
||||||
EMH: EventManagerHooksTuple<S>,
|
E::Observers: DeserializeOwned,
|
||||||
E: HasObservers + Executor<Self, <S::Corpus as Corpus>::Input, S, Z>,
|
EM: EventProcessor<E, S, Z> + HasEventManagerId + EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
E::Observers:
|
EMH: EventManagerHooksTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State> + Serialize,
|
S: HasCorpus + Stoppable,
|
||||||
for<'a> E::Observers: Deserialize<'a>,
|
<S::Corpus as Corpus>::Input: Input,
|
||||||
S: State + HasCorpus,
|
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
|
||||||
Self::State: HasExecutions + HasMetadata,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
Z: EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>
|
Z: ExecutionProcessor<Self, <S::Corpus as Corpus>::Input, E::Observers, S>
|
||||||
+ ExecutionProcessor<Self, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
+ EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>,
|
||||||
{
|
{
|
||||||
fn process(
|
fn process(&mut self, fuzzer: &mut Z, state: &mut S, executor: &mut E) -> Result<usize, Error> {
|
||||||
&mut self,
|
|
||||||
fuzzer: &mut Z,
|
|
||||||
state: &mut Self::State,
|
|
||||||
executor: &mut E,
|
|
||||||
) -> Result<usize, Error> {
|
|
||||||
if self.is_main {
|
if self.is_main {
|
||||||
// main node
|
// main node
|
||||||
self.receive_from_secondary(fuzzer, state, executor)
|
self.receive_from_secondary(fuzzer, state, executor)
|
||||||
@ -400,40 +345,35 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, EM, EMH, S, SP, Z> EventManager<E, Z> for CentralizedEventManager<EM, EMH, S, SP>
|
impl<EM, EMH, S, SP> ProgressReporter<S> for CentralizedEventManager<EM, EMH, S, SP>
|
||||||
where
|
where
|
||||||
E: HasObservers + Executor<Self, <S::Corpus as Corpus>::Input, S, Z>,
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S> + HasEventManagerId,
|
||||||
E::Observers:
|
EMH: EventManagerHooksTuple<<<S as HasCorpus>::Corpus as Corpus>::Input, S>,
|
||||||
ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State> + Serialize,
|
S: HasExecutions
|
||||||
for<'a> E::Observers: Deserialize<'a>,
|
+ HasMetadata
|
||||||
EM: AdaptiveSerializer + EventManager<E, Z, State = S>,
|
+ HasLastReportTime
|
||||||
EM::State: HasExecutions + HasMetadata + HasLastReportTime,
|
+ Stoppable
|
||||||
EMH: EventManagerHooksTuple<S>,
|
+ HasCorpus
|
||||||
S: State + HasCorpus,
|
+ MaybeHasClientPerfMonitor,
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
<S::Corpus as Corpus>::Input: Input,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
Z: EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>
|
|
||||||
+ ExecutionProcessor<Self, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
|
||||||
{
|
{
|
||||||
}
|
fn maybe_report_progress(
|
||||||
|
&mut self,
|
||||||
|
state: &mut S,
|
||||||
|
monitor_timeout: Duration,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
std_maybe_report_progress(self, state, monitor_timeout)
|
||||||
|
}
|
||||||
|
|
||||||
impl<EM, EMH, S, SP> ProgressReporter for CentralizedEventManager<EM, EMH, S, SP>
|
fn report_progress(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
where
|
std_report_progress(self, state)
|
||||||
EM: AdaptiveSerializer + ProgressReporter<State = S> + HasEventManagerId,
|
}
|
||||||
EM::State: HasMetadata + HasExecutions + HasLastReportTime,
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State + HasCorpus,
|
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
|
||||||
SP: ShMemProvider,
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EM, EMH, S, SP> HasEventManagerId for CentralizedEventManager<EM, EMH, S, SP>
|
impl<EM, EMH, S, SP> HasEventManagerId for CentralizedEventManager<EM, EMH, S, SP>
|
||||||
where
|
where
|
||||||
EM: HasEventManagerId + UsesState<State = S>,
|
EM: HasEventManagerId,
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State + HasCorpus,
|
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
fn mgr_id(&self) -> EventManagerId {
|
fn mgr_id(&self) -> EventManagerId {
|
||||||
@ -443,10 +383,6 @@ where
|
|||||||
|
|
||||||
impl<EM, EMH, S, SP> CentralizedEventManager<EM, EMH, S, SP>
|
impl<EM, EMH, S, SP> CentralizedEventManager<EM, EMH, S, SP>
|
||||||
where
|
where
|
||||||
EM: UsesState<State = S>,
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State + HasCorpus,
|
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
/// Describe the client event manager's LLMP parts in a restorable fashion
|
/// Describe the client event manager's LLMP parts in a restorable fashion
|
||||||
@ -454,7 +390,7 @@ where
|
|||||||
self.client.describe()
|
self.client.describe()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write the config for a client [`EventManager`] to env vars, a new
|
/// Write the config for a client `EventManager` to env vars, a new
|
||||||
/// client can reattach using [`CentralizedEventManagerBuilder::build_existing_client_from_env()`].
|
/// client can reattach using [`CentralizedEventManagerBuilder::build_existing_client_from_env()`].
|
||||||
pub fn to_env(&self, env_name: &str) {
|
pub fn to_env(&self, env_name: &str) {
|
||||||
self.client.to_env(env_name).unwrap();
|
self.client.to_env(env_name).unwrap();
|
||||||
@ -468,10 +404,10 @@ where
|
|||||||
|
|
||||||
impl<EM, EMH, S, SP> CentralizedEventManager<EM, EMH, S, SP>
|
impl<EM, EMH, S, SP> CentralizedEventManager<EM, EMH, S, SP>
|
||||||
where
|
where
|
||||||
EM: UsesState<State = S> + EventFirer + AdaptiveSerializer + HasEventManagerId,
|
EM: HasEventManagerId + EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
EMH: EventManagerHooksTuple<S>,
|
EMH: EventManagerHooksTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
S: State + Stoppable + HasCorpus,
|
S: HasCorpus + Stoppable,
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
<S::Corpus as Corpus>::Input: Input,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
#[cfg(feature = "llmp_compression")]
|
#[cfg(feature = "llmp_compression")]
|
||||||
@ -510,17 +446,14 @@ where
|
|||||||
fn receive_from_secondary<E, Z>(
|
fn receive_from_secondary<E, Z>(
|
||||||
&mut self,
|
&mut self,
|
||||||
fuzzer: &mut Z,
|
fuzzer: &mut Z,
|
||||||
state: &mut <Self as UsesState>::State,
|
state: &mut S,
|
||||||
executor: &mut E,
|
executor: &mut E,
|
||||||
) -> Result<usize, Error>
|
) -> Result<usize, Error>
|
||||||
where
|
where
|
||||||
E: Executor<Self, <S::Corpus as Corpus>::Input, S, Z> + HasObservers,
|
E: HasObservers,
|
||||||
E::Observers:
|
E::Observers: DeserializeOwned,
|
||||||
ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State> + Serialize,
|
Z: ExecutionProcessor<Self, <S::Corpus as Corpus>::Input, E::Observers, S>
|
||||||
<Self as UsesState>::State: UsesInput + HasExecutions + HasMetadata,
|
+ EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>,
|
||||||
for<'a> E::Observers: Deserialize<'a>,
|
|
||||||
Z: EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>
|
|
||||||
+ ExecutionProcessor<Self, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
|
||||||
{
|
{
|
||||||
// TODO: Get around local event copy by moving handle_in_client
|
// TODO: Get around local event copy by moving handle_in_client
|
||||||
let self_id = self.client.sender().id();
|
let self_id = self.client.sender().id();
|
||||||
@ -545,8 +478,7 @@ where
|
|||||||
} else {
|
} else {
|
||||||
msg
|
msg
|
||||||
};
|
};
|
||||||
let event: Event<<<Self as UsesState>::State as UsesInput>::Input> =
|
let event: Event<<S::Corpus as Corpus>::Input> = postcard::from_bytes(event_bytes)?;
|
||||||
postcard::from_bytes(event_bytes)?;
|
|
||||||
log::debug!("Processor received message {}", event.name_detailed());
|
log::debug!("Processor received message {}", event.name_detailed());
|
||||||
self.handle_in_main(fuzzer, executor, state, client_id, event)?;
|
self.handle_in_main(fuzzer, executor, state, client_id, event)?;
|
||||||
count += 1;
|
count += 1;
|
||||||
@ -559,18 +491,15 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
fuzzer: &mut Z,
|
fuzzer: &mut Z,
|
||||||
executor: &mut E,
|
executor: &mut E,
|
||||||
state: &mut <Self as UsesState>::State,
|
state: &mut S,
|
||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
event: Event<<<Self as UsesState>::State as UsesInput>::Input>,
|
event: Event<<S::Corpus as Corpus>::Input>,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
E: Executor<Self, <S::Corpus as Corpus>::Input, S, Z> + HasObservers,
|
E: HasObservers,
|
||||||
E::Observers:
|
E::Observers: DeserializeOwned,
|
||||||
ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State> + Serialize,
|
Z: ExecutionProcessor<Self, <S::Corpus as Corpus>::Input, E::Observers, S>
|
||||||
<Self as UsesState>::State: UsesInput + HasExecutions + HasMetadata,
|
+ EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>,
|
||||||
for<'a> E::Observers: Deserialize<'a> + Serialize,
|
|
||||||
Z: EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>
|
|
||||||
+ ExecutionProcessor<Self, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
|
||||||
{
|
{
|
||||||
log::debug!("handle_in_main!");
|
log::debug!("handle_in_main!");
|
||||||
|
|
||||||
@ -597,10 +526,6 @@ where
|
|||||||
if client_config.match_with(&self.configuration()) && observers_buf.is_some() {
|
if client_config.match_with(&self.configuration()) && observers_buf.is_some() {
|
||||||
let observers: E::Observers =
|
let observers: E::Observers =
|
||||||
postcard::from_bytes(observers_buf.as_ref().unwrap())?;
|
postcard::from_bytes(observers_buf.as_ref().unwrap())?;
|
||||||
#[cfg(feature = "scalability_introspection")]
|
|
||||||
{
|
|
||||||
state.scalability_monitor_mut().testcase_with_observers += 1;
|
|
||||||
}
|
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"[{}] Running fuzzer with event {}",
|
"[{}] Running fuzzer with event {}",
|
||||||
process::id(),
|
process::id(),
|
||||||
@ -615,10 +540,6 @@ where
|
|||||||
false,
|
false,
|
||||||
)?
|
)?
|
||||||
} else {
|
} else {
|
||||||
#[cfg(feature = "scalability_introspection")]
|
|
||||||
{
|
|
||||||
state.scalability_monitor_mut().testcase_without_observers += 1;
|
|
||||||
}
|
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"[{}] Running fuzzer with event {}",
|
"[{}] Running fuzzer with event {}",
|
||||||
process::id(),
|
process::id(),
|
||||||
|
@ -4,20 +4,17 @@
|
|||||||
//! other clients
|
//! other clients
|
||||||
use libafl_bolts::ClientId;
|
use libafl_bolts::ClientId;
|
||||||
|
|
||||||
use crate::{events::Event, state::State, Error};
|
use crate::{events::Event, Error};
|
||||||
|
|
||||||
/// The `broker_hooks` that are run before and after the event manager calls `handle_in_client`
|
/// The `broker_hooks` that are run before and after the event manager calls `handle_in_client`
|
||||||
pub trait EventManagerHook<S>
|
pub trait EventManagerHook<I, S> {
|
||||||
where
|
|
||||||
S: State,
|
|
||||||
{
|
|
||||||
/// The hook that runs before `handle_in_client`
|
/// The hook that runs before `handle_in_client`
|
||||||
/// Return false if you want to cancel the subsequent event handling
|
/// Return false if you want to cancel the subsequent event handling
|
||||||
fn pre_exec(
|
fn pre_exec(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
event: &Event<S::Input>,
|
event: &Event<I>,
|
||||||
) -> Result<bool, Error>;
|
) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Triggered when the even manager decides to fire the event after processing
|
/// Triggered when the even manager decides to fire the event after processing
|
||||||
@ -25,7 +22,7 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
_state: &mut S,
|
_state: &mut S,
|
||||||
_client_id: ClientId,
|
_client_id: ClientId,
|
||||||
_event: &Event<S::Input>,
|
_event: &Event<I>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -38,16 +35,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The tuples contains `broker_hooks` to be executed for `handle_in_client`
|
/// The tuples contains `broker_hooks` to be executed for `handle_in_client`
|
||||||
pub trait EventManagerHooksTuple<S>
|
pub trait EventManagerHooksTuple<I, S> {
|
||||||
where
|
|
||||||
S: State,
|
|
||||||
{
|
|
||||||
/// The hook that runs before `handle_in_client`
|
/// The hook that runs before `handle_in_client`
|
||||||
fn pre_exec_all(
|
fn pre_exec_all(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
event: &Event<S::Input>,
|
event: &Event<I>,
|
||||||
) -> Result<bool, Error>;
|
) -> Result<bool, Error>;
|
||||||
|
|
||||||
/// Ran when the Event Manager decides to accept an event and propagates it
|
/// Ran when the Event Manager decides to accept an event and propagates it
|
||||||
@ -55,23 +49,20 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
event: &Event<S::Input>,
|
event: &Event<I>,
|
||||||
) -> Result<(), Error>;
|
) -> Result<(), Error>;
|
||||||
|
|
||||||
/// The hook that runs after `handle_in_client`
|
/// The hook that runs after `handle_in_client`
|
||||||
fn post_exec_all(&mut self, state: &mut S, client_id: ClientId) -> Result<bool, Error>;
|
fn post_exec_all(&mut self, state: &mut S, client_id: ClientId) -> Result<bool, Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> EventManagerHooksTuple<S> for ()
|
impl<I, S> EventManagerHooksTuple<I, S> for () {
|
||||||
where
|
|
||||||
S: State,
|
|
||||||
{
|
|
||||||
/// The hook that runs before `handle_in_client`
|
/// The hook that runs before `handle_in_client`
|
||||||
fn pre_exec_all(
|
fn pre_exec_all(
|
||||||
&mut self,
|
&mut self,
|
||||||
_state: &mut S,
|
_state: &mut S,
|
||||||
_client_id: ClientId,
|
_client_id: ClientId,
|
||||||
_event: &Event<S::Input>,
|
_event: &Event<I>,
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
@ -80,7 +71,7 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
_state: &mut S,
|
_state: &mut S,
|
||||||
_client_id: ClientId,
|
_client_id: ClientId,
|
||||||
_event: &Event<S::Input>,
|
_event: &Event<I>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -91,18 +82,17 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Head, Tail, S> EventManagerHooksTuple<S> for (Head, Tail)
|
impl<Head, Tail, I, S> EventManagerHooksTuple<I, S> for (Head, Tail)
|
||||||
where
|
where
|
||||||
Head: EventManagerHook<S>,
|
Head: EventManagerHook<I, S>,
|
||||||
Tail: EventManagerHooksTuple<S>,
|
Tail: EventManagerHooksTuple<I, S>,
|
||||||
S: State,
|
|
||||||
{
|
{
|
||||||
/// The hook that runs before `handle_in_client`
|
/// The hook that runs before `handle_in_client`
|
||||||
fn pre_exec_all(
|
fn pre_exec_all(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
event: &Event<S::Input>,
|
event: &Event<I>,
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
let first = self.0.pre_exec(state, client_id, event)?;
|
let first = self.0.pre_exec(state, client_id, event)?;
|
||||||
let second = self.1.pre_exec_all(state, client_id, event)?;
|
let second = self.1.pre_exec_all(state, client_id, event)?;
|
||||||
@ -113,7 +103,7 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
event: &Event<S::Input>,
|
event: &Event<I>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
self.0.on_fire(state, client_id, event)?;
|
self.0.on_fire(state, client_id, event)?;
|
||||||
self.1.on_fire_all(state, client_id, event)
|
self.1.on_fire_all(state, client_id, event)
|
||||||
|
@ -24,14 +24,13 @@ use libafl_bolts::{
|
|||||||
shmem::ShMemProvider,
|
shmem::ShMemProvider,
|
||||||
tuples::{tuple_list, Handle},
|
tuples::{tuple_list, Handle},
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
use typed_builder::TypedBuilder;
|
use typed_builder::TypedBuilder;
|
||||||
#[cfg(all(unix, feature = "fork"))]
|
#[cfg(all(unix, feature = "fork"))]
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
events::{centralized::CentralizedEventManager, CentralizedLlmpHook, StdLlmpEventHook},
|
events::{centralized::CentralizedEventManager, CentralizedLlmpHook, StdLlmpEventHook},
|
||||||
inputs::UsesInput,
|
inputs::Input,
|
||||||
state::UsesState,
|
|
||||||
},
|
},
|
||||||
alloc::string::ToString,
|
alloc::string::ToString,
|
||||||
libafl_bolts::{
|
libafl_bolts::{
|
||||||
@ -52,13 +51,14 @@ use {libafl_bolts::os::startable_self, std::process::Stdio};
|
|||||||
#[cfg(all(unix, feature = "fork", feature = "multi_machine"))]
|
#[cfg(all(unix, feature = "fork", feature = "multi_machine"))]
|
||||||
use crate::events::multi_machine::{NodeDescriptor, TcpMultiMachineHooks};
|
use crate::events::multi_machine::{NodeDescriptor, TcpMultiMachineHooks};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
corpus::Corpus,
|
||||||
events::{
|
events::{
|
||||||
llmp::{LlmpRestartingEventManager, LlmpShouldSaveState, ManagerKind, RestartingMgr},
|
llmp::{LlmpRestartingEventManager, LlmpShouldSaveState, ManagerKind, RestartingMgr},
|
||||||
EventConfig, EventManagerHooksTuple,
|
EventConfig, EventManagerHooksTuple,
|
||||||
},
|
},
|
||||||
monitors::Monitor,
|
monitors::Monitor,
|
||||||
observers::TimeObserver,
|
observers::TimeObserver,
|
||||||
state::{HasExecutions, State},
|
state::HasCorpus,
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -216,7 +216,8 @@ where
|
|||||||
#[cfg(any(windows, not(feature = "fork"), all(unix, feature = "fork")))]
|
#[cfg(any(windows, not(feature = "fork"), all(unix, feature = "fork")))]
|
||||||
pub fn launch<S>(&mut self) -> Result<(), Error>
|
pub fn launch<S>(&mut self) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
S: State + HasExecutions,
|
S: DeserializeOwned + HasCorpus + Serialize,
|
||||||
|
<S::Corpus as Corpus>::Input: DeserializeOwned,
|
||||||
CF: FnOnce(
|
CF: FnOnce(
|
||||||
Option<S>,
|
Option<S>,
|
||||||
LlmpRestartingEventManager<(), S, SP>,
|
LlmpRestartingEventManager<(), S, SP>,
|
||||||
@ -236,8 +237,9 @@ where
|
|||||||
#[cfg(all(unix, feature = "fork"))]
|
#[cfg(all(unix, feature = "fork"))]
|
||||||
pub fn launch_with_hooks<EMH, S>(&mut self, hooks: EMH) -> Result<(), Error>
|
pub fn launch_with_hooks<EMH, S>(&mut self, hooks: EMH) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
S: State + HasExecutions,
|
S: DeserializeOwned + HasCorpus + Serialize,
|
||||||
EMH: EventManagerHooksTuple<S> + Clone + Copy,
|
<S::Corpus as Corpus>::Input: DeserializeOwned,
|
||||||
|
EMH: EventManagerHooksTuple<<S::Corpus as Corpus>::Input, S> + Clone + Copy,
|
||||||
CF: FnOnce(
|
CF: FnOnce(
|
||||||
Option<S>,
|
Option<S>,
|
||||||
LlmpRestartingEventManager<EMH, S, SP>,
|
LlmpRestartingEventManager<EMH, S, SP>,
|
||||||
@ -383,8 +385,9 @@ where
|
|||||||
#[expect(clippy::too_many_lines, clippy::match_wild_err_arm)]
|
#[expect(clippy::too_many_lines, clippy::match_wild_err_arm)]
|
||||||
pub fn launch_with_hooks<EMH, S>(&mut self, hooks: EMH) -> Result<(), Error>
|
pub fn launch_with_hooks<EMH, S>(&mut self, hooks: EMH) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
S: State + HasExecutions,
|
S: DeserializeOwned + HasCorpus + Serialize,
|
||||||
EMH: EventManagerHooksTuple<S> + Clone + Copy,
|
<S::Corpus as Corpus>::Input: DeserializeOwned,
|
||||||
|
EMH: EventManagerHooksTuple<<S::Corpus as Corpus>::Input, S> + Clone + Copy,
|
||||||
CF: FnOnce(
|
CF: FnOnce(
|
||||||
Option<S>,
|
Option<S>,
|
||||||
LlmpRestartingEventManager<EMH, S, SP>,
|
LlmpRestartingEventManager<EMH, S, SP>,
|
||||||
@ -547,9 +550,6 @@ pub struct CentralizedLauncher<'a, CF, MF, MT, SP> {
|
|||||||
monitor: MT,
|
monitor: MT,
|
||||||
/// The configuration
|
/// The configuration
|
||||||
configuration: EventConfig,
|
configuration: EventConfig,
|
||||||
/// Consider this testcase as interesting always if true
|
|
||||||
#[builder(default = false)]
|
|
||||||
always_interesting: bool,
|
|
||||||
/// The 'main' function to run for each secondary client forked. This probably shouldn't return
|
/// The 'main' function to run for each secondary client forked. This probably shouldn't return
|
||||||
#[builder(default, setter(strip_option))]
|
#[builder(default, setter(strip_option))]
|
||||||
secondary_run_client: Option<CF>,
|
secondary_run_client: Option<CF>,
|
||||||
@ -633,8 +633,8 @@ where
|
|||||||
/// Launch a standard Centralized-based fuzzer
|
/// Launch a standard Centralized-based fuzzer
|
||||||
pub fn launch<S>(&mut self) -> Result<(), Error>
|
pub fn launch<S>(&mut self) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
S: State,
|
S: DeserializeOwned + HasCorpus + Serialize,
|
||||||
S::Input: Send + Sync + 'static,
|
<S::Corpus as Corpus>::Input: DeserializeOwned + Input + Send + Sync + 'static,
|
||||||
CF: FnOnce(
|
CF: FnOnce(
|
||||||
Option<S>,
|
Option<S>,
|
||||||
CentralizedEventManager<StdCentralizedInnerMgr<S, SP>, (), S, SP>,
|
CentralizedEventManager<StdCentralizedInnerMgr<S, SP>, (), S, SP>,
|
||||||
@ -650,7 +650,6 @@ where
|
|||||||
|centralized_launcher: &Self, client_description: ClientDescription| {
|
|centralized_launcher: &Self, client_description: ClientDescription| {
|
||||||
// Fuzzer client. keeps retrying the connection to broker till the broker starts
|
// Fuzzer client. keeps retrying the connection to broker till the broker starts
|
||||||
let builder = RestartingMgr::<(), MT, S, SP>::builder()
|
let builder = RestartingMgr::<(), MT, S, SP>::builder()
|
||||||
.always_interesting(centralized_launcher.always_interesting)
|
|
||||||
.shmem_provider(centralized_launcher.shmem_provider.clone())
|
.shmem_provider(centralized_launcher.shmem_provider.clone())
|
||||||
.broker_port(centralized_launcher.broker_port)
|
.broker_port(centralized_launcher.broker_port)
|
||||||
.kind(ManagerKind::Client { client_description })
|
.kind(ManagerKind::Client { client_description })
|
||||||
@ -682,21 +681,19 @@ where
|
|||||||
secondary_inner_mgr_builder: EMB,
|
secondary_inner_mgr_builder: EMB,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
S: State,
|
S: HasCorpus,
|
||||||
S::Input: Send + Sync + 'static,
|
<S::Corpus as Corpus>::Input: Input + Send + Sync + 'static,
|
||||||
CF: FnOnce(
|
CF: FnOnce(
|
||||||
Option<S>,
|
Option<S>,
|
||||||
CentralizedEventManager<EM, (), S, SP>,
|
CentralizedEventManager<EM, (), S, SP>,
|
||||||
ClientDescription,
|
ClientDescription,
|
||||||
) -> Result<(), Error>,
|
) -> Result<(), Error>,
|
||||||
EM: UsesState<State = S>,
|
|
||||||
EMB: FnOnce(&Self, ClientDescription) -> Result<(Option<S>, EM), Error>,
|
EMB: FnOnce(&Self, ClientDescription) -> Result<(Option<S>, EM), Error>,
|
||||||
MF: FnOnce(
|
MF: FnOnce(
|
||||||
Option<S>,
|
Option<S>,
|
||||||
CentralizedEventManager<EM, (), S, SP>, // No broker_hooks for centralized EM
|
CentralizedEventManager<EM, (), S, SP>, // No broker_hooks for centralized EM
|
||||||
ClientDescription,
|
ClientDescription,
|
||||||
) -> Result<(), Error>,
|
) -> Result<(), Error>,
|
||||||
<<EM as UsesState>::State as UsesInput>::Input: Send + Sync + 'static,
|
|
||||||
{
|
{
|
||||||
let mut main_inner_mgr_builder = Some(main_inner_mgr_builder);
|
let mut main_inner_mgr_builder = Some(main_inner_mgr_builder);
|
||||||
let mut secondary_inner_mgr_builder = Some(secondary_inner_mgr_builder);
|
let mut secondary_inner_mgr_builder = Some(secondary_inner_mgr_builder);
|
||||||
@ -838,7 +835,7 @@ where
|
|||||||
} = unsafe {
|
} = unsafe {
|
||||||
TcpMultiMachineHooks::builder()
|
TcpMultiMachineHooks::builder()
|
||||||
.node_descriptor(self.multi_machine_node_descriptor.clone())
|
.node_descriptor(self.multi_machine_node_descriptor.clone())
|
||||||
.build::<<<EM as UsesState>::State as UsesInput>::Input>()?
|
.build::<<S::Corpus as Corpus>::Input>()?
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut brokers = Brokers::new();
|
let mut brokers = Brokers::new();
|
||||||
@ -848,12 +845,13 @@ where
|
|||||||
brokers.add(Box::new({
|
brokers.add(Box::new({
|
||||||
#[cfg(feature = "multi_machine")]
|
#[cfg(feature = "multi_machine")]
|
||||||
let centralized_hooks = tuple_list!(
|
let centralized_hooks = tuple_list!(
|
||||||
CentralizedLlmpHook::<S::Input>::new()?,
|
CentralizedLlmpHook::<<S::Corpus as Corpus>::Input>::new()?,
|
||||||
multi_machine_receiver_hook,
|
multi_machine_receiver_hook,
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(not(feature = "multi_machine"))]
|
#[cfg(not(feature = "multi_machine"))]
|
||||||
let centralized_hooks = tuple_list!(CentralizedLlmpHook::<S::Input>::new()?);
|
let centralized_hooks =
|
||||||
|
tuple_list!(CentralizedLlmpHook::<<S::Corpus as Corpus>::Input>::new()?);
|
||||||
|
|
||||||
// TODO switch to false after solving the bug
|
// TODO switch to false after solving the bug
|
||||||
let mut broker = LlmpBroker::with_keep_pages_attach_to_tcp(
|
let mut broker = LlmpBroker::with_keep_pages_attach_to_tcp(
|
||||||
@ -877,12 +875,13 @@ where
|
|||||||
log::info!("I am broker!!.");
|
log::info!("I am broker!!.");
|
||||||
|
|
||||||
#[cfg(not(feature = "multi_machine"))]
|
#[cfg(not(feature = "multi_machine"))]
|
||||||
let llmp_hook =
|
let llmp_hook = tuple_list!(StdLlmpEventHook::<<S::Corpus as Corpus>::Input, MT>::new(
|
||||||
tuple_list!(StdLlmpEventHook::<S::Input, MT>::new(self.monitor.clone())?);
|
self.monitor.clone()
|
||||||
|
)?);
|
||||||
|
|
||||||
#[cfg(feature = "multi_machine")]
|
#[cfg(feature = "multi_machine")]
|
||||||
let llmp_hook = tuple_list!(
|
let llmp_hook = tuple_list!(
|
||||||
StdLlmpEventHook::<S::Input, MT>::new(self.monitor.clone())?,
|
StdLlmpEventHook::<<S::Corpus as Corpus>::Input, MT>::new(self.monitor.clone())?,
|
||||||
multi_machine_sender_hook,
|
multi_machine_sender_hook,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//! An [`crate::events::EventManager`] that forwards all events to other attached fuzzers on shared maps or via tcp,
|
//! An event manager that forwards all events to other attached fuzzers on shared maps or via tcp,
|
||||||
//! using low-level message passing, [`libafl_bolts::llmp`].
|
//! using low-level message passing, [`libafl_bolts::llmp`].
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -8,6 +8,8 @@ use core::{marker::PhantomData, time::Duration};
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use libafl_bolts::tuples::MatchNameRef;
|
||||||
#[cfg(feature = "llmp_compression")]
|
#[cfg(feature = "llmp_compression")]
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
compress::GzipCompressor,
|
compress::GzipCompressor,
|
||||||
@ -25,39 +27,43 @@ use libafl_bolts::{
|
|||||||
llmp::{recv_tcp_msg, send_tcp_msg, TcpRequest, TcpResponse},
|
llmp::{recv_tcp_msg, send_tcp_msg, TcpRequest, TcpResponse},
|
||||||
IP_LOCALHOST,
|
IP_LOCALHOST,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
|
|
||||||
#[cfg(feature = "llmp_compression")]
|
#[cfg(feature = "llmp_compression")]
|
||||||
use crate::events::llmp::COMPRESS_THRESHOLD;
|
use crate::events::llmp::COMPRESS_THRESHOLD;
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use crate::events::{serialize_observers_adaptive, CanSerializeObserver};
|
||||||
use crate::{
|
use crate::{
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
events::{
|
events::{
|
||||||
llmp::{LLMP_TAG_EVENT_TO_BOTH, _LLMP_TAG_EVENT_TO_BROKER},
|
llmp::{LLMP_TAG_EVENT_TO_BOTH, _LLMP_TAG_EVENT_TO_BROKER},
|
||||||
AdaptiveSerializer, Event, EventConfig, EventFirer, EventManager, EventManagerHooksTuple,
|
std_maybe_report_progress, std_on_restart, std_report_progress, AdaptiveSerializer, Event,
|
||||||
EventManagerId, EventProcessor, EventRestarter, HasEventManagerId, ProgressReporter,
|
EventConfig, EventFirer, EventManagerHooksTuple, EventManagerId, EventProcessor,
|
||||||
|
EventRestarter, HasEventManagerId, ManagerExit, ProgressReporter,
|
||||||
|
},
|
||||||
|
executors::HasObservers,
|
||||||
|
fuzzer::{EvaluatorObservers, ExecutionProcessor},
|
||||||
|
inputs::{Input, NopInput},
|
||||||
|
observers::TimeObserver,
|
||||||
|
stages::HasCurrentStageId,
|
||||||
|
state::{
|
||||||
|
HasCorpus, HasExecutions, HasImported, HasLastReportTime, MaybeHasClientPerfMonitor,
|
||||||
|
NopState, Stoppable,
|
||||||
},
|
},
|
||||||
executors::{Executor, HasObservers},
|
|
||||||
fuzzer::{Evaluator, EvaluatorObservers, ExecutionProcessor},
|
|
||||||
inputs::{NopInput, UsesInput},
|
|
||||||
observers::{ObserversTuple, TimeObserver},
|
|
||||||
state::{HasCorpus, HasExecutions, HasImported, HasLastReportTime, NopState, State, UsesState},
|
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Default initial capacity of the event buffer - 4KB
|
/// Default initial capacity of the event buffer - 4KB
|
||||||
const INITIAL_EVENT_BUFFER_SIZE: usize = 1024 * 4;
|
const INITIAL_EVENT_BUFFER_SIZE: usize = 1024 * 4;
|
||||||
|
|
||||||
/// An [`EventManager`] that forwards all events to other attached fuzzers on shared maps or via tcp,
|
/// An `EventManager` that forwards all events to other attached fuzzers on shared maps or via tcp,
|
||||||
/// using low-level message passing, `llmp`.
|
/// using low-level message passing, `llmp`.
|
||||||
pub struct LlmpEventManager<EMH, S, SP>
|
pub struct LlmpEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
/// We only send 1 testcase for every `throttle` second
|
/// We only send 1 testcase for every `throttle` second
|
||||||
pub(crate) throttle: Option<Duration>,
|
pub(crate) throttle: Option<Duration>,
|
||||||
/// Treat the incoming testcase as interesting always without evaluating them
|
|
||||||
always_interesting: bool,
|
|
||||||
/// We sent last message at `last_sent`
|
/// We sent last message at `last_sent`
|
||||||
last_sent: Duration,
|
last_sent: Duration,
|
||||||
hooks: EMH,
|
hooks: EMH,
|
||||||
@ -91,7 +97,6 @@ impl LlmpEventManager<(), NopState<NopInput>, NopShMemProvider> {
|
|||||||
pub struct LlmpEventManagerBuilder<EMH> {
|
pub struct LlmpEventManagerBuilder<EMH> {
|
||||||
throttle: Option<Duration>,
|
throttle: Option<Duration>,
|
||||||
hooks: EMH,
|
hooks: EMH,
|
||||||
always_interesting: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for LlmpEventManagerBuilder<()> {
|
impl Default for LlmpEventManagerBuilder<()> {
|
||||||
@ -107,7 +112,6 @@ impl LlmpEventManagerBuilder<()> {
|
|||||||
Self {
|
Self {
|
||||||
throttle: None,
|
throttle: None,
|
||||||
hooks: (),
|
hooks: (),
|
||||||
always_interesting: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,17 +120,6 @@ impl LlmpEventManagerBuilder<()> {
|
|||||||
LlmpEventManagerBuilder {
|
LlmpEventManagerBuilder {
|
||||||
throttle: self.throttle,
|
throttle: self.throttle,
|
||||||
hooks,
|
hooks,
|
||||||
always_interesting: self.always_interesting,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set `always_interesting`
|
|
||||||
#[must_use]
|
|
||||||
pub fn always_interesting(self, always_interesting: bool) -> LlmpEventManagerBuilder<()> {
|
|
||||||
LlmpEventManagerBuilder {
|
|
||||||
throttle: self.throttle,
|
|
||||||
hooks: self.hooks,
|
|
||||||
always_interesting,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,13 +141,11 @@ impl<EMH> LlmpEventManagerBuilder<EMH> {
|
|||||||
) -> Result<LlmpEventManager<EMH, S, SP>, Error>
|
) -> Result<LlmpEventManager<EMH, S, SP>, Error>
|
||||||
where
|
where
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
S: State,
|
|
||||||
{
|
{
|
||||||
Ok(LlmpEventManager {
|
Ok(LlmpEventManager {
|
||||||
throttle: self.throttle,
|
throttle: self.throttle,
|
||||||
last_sent: Duration::from_secs(0),
|
last_sent: Duration::from_secs(0),
|
||||||
hooks: self.hooks,
|
hooks: self.hooks,
|
||||||
always_interesting: self.always_interesting,
|
|
||||||
llmp,
|
llmp,
|
||||||
#[cfg(feature = "llmp_compression")]
|
#[cfg(feature = "llmp_compression")]
|
||||||
compressor: GzipCompressor::with_threshold(COMPRESS_THRESHOLD),
|
compressor: GzipCompressor::with_threshold(COMPRESS_THRESHOLD),
|
||||||
@ -181,26 +172,9 @@ impl<EMH> LlmpEventManagerBuilder<EMH> {
|
|||||||
) -> Result<LlmpEventManager<EMH, S, SP>, Error>
|
) -> Result<LlmpEventManager<EMH, S, SP>, Error>
|
||||||
where
|
where
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
S: State,
|
|
||||||
{
|
{
|
||||||
let llmp = LlmpClient::create_attach_to_tcp(shmem_provider, port)?;
|
let llmp = LlmpClient::create_attach_to_tcp(shmem_provider, port)?;
|
||||||
Ok(LlmpEventManager {
|
Self::build_from_client(self, llmp, configuration, time_ref)
|
||||||
throttle: self.throttle,
|
|
||||||
last_sent: Duration::from_secs(0),
|
|
||||||
hooks: self.hooks,
|
|
||||||
always_interesting: self.always_interesting,
|
|
||||||
llmp,
|
|
||||||
#[cfg(feature = "llmp_compression")]
|
|
||||||
compressor: GzipCompressor::with_threshold(COMPRESS_THRESHOLD),
|
|
||||||
configuration,
|
|
||||||
serialization_time: Duration::ZERO,
|
|
||||||
deserialization_time: Duration::ZERO,
|
|
||||||
serializations_cnt: 0,
|
|
||||||
should_serialize_cnt: 0,
|
|
||||||
time_ref,
|
|
||||||
phantom: PhantomData,
|
|
||||||
event_buffer: Vec::with_capacity(INITIAL_EVENT_BUFFER_SIZE),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If a client respawns, it may reuse the existing connection, previously
|
/// If a client respawns, it may reuse the existing connection, previously
|
||||||
@ -215,26 +189,9 @@ impl<EMH> LlmpEventManagerBuilder<EMH> {
|
|||||||
) -> Result<LlmpEventManager<EMH, S, SP>, Error>
|
) -> Result<LlmpEventManager<EMH, S, SP>, Error>
|
||||||
where
|
where
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
S: State,
|
|
||||||
{
|
{
|
||||||
let llmp = LlmpClient::on_existing_from_env(shmem_provider, env_name)?;
|
let llmp = LlmpClient::on_existing_from_env(shmem_provider, env_name)?;
|
||||||
Ok(LlmpEventManager {
|
Self::build_from_client(self, llmp, configuration, time_ref)
|
||||||
throttle: self.throttle,
|
|
||||||
last_sent: Duration::from_secs(0),
|
|
||||||
hooks: self.hooks,
|
|
||||||
always_interesting: self.always_interesting,
|
|
||||||
llmp,
|
|
||||||
#[cfg(feature = "llmp_compression")]
|
|
||||||
compressor: GzipCompressor::with_threshold(COMPRESS_THRESHOLD),
|
|
||||||
configuration,
|
|
||||||
serialization_time: Duration::ZERO,
|
|
||||||
deserialization_time: Duration::ZERO,
|
|
||||||
serializations_cnt: 0,
|
|
||||||
should_serialize_cnt: 0,
|
|
||||||
time_ref,
|
|
||||||
phantom: PhantomData,
|
|
||||||
event_buffer: Vec::with_capacity(INITIAL_EVENT_BUFFER_SIZE),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an existing client from description
|
/// Create an existing client from description
|
||||||
@ -247,33 +204,26 @@ impl<EMH> LlmpEventManagerBuilder<EMH> {
|
|||||||
) -> Result<LlmpEventManager<EMH, S, SP>, Error>
|
) -> Result<LlmpEventManager<EMH, S, SP>, Error>
|
||||||
where
|
where
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
S: State,
|
|
||||||
{
|
{
|
||||||
let llmp = LlmpClient::existing_client_from_description(shmem_provider, description)?;
|
let llmp = LlmpClient::existing_client_from_description(shmem_provider, description)?;
|
||||||
Ok(LlmpEventManager {
|
Self::build_from_client(self, llmp, configuration, time_ref)
|
||||||
throttle: self.throttle,
|
}
|
||||||
last_sent: Duration::from_secs(0),
|
}
|
||||||
hooks: self.hooks,
|
|
||||||
always_interesting: self.always_interesting,
|
#[cfg(feature = "std")]
|
||||||
llmp,
|
impl<EMH, OT, S, SP> CanSerializeObserver<OT> for LlmpEventManager<EMH, S, SP>
|
||||||
#[cfg(feature = "llmp_compression")]
|
where
|
||||||
compressor: GzipCompressor::with_threshold(COMPRESS_THRESHOLD),
|
SP: ShMemProvider,
|
||||||
configuration,
|
OT: Serialize + MatchNameRef,
|
||||||
serialization_time: Duration::ZERO,
|
{
|
||||||
deserialization_time: Duration::ZERO,
|
fn serialize_observers(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error> {
|
||||||
serializations_cnt: 0,
|
serialize_observers_adaptive::<Self, OT>(self, observers, 2, 80)
|
||||||
should_serialize_cnt: 0,
|
|
||||||
time_ref,
|
|
||||||
phantom: PhantomData,
|
|
||||||
event_buffer: Vec::with_capacity(INITIAL_EVENT_BUFFER_SIZE),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EMH, S, SP> AdaptiveSerializer for LlmpEventManager<EMH, S, SP>
|
impl<EMH, S, SP> AdaptiveSerializer for LlmpEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
S: State,
|
|
||||||
{
|
{
|
||||||
fn serialization_time(&self) -> Duration {
|
fn serialization_time(&self) -> Duration {
|
||||||
self.serialization_time
|
self.serialization_time
|
||||||
@ -309,7 +259,6 @@ where
|
|||||||
impl<EMH, S, SP> core::fmt::Debug for LlmpEventManager<EMH, S, SP>
|
impl<EMH, S, SP> core::fmt::Debug for LlmpEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
S: State,
|
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
let mut debug_struct = f.debug_struct("LlmpEventManager");
|
let mut debug_struct = f.debug_struct("LlmpEventManager");
|
||||||
@ -327,7 +276,6 @@ where
|
|||||||
impl<EMH, S, SP> Drop for LlmpEventManager<EMH, S, SP>
|
impl<EMH, S, SP> Drop for LlmpEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
S: State,
|
|
||||||
{
|
{
|
||||||
/// LLMP clients will have to wait until their pages are mapped by somebody.
|
/// LLMP clients will have to wait until their pages are mapped by somebody.
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
@ -337,7 +285,6 @@ where
|
|||||||
|
|
||||||
impl<EMH, S, SP> LlmpEventManager<EMH, S, SP>
|
impl<EMH, S, SP> LlmpEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
/// Calling this function will tell the llmp broker that this client is exiting
|
/// Calling this function will tell the llmp broker that this client is exiting
|
||||||
@ -378,7 +325,7 @@ where
|
|||||||
self.llmp.describe()
|
self.llmp.describe()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write the config for a client [`EventManager`] to env vars, a new
|
/// Write the config for a client `EventManager` to env vars, a new
|
||||||
/// client can reattach using [`LlmpEventManagerBuilder::build_existing_client_from_env()`].
|
/// client can reattach using [`LlmpEventManagerBuilder::build_existing_client_from_env()`].
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub fn to_env(&self, env_name: &str) {
|
pub fn to_env(&self, env_name: &str) {
|
||||||
@ -388,9 +335,6 @@ where
|
|||||||
|
|
||||||
impl<EMH, S, SP> LlmpEventManager<EMH, S, SP>
|
impl<EMH, S, SP> LlmpEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State + HasExecutions + HasMetadata + HasImported + HasCorpus,
|
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
// Handle arriving events in the client
|
// Handle arriving events in the client
|
||||||
@ -400,15 +344,16 @@ where
|
|||||||
executor: &mut E,
|
executor: &mut E,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
event: Event<S::Input>,
|
event: Event<<S::Corpus as Corpus>::Input>,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
E: Executor<Self, <S::Corpus as Corpus>::Input, S, Z> + HasObservers,
|
S: HasCorpus + HasImported + Stoppable,
|
||||||
E::Observers: ObserversTuple<S::Input, S> + Serialize,
|
EMH: EventManagerHooksTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
for<'a> E::Observers: Deserialize<'a>,
|
<S::Corpus as Corpus>::Input: Input,
|
||||||
|
E: HasObservers,
|
||||||
|
E::Observers: DeserializeOwned,
|
||||||
Z: ExecutionProcessor<Self, <S::Corpus as Corpus>::Input, E::Observers, S>
|
Z: ExecutionProcessor<Self, <S::Corpus as Corpus>::Input, E::Observers, S>
|
||||||
+ EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>
|
+ EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>,
|
||||||
+ Evaluator<E, Self, <S::Corpus as Corpus>::Input, S>,
|
|
||||||
{
|
{
|
||||||
log::trace!("Got event in client: {} from {client_id:?}", event.name());
|
log::trace!("Got event in client: {} from {client_id:?}", event.name());
|
||||||
if !self.hooks.pre_exec_all(state, client_id, &event)? {
|
if !self.hooks.pre_exec_all(state, client_id, &event)? {
|
||||||
@ -428,38 +373,24 @@ where
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
log::debug!("[{}] Received new Testcase {evt_name} from {client_id:?} ({client_config:?}, forward {forward_id:?})", std::process::id());
|
log::debug!("[{}] Received new Testcase {evt_name} from {client_id:?} ({client_config:?}, forward {forward_id:?})", std::process::id());
|
||||||
|
|
||||||
if self.always_interesting {
|
let res = if client_config.match_with(&self.configuration)
|
||||||
let item = fuzzer.add_input(state, executor, self, input)?;
|
&& observers_buf.is_some()
|
||||||
log::debug!("Added received Testcase as item #{item}");
|
{
|
||||||
} else {
|
let start = current_time();
|
||||||
let res = if client_config.match_with(&self.configuration)
|
let observers: E::Observers =
|
||||||
&& observers_buf.is_some()
|
postcard::from_bytes(observers_buf.as_ref().unwrap())?;
|
||||||
{
|
{
|
||||||
let start = current_time();
|
self.deserialization_time = current_time() - start;
|
||||||
let observers: E::Observers =
|
|
||||||
postcard::from_bytes(observers_buf.as_ref().unwrap())?;
|
|
||||||
{
|
|
||||||
self.deserialization_time = current_time() - start;
|
|
||||||
}
|
|
||||||
#[cfg(feature = "scalability_introspection")]
|
|
||||||
{
|
|
||||||
state.scalability_monitor_mut().testcase_with_observers += 1;
|
|
||||||
}
|
|
||||||
fuzzer
|
|
||||||
.evaluate_execution(state, self, input, &observers, &exit_kind, false)?
|
|
||||||
} else {
|
|
||||||
#[cfg(feature = "scalability_introspection")]
|
|
||||||
{
|
|
||||||
state.scalability_monitor_mut().testcase_without_observers += 1;
|
|
||||||
}
|
|
||||||
fuzzer.evaluate_input_with_observers(state, executor, self, input, false)?
|
|
||||||
};
|
|
||||||
if let Some(item) = res.1 {
|
|
||||||
*state.imported_mut() += 1;
|
|
||||||
log::debug!("Added received Testcase {evt_name} as item #{item}");
|
|
||||||
} else {
|
|
||||||
log::debug!("Testcase {evt_name} was discarded");
|
|
||||||
}
|
}
|
||||||
|
fuzzer.evaluate_execution(state, self, input, &observers, &exit_kind, false)?
|
||||||
|
} else {
|
||||||
|
fuzzer.evaluate_input_with_observers(state, executor, self, input, false)?
|
||||||
|
};
|
||||||
|
if let Some(item) = res.1 {
|
||||||
|
*state.imported_mut() += 1;
|
||||||
|
log::debug!("Added received Testcase {evt_name} as item #{item}");
|
||||||
|
} else {
|
||||||
|
log::debug!("Testcase {evt_name} was discarded");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::Stop => {
|
Event::Stop => {
|
||||||
@ -478,7 +409,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EMH, S: State, SP: ShMemProvider> LlmpEventManager<EMH, S, SP> {
|
impl<EMH, S, SP: ShMemProvider> LlmpEventManager<EMH, S, SP> {
|
||||||
/// Send information that this client is exiting.
|
/// Send information that this client is exiting.
|
||||||
/// The other side may free up all allocated memory.
|
/// The other side may free up all allocated memory.
|
||||||
/// We are no longer allowed to send anything afterwards.
|
/// We are no longer allowed to send anything afterwards.
|
||||||
@ -487,17 +418,9 @@ impl<EMH, S: State, SP: ShMemProvider> LlmpEventManager<EMH, S, SP> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EMH, S, SP> UsesState for LlmpEventManager<EMH, S, SP>
|
impl<EMH, I, S, SP> EventFirer<I, S> for LlmpEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
S: State,
|
I: Serialize,
|
||||||
SP: ShMemProvider,
|
|
||||||
{
|
|
||||||
type State = S;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<EMH, S, SP> EventFirer for LlmpEventManager<EMH, S, SP>
|
|
||||||
where
|
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
fn should_send(&self) -> bool {
|
fn should_send(&self) -> bool {
|
||||||
@ -507,11 +430,7 @@ where
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn fire(
|
fn fire(&mut self, _state: &mut S, event: Event<I>) -> Result<(), Error> {
|
||||||
&mut self,
|
|
||||||
_state: &mut Self::State,
|
|
||||||
event: Event<<Self::State as UsesInput>::Input>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
#[cfg(feature = "llmp_compression")]
|
#[cfg(feature = "llmp_compression")]
|
||||||
let flags = LLMP_FLAG_INITIALIZED;
|
let flags = LLMP_FLAG_INITIALIZED;
|
||||||
|
|
||||||
@ -557,27 +476,24 @@ where
|
|||||||
self.last_sent = current_time();
|
self.last_sent = current_time();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn serialize_observers<OT>(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error>
|
|
||||||
where
|
|
||||||
OT: ObserversTuple<Self::Input, Self::State> + Serialize,
|
|
||||||
{
|
|
||||||
const SERIALIZE_TIME_FACTOR: u32 = 2;
|
|
||||||
const SERIALIZE_PERCENTAGE_THRESHOLD: usize = 80;
|
|
||||||
self.serialize_observers_adaptive(
|
|
||||||
observers,
|
|
||||||
SERIALIZE_TIME_FACTOR,
|
|
||||||
SERIALIZE_PERCENTAGE_THRESHOLD,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn configuration(&self) -> EventConfig {
|
fn configuration(&self) -> EventConfig {
|
||||||
self.configuration
|
self.configuration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EMH, S, SP> EventRestarter for LlmpEventManager<EMH, S, SP>
|
impl<EMH, S, SP> EventRestarter<S> for LlmpEventManager<EMH, S, SP>
|
||||||
|
where
|
||||||
|
SP: ShMemProvider,
|
||||||
|
S: HasCurrentStageId,
|
||||||
|
{
|
||||||
|
fn on_restart(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
|
std_on_restart(self, state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<EMH, S, SP> ManagerExit for LlmpEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
/// The LLMP client needs to wait until a broker has mapped all pages before shutting down.
|
/// The LLMP client needs to wait until a broker has mapped all pages before shutting down.
|
||||||
@ -586,27 +502,24 @@ where
|
|||||||
// wait until we can drop the message safely.
|
// wait until we can drop the message safely.
|
||||||
self.llmp.await_safe_to_unmap_blocking();
|
self.llmp.await_safe_to_unmap_blocking();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_exiting(&mut self) -> Result<(), Error> {
|
||||||
|
self.llmp.sender_mut().send_exiting()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, EMH, S, SP, Z> EventProcessor<E, Z> for LlmpEventManager<EMH, S, SP>
|
impl<E, EMH, S, SP, Z> EventProcessor<E, S, Z> for LlmpEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
EMH: EventManagerHooksTuple<S>,
|
E: HasObservers,
|
||||||
S: State + HasExecutions + HasMetadata + HasImported + HasCorpus,
|
E::Observers: DeserializeOwned,
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
S: HasCorpus + HasImported + Stoppable,
|
||||||
|
EMH: EventManagerHooksTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
|
<S::Corpus as Corpus>::Input: DeserializeOwned + Input,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
E: HasObservers + Executor<Self, <S::Corpus as Corpus>::Input, S, Z>,
|
|
||||||
E::Observers: ObserversTuple<S::Input, S> + Serialize,
|
|
||||||
for<'a> E::Observers: Deserialize<'a>,
|
|
||||||
Z: ExecutionProcessor<Self, <S::Corpus as Corpus>::Input, E::Observers, S>
|
Z: ExecutionProcessor<Self, <S::Corpus as Corpus>::Input, E::Observers, S>
|
||||||
+ EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>
|
+ EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>,
|
||||||
+ Evaluator<E, Self, <S::Corpus as Corpus>::Input, S>,
|
|
||||||
{
|
{
|
||||||
fn process(
|
fn process(&mut self, fuzzer: &mut Z, state: &mut S, executor: &mut E) -> Result<usize, Error> {
|
||||||
&mut self,
|
|
||||||
fuzzer: &mut Z,
|
|
||||||
state: &mut Self::State,
|
|
||||||
executor: &mut E,
|
|
||||||
) -> Result<usize, Error> {
|
|
||||||
// TODO: Get around local event copy by moving handle_in_client
|
// TODO: Get around local event copy by moving handle_in_client
|
||||||
let self_id = self.llmp.sender().id();
|
let self_id = self.llmp.sender().id();
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
@ -630,7 +543,7 @@ where
|
|||||||
} else {
|
} else {
|
||||||
msg
|
msg
|
||||||
};
|
};
|
||||||
let event: Event<S::Input> = postcard::from_bytes(event_bytes)?;
|
let event: Event<<S::Corpus as Corpus>::Input> = postcard::from_bytes(event_bytes)?;
|
||||||
log::debug!("Received event in normal llmp {}", event.name_detailed());
|
log::debug!("Received event in normal llmp {}", event.name_detailed());
|
||||||
|
|
||||||
// If the message comes from another machine, do not
|
// If the message comes from another machine, do not
|
||||||
@ -650,31 +563,27 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, EMH, S, SP, Z> EventManager<E, Z> for LlmpEventManager<EMH, S, SP>
|
impl<EMH, S, SP> ProgressReporter<S> for LlmpEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
E: HasObservers + Executor<Self, <S::Corpus as Corpus>::Input, S, Z>,
|
S: HasExecutions + HasLastReportTime + HasMetadata + HasCorpus + MaybeHasClientPerfMonitor,
|
||||||
E::Observers: ObserversTuple<S::Input, S> + Serialize,
|
|
||||||
for<'a> E::Observers: Deserialize<'a>,
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State + HasExecutions + HasMetadata + HasLastReportTime + HasImported + HasCorpus,
|
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
Z: ExecutionProcessor<Self, <S::Corpus as Corpus>::Input, E::Observers, S>
|
<S::Corpus as Corpus>::Input: Serialize,
|
||||||
+ EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>
|
|
||||||
+ Evaluator<E, Self, <S::Corpus as Corpus>::Input, S>,
|
|
||||||
{
|
{
|
||||||
}
|
fn maybe_report_progress(
|
||||||
|
&mut self,
|
||||||
|
state: &mut S,
|
||||||
|
monitor_timeout: Duration,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
std_maybe_report_progress(self, state, monitor_timeout)
|
||||||
|
}
|
||||||
|
|
||||||
impl<EMH, S, SP> ProgressReporter for LlmpEventManager<EMH, S, SP>
|
fn report_progress(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
where
|
std_report_progress(self, state)
|
||||||
S: State + HasExecutions + HasMetadata + HasLastReportTime,
|
}
|
||||||
SP: ShMemProvider,
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EMH, S, SP> HasEventManagerId for LlmpEventManager<EMH, S, SP>
|
impl<EMH, S, SP> HasEventManagerId for LlmpEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
/// Gets the id assigned to this staterestorer.
|
/// Gets the id assigned to this staterestorer.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! LLMP-backed event manager for scalable multi-processed fuzzing
|
//! LLMP-backed event manager for scalable multi-processed fuzzing
|
||||||
|
|
||||||
use core::{marker::PhantomData, time::Duration};
|
use core::{fmt::Debug, marker::PhantomData, time::Duration};
|
||||||
|
|
||||||
#[cfg(feature = "llmp_compression")]
|
#[cfg(feature = "llmp_compression")]
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
@ -12,16 +12,15 @@ use libafl_bolts::{
|
|||||||
shmem::{NopShMemProvider, ShMemProvider},
|
shmem::{NopShMemProvider, ShMemProvider},
|
||||||
ClientId,
|
ClientId,
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
events::{Event, EventFirer},
|
events::{Event, EventFirer},
|
||||||
executors::{Executor, HasObservers},
|
fuzzer::EvaluatorObservers,
|
||||||
fuzzer::{EvaluatorObservers, ExecutionProcessor},
|
inputs::{Input, InputConverter, NopInput, NopInputConverter},
|
||||||
inputs::{Input, InputConverter, NopInput, NopInputConverter, UsesInput},
|
state::{HasCorpus, NopState},
|
||||||
state::{HasCorpus, HasExecutions, NopState, State, Stoppable, UsesState},
|
Error,
|
||||||
Error, HasMetadata,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The llmp event manager
|
/// The llmp event manager
|
||||||
@ -84,13 +83,9 @@ impl LlmpShouldSaveState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A manager-like llmp client that converts between input types
|
/// A manager-like llmp client that converts between input types
|
||||||
pub struct LlmpEventConverter<DI, IC, ICB, S, SP>
|
pub struct LlmpEventConverter<IC, ICB, S, SP>
|
||||||
where
|
where
|
||||||
S: UsesInput,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
IC: InputConverter<From = S::Input, To = DI>,
|
|
||||||
ICB: InputConverter<From = DI, To = S::Input>,
|
|
||||||
DI: Input,
|
|
||||||
{
|
{
|
||||||
throttle: Option<Duration>,
|
throttle: Option<Duration>,
|
||||||
llmp: LlmpClient<SP>,
|
llmp: LlmpClient<SP>,
|
||||||
@ -104,7 +99,6 @@ where
|
|||||||
|
|
||||||
impl
|
impl
|
||||||
LlmpEventConverter<
|
LlmpEventConverter<
|
||||||
NopInput,
|
|
||||||
NopInputConverter<NopInput>,
|
NopInputConverter<NopInput>,
|
||||||
NopInputConverter<NopInput>,
|
NopInputConverter<NopInput>,
|
||||||
NopState<NopInput>,
|
NopState<NopInput>,
|
||||||
@ -140,18 +134,14 @@ impl LlmpEventConverterBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a event converter from a raw llmp client
|
/// Create a event converter from a raw llmp client
|
||||||
pub fn build_from_client<DI, IC, ICB, S, SP>(
|
pub fn build_from_client<IC, ICB, S, SP>(
|
||||||
self,
|
self,
|
||||||
llmp: LlmpClient<SP>,
|
llmp: LlmpClient<SP>,
|
||||||
converter: Option<IC>,
|
converter: Option<IC>,
|
||||||
converter_back: Option<ICB>,
|
converter_back: Option<ICB>,
|
||||||
) -> Result<LlmpEventConverter<DI, IC, ICB, S, SP>, Error>
|
) -> Result<LlmpEventConverter<IC, ICB, S, SP>, Error>
|
||||||
where
|
where
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
S: UsesInput,
|
|
||||||
IC: InputConverter<From = S::Input, To = DI>,
|
|
||||||
ICB: InputConverter<From = DI, To = S::Input>,
|
|
||||||
DI: Input,
|
|
||||||
{
|
{
|
||||||
Ok(LlmpEventConverter {
|
Ok(LlmpEventConverter {
|
||||||
throttle: self.throttle,
|
throttle: self.throttle,
|
||||||
@ -167,19 +157,15 @@ impl LlmpEventConverterBuilder {
|
|||||||
|
|
||||||
/// Create a client from port and the input converters
|
/// Create a client from port and the input converters
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub fn build_on_port<DI, IC, ICB, S, SP>(
|
pub fn build_on_port<IC, ICB, S, SP>(
|
||||||
self,
|
self,
|
||||||
shmem_provider: SP,
|
shmem_provider: SP,
|
||||||
port: u16,
|
port: u16,
|
||||||
converter: Option<IC>,
|
converter: Option<IC>,
|
||||||
converter_back: Option<ICB>,
|
converter_back: Option<ICB>,
|
||||||
) -> Result<LlmpEventConverter<DI, IC, ICB, S, SP>, Error>
|
) -> Result<LlmpEventConverter<IC, ICB, S, SP>, Error>
|
||||||
where
|
where
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
S: UsesInput,
|
|
||||||
IC: InputConverter<From = S::Input, To = DI>,
|
|
||||||
ICB: InputConverter<From = DI, To = S::Input>,
|
|
||||||
DI: Input,
|
|
||||||
{
|
{
|
||||||
let llmp = LlmpClient::create_attach_to_tcp(shmem_provider, port)?;
|
let llmp = LlmpClient::create_attach_to_tcp(shmem_provider, port)?;
|
||||||
Ok(LlmpEventConverter {
|
Ok(LlmpEventConverter {
|
||||||
@ -196,19 +182,15 @@ impl LlmpEventConverterBuilder {
|
|||||||
|
|
||||||
/// If a client respawns, it may reuse the existing connection, previously stored by [`LlmpClient::to_env()`].
|
/// If a client respawns, it may reuse the existing connection, previously stored by [`LlmpClient::to_env()`].
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub fn build_existing_client_from_env<DI, IC, ICB, S, SP>(
|
pub fn build_existing_client_from_env<IC, ICB, S, SP>(
|
||||||
self,
|
self,
|
||||||
shmem_provider: SP,
|
shmem_provider: SP,
|
||||||
env_name: &str,
|
env_name: &str,
|
||||||
converter: Option<IC>,
|
converter: Option<IC>,
|
||||||
converter_back: Option<ICB>,
|
converter_back: Option<ICB>,
|
||||||
) -> Result<LlmpEventConverter<DI, IC, ICB, S, SP>, Error>
|
) -> Result<LlmpEventConverter<IC, ICB, S, SP>, Error>
|
||||||
where
|
where
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
S: UsesInput,
|
|
||||||
IC: InputConverter<From = S::Input, To = DI>,
|
|
||||||
ICB: InputConverter<From = DI, To = S::Input>,
|
|
||||||
DI: Input,
|
|
||||||
{
|
{
|
||||||
let llmp = LlmpClient::on_existing_from_env(shmem_provider, env_name)?;
|
let llmp = LlmpClient::on_existing_from_env(shmem_provider, env_name)?;
|
||||||
Ok(LlmpEventConverter {
|
Ok(LlmpEventConverter {
|
||||||
@ -224,13 +206,11 @@ impl LlmpEventConverterBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DI, IC, ICB, S, SP> core::fmt::Debug for LlmpEventConverter<DI, IC, ICB, S, SP>
|
impl<IC, ICB, S, SP> Debug for LlmpEventConverter<IC, ICB, S, SP>
|
||||||
where
|
where
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
S: UsesInput,
|
ICB: Debug,
|
||||||
IC: InputConverter<From = S::Input, To = DI>,
|
IC: Debug,
|
||||||
ICB: InputConverter<From = DI, To = S::Input>,
|
|
||||||
DI: Input,
|
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
let mut debug_struct = f.debug_struct("LlmpEventConverter");
|
let mut debug_struct = f.debug_struct("LlmpEventConverter");
|
||||||
@ -246,13 +226,10 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DI, IC, ICB, S, SP> LlmpEventConverter<DI, IC, ICB, S, SP>
|
impl<IC, ICB, S, SP> LlmpEventConverter<IC, ICB, S, SP>
|
||||||
where
|
where
|
||||||
S: UsesInput + HasExecutions + HasMetadata + Stoppable + HasCorpus,
|
S: HasCorpus,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
IC: InputConverter<From = S::Input, To = DI>,
|
|
||||||
ICB: InputConverter<From = DI, To = S::Input>,
|
|
||||||
DI: Input,
|
|
||||||
{
|
{
|
||||||
// TODO other new_* routines
|
// TODO other new_* routines
|
||||||
|
|
||||||
@ -278,7 +255,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle arriving events in the client
|
// Handle arriving events in the client
|
||||||
fn handle_in_client<E, EM, Z>(
|
fn handle_in_client<DI, E, EM, Z>(
|
||||||
&mut self,
|
&mut self,
|
||||||
fuzzer: &mut Z,
|
fuzzer: &mut Z,
|
||||||
executor: &mut E,
|
executor: &mut E,
|
||||||
@ -288,12 +265,8 @@ where
|
|||||||
event: Event<DI>,
|
event: Event<DI>,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
E: Executor<EM, <S::Corpus as Corpus>::Input, S, Z> + HasObservers,
|
ICB: InputConverter<To = <S::Corpus as Corpus>::Input, From = DI>,
|
||||||
EM: UsesState<State = S> + EventFirer,
|
Z: EvaluatorObservers<E, EM, <S::Corpus as Corpus>::Input, S>,
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
|
||||||
for<'a> E::Observers: Deserialize<'a>,
|
|
||||||
Z: ExecutionProcessor<EM, <S::Corpus as Corpus>::Input, E::Observers, S>
|
|
||||||
+ EvaluatorObservers<E, EM, <S::Corpus as Corpus>::Input, S>,
|
|
||||||
{
|
{
|
||||||
match event {
|
match event {
|
||||||
Event::NewTestcase {
|
Event::NewTestcase {
|
||||||
@ -327,7 +300,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Handle arriving events in the client
|
/// Handle arriving events in the client
|
||||||
pub fn process<E, EM, Z>(
|
pub fn process<DI, E, EM, Z>(
|
||||||
&mut self,
|
&mut self,
|
||||||
fuzzer: &mut Z,
|
fuzzer: &mut Z,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
@ -335,12 +308,9 @@ where
|
|||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
) -> Result<usize, Error>
|
) -> Result<usize, Error>
|
||||||
where
|
where
|
||||||
E: Executor<EM, <S::Corpus as Corpus>::Input, S, Z> + HasObservers,
|
ICB: InputConverter<To = <S::Corpus as Corpus>::Input, From = DI>,
|
||||||
EM: UsesState<State = S> + EventFirer,
|
DI: DeserializeOwned + Input,
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
Z: EvaluatorObservers<E, EM, <S::Corpus as Corpus>::Input, S>,
|
||||||
for<'a> E::Observers: Deserialize<'a>,
|
|
||||||
Z: ExecutionProcessor<EM, <S::Corpus as Corpus>::Input, E::Observers, S>
|
|
||||||
+ EvaluatorObservers<E, EM, <S::Corpus as Corpus>::Input, S>,
|
|
||||||
{
|
{
|
||||||
// TODO: Get around local event copy by moving handle_in_client
|
// TODO: Get around local event copy by moving handle_in_client
|
||||||
let self_id = self.llmp.sender().id();
|
let self_id = self.llmp.sender().id();
|
||||||
@ -375,24 +345,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DI, IC, ICB, S, SP> UsesState for LlmpEventConverter<DI, IC, ICB, S, SP>
|
impl<IC, ICB, S, SP> EventFirer<<S::Corpus as Corpus>::Input, S>
|
||||||
|
for LlmpEventConverter<IC, ICB, S, SP>
|
||||||
where
|
where
|
||||||
S: State,
|
IC: InputConverter<From = <S::Corpus as Corpus>::Input>,
|
||||||
|
S: HasCorpus,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
IC: InputConverter<From = S::Input, To = DI>,
|
IC::To: Serialize,
|
||||||
ICB: InputConverter<From = DI, To = S::Input>,
|
|
||||||
DI: Input,
|
|
||||||
{
|
|
||||||
type State = S;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<DI, IC, ICB, S, SP> EventFirer for LlmpEventConverter<DI, IC, ICB, S, SP>
|
|
||||||
where
|
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
|
||||||
IC: InputConverter<From = S::Input, To = DI>,
|
|
||||||
ICB: InputConverter<From = DI, To = S::Input>,
|
|
||||||
DI: Input,
|
|
||||||
{
|
{
|
||||||
fn should_send(&self) -> bool {
|
fn should_send(&self) -> bool {
|
||||||
if let Some(throttle) = self.throttle {
|
if let Some(throttle) = self.throttle {
|
||||||
@ -405,8 +364,8 @@ where
|
|||||||
#[cfg(feature = "llmp_compression")]
|
#[cfg(feature = "llmp_compression")]
|
||||||
fn fire(
|
fn fire(
|
||||||
&mut self,
|
&mut self,
|
||||||
_state: &mut Self::State,
|
_state: &mut S,
|
||||||
event: Event<<Self::State as UsesInput>::Input>,
|
event: Event<<S::Corpus as Corpus>::Input>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
if self.converter.is_none() {
|
if self.converter.is_none() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -461,8 +420,8 @@ where
|
|||||||
#[cfg(not(feature = "llmp_compression"))]
|
#[cfg(not(feature = "llmp_compression"))]
|
||||||
fn fire(
|
fn fire(
|
||||||
&mut self,
|
&mut self,
|
||||||
_state: &mut Self::State,
|
_state: &mut S,
|
||||||
event: Event<<Self::State as UsesInput>::Input>,
|
event: Event<<S::Corpus as Corpus>::Input>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
if self.converter.is_none() {
|
if self.converter.is_none() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -24,37 +24,41 @@ use libafl_bolts::{
|
|||||||
os::CTRL_C_EXIT,
|
os::CTRL_C_EXIT,
|
||||||
shmem::{ShMemProvider, StdShMemProvider},
|
shmem::{ShMemProvider, StdShMemProvider},
|
||||||
staterestore::StateRestorer,
|
staterestore::StateRestorer,
|
||||||
tuples::{tuple_list, Handle},
|
tuples::{tuple_list, Handle, MatchNameRef},
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
use typed_builder::TypedBuilder;
|
use typed_builder::TypedBuilder;
|
||||||
|
|
||||||
#[cfg(all(unix, not(miri)))]
|
#[cfg(all(unix, not(miri)))]
|
||||||
use crate::events::EVENTMGR_SIGHANDLER_STATE;
|
use crate::events::EVENTMGR_SIGHANDLER_STATE;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
common::HasMetadata,
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
events::{
|
events::{
|
||||||
launcher::ClientDescription, AdaptiveSerializer, Event, EventConfig, EventFirer,
|
launcher::ClientDescription, serialize_observers_adaptive, std_maybe_report_progress,
|
||||||
EventManager, EventManagerHooksTuple, EventManagerId, EventProcessor, EventRestarter,
|
std_report_progress, AdaptiveSerializer, CanSerializeObserver, Event, EventConfig,
|
||||||
HasEventManagerId, LlmpEventManager, LlmpShouldSaveState, ProgressReporter,
|
EventFirer, EventManagerHooksTuple, EventManagerId, EventProcessor, EventRestarter,
|
||||||
|
HasEventManagerId, LlmpEventManager, LlmpShouldSaveState, ManagerExit, ProgressReporter,
|
||||||
StdLlmpEventHook,
|
StdLlmpEventHook,
|
||||||
},
|
},
|
||||||
executors::{Executor, HasObservers},
|
executors::HasObservers,
|
||||||
fuzzer::{Evaluator, EvaluatorObservers, ExecutionProcessor},
|
fuzzer::{EvaluatorObservers, ExecutionProcessor},
|
||||||
inputs::UsesInput,
|
inputs::Input,
|
||||||
monitors::Monitor,
|
monitors::Monitor,
|
||||||
observers::{ObserversTuple, TimeObserver},
|
observers::TimeObserver,
|
||||||
state::{HasCorpus, HasExecutions, HasImported, HasLastReportTime, State, UsesState},
|
stages::HasCurrentStageId,
|
||||||
Error, HasMetadata,
|
state::{
|
||||||
|
HasCorpus, HasExecutions, HasImported, HasLastReportTime, MaybeHasClientPerfMonitor,
|
||||||
|
Stoppable,
|
||||||
|
},
|
||||||
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A manager that can restart on the fly, storing states in-between (in `on_restart`)
|
/// A manager that can restart on the fly, storing states in-between (in `on_restart`)
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct LlmpRestartingEventManager<EMH, S, SP>
|
pub struct LlmpRestartingEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
//CE: CustomEvent<I>,
|
|
||||||
{
|
{
|
||||||
/// The embedded LLMP event manager
|
/// The embedded LLMP event manager
|
||||||
llmp_mgr: LlmpEventManager<EMH, S, SP>,
|
llmp_mgr: LlmpEventManager<EMH, S, SP>,
|
||||||
@ -67,7 +71,6 @@ where
|
|||||||
impl<EMH, S, SP> AdaptiveSerializer for LlmpRestartingEventManager<EMH, S, SP>
|
impl<EMH, S, SP> AdaptiveSerializer for LlmpRestartingEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
S: State,
|
|
||||||
{
|
{
|
||||||
fn serialization_time(&self) -> Duration {
|
fn serialization_time(&self) -> Duration {
|
||||||
self.llmp_mgr.serialization_time()
|
self.llmp_mgr.serialization_time()
|
||||||
@ -100,67 +103,68 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EMH, S, SP> UsesState for LlmpRestartingEventManager<EMH, S, SP>
|
impl<EMH, S, SP> ProgressReporter<S> for LlmpRestartingEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
S: State,
|
S: HasExecutions
|
||||||
|
+ HasLastReportTime
|
||||||
|
+ HasMetadata
|
||||||
|
+ HasCorpus
|
||||||
|
+ Serialize
|
||||||
|
+ MaybeHasClientPerfMonitor,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
|
<S::Corpus as Corpus>::Input: Serialize,
|
||||||
{
|
{
|
||||||
type State = S;
|
fn maybe_report_progress(
|
||||||
}
|
&mut self,
|
||||||
|
state: &mut S,
|
||||||
impl<EMH, S, SP> ProgressReporter for LlmpRestartingEventManager<EMH, S, SP>
|
monitor_timeout: Duration,
|
||||||
where
|
) -> Result<(), Error> {
|
||||||
S: State + HasExecutions + HasMetadata + HasLastReportTime,
|
std_maybe_report_progress(self, state, monitor_timeout)
|
||||||
SP: ShMemProvider,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<EMH, S, SP> EventFirer for LlmpRestartingEventManager<EMH, S, SP>
|
|
||||||
where
|
|
||||||
SP: ShMemProvider,
|
|
||||||
S: State,
|
|
||||||
//CE: CustomEvent<I>,
|
|
||||||
{
|
|
||||||
fn should_send(&self) -> bool {
|
|
||||||
self.llmp_mgr.should_send()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fire(
|
fn report_progress(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
&mut self,
|
std_report_progress(self, state)
|
||||||
state: &mut Self::State,
|
}
|
||||||
event: Event<<Self::State as UsesInput>::Input>,
|
}
|
||||||
) -> Result<(), Error> {
|
|
||||||
|
impl<EMH, I, S, SP> EventFirer<I, S> for LlmpRestartingEventManager<EMH, S, SP>
|
||||||
|
where
|
||||||
|
I: Serialize,
|
||||||
|
S: HasCorpus + Serialize,
|
||||||
|
SP: ShMemProvider,
|
||||||
|
{
|
||||||
|
fn should_send(&self) -> bool {
|
||||||
|
<LlmpEventManager<EMH, S, SP> as EventFirer<I, S>>::should_send(&self.llmp_mgr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fire(&mut self, state: &mut S, event: Event<I>) -> Result<(), Error> {
|
||||||
// Check if we are going to crash in the event, in which case we store our current state for the next runner
|
// Check if we are going to crash in the event, in which case we store our current state for the next runner
|
||||||
self.llmp_mgr.fire(state, event)?;
|
self.llmp_mgr.fire(state, event)?;
|
||||||
self.intermediate_save()?;
|
self.intermediate_save()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_observers<OT>(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error>
|
|
||||||
where
|
|
||||||
OT: ObserversTuple<Self::Input, Self::State> + Serialize,
|
|
||||||
{
|
|
||||||
self.llmp_mgr.serialize_observers(observers)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn configuration(&self) -> EventConfig {
|
fn configuration(&self) -> EventConfig {
|
||||||
self.llmp_mgr.configuration()
|
<LlmpEventManager<EMH, S, SP> as EventFirer<I, S>>::configuration(&self.llmp_mgr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EMH, S, SP> EventRestarter for LlmpRestartingEventManager<EMH, S, SP>
|
#[cfg(feature = "std")]
|
||||||
|
impl<EMH, OT, S, SP> CanSerializeObserver<OT> for LlmpRestartingEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
S: State + HasExecutions,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
//CE: CustomEvent<I>,
|
OT: Serialize + MatchNameRef,
|
||||||
{
|
{
|
||||||
/// The llmp client needs to wait until a broker mapped all pages, before shutting down.
|
fn serialize_observers(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error> {
|
||||||
/// Otherwise, the OS may already have removed the shared maps,
|
serialize_observers_adaptive::<Self, OT>(self, observers, 2, 80)
|
||||||
#[inline]
|
|
||||||
fn await_restart_safe(&mut self) {
|
|
||||||
self.llmp_mgr.await_restart_safe();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<EMH, S, SP> EventRestarter<S> for LlmpRestartingEventManager<EMH, S, SP>
|
||||||
|
where
|
||||||
|
SP: ShMemProvider,
|
||||||
|
S: Serialize + HasCurrentStageId,
|
||||||
|
{
|
||||||
/// Reset the single page (we reuse it over and over from pos 0), then send the current state to the next runner.
|
/// Reset the single page (we reuse it over and over from pos 0), then send the current state to the next runner.
|
||||||
fn on_restart(&mut self, state: &mut S) -> Result<(), Error> {
|
fn on_restart(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
state.on_restart()?;
|
state.on_restart()?;
|
||||||
@ -180,31 +184,42 @@ where
|
|||||||
self.await_restart_safe();
|
self.await_restart_safe();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<EMH, S, SP> ManagerExit for LlmpRestartingEventManager<EMH, S, SP>
|
||||||
|
where
|
||||||
|
SP: ShMemProvider,
|
||||||
|
{
|
||||||
fn send_exiting(&mut self) -> Result<(), Error> {
|
fn send_exiting(&mut self) -> Result<(), Error> {
|
||||||
self.staterestorer.send_exiting();
|
self.staterestorer.send_exiting();
|
||||||
// Also inform the broker that we are about to exit.
|
// Also inform the broker that we are about to exit.
|
||||||
// This way, the broker can clean up the pages, and eventually exit.
|
// This way, the broker can clean up the pages, and eventually exit.
|
||||||
self.llmp_mgr.send_exiting()
|
self.llmp_mgr.send_exiting()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The llmp client needs to wait until a broker mapped all pages, before shutting down.
|
||||||
|
/// Otherwise, the OS may already have removed the shared maps,
|
||||||
|
#[inline]
|
||||||
|
fn await_restart_safe(&mut self) {
|
||||||
|
self.llmp_mgr.await_restart_safe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, EMH, S, SP, Z> EventProcessor<E, Z> for LlmpRestartingEventManager<EMH, S, SP>
|
impl<E, EMH, S, SP, Z> EventProcessor<E, S, Z> for LlmpRestartingEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
E: HasObservers + Executor<LlmpEventManager<EMH, S, SP>, <S::Corpus as Corpus>::Input, S, Z>,
|
EMH: EventManagerHooksTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
E::Observers: ObserversTuple<S::Input, S> + Serialize,
|
E: HasObservers,
|
||||||
for<'a> E::Observers: Deserialize<'a>,
|
E::Observers: DeserializeOwned,
|
||||||
EMH: EventManagerHooksTuple<S>,
|
S: HasCorpus + HasImported + Stoppable + Serialize,
|
||||||
S: State + HasExecutions + HasMetadata + HasImported + HasCorpus,
|
<S::Corpus as Corpus>::Input: DeserializeOwned + Input,
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
S::Corpus: Serialize,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
Z: ExecutionProcessor<
|
Z: ExecutionProcessor<
|
||||||
LlmpEventManager<EMH, S, SP>,
|
LlmpEventManager<EMH, S, SP>,
|
||||||
<S::Corpus as Corpus>::Input,
|
<S::Corpus as Corpus>::Input,
|
||||||
E::Observers,
|
E::Observers,
|
||||||
S,
|
S,
|
||||||
> + EvaluatorObservers<E, LlmpEventManager<EMH, S, SP>, <S::Corpus as Corpus>::Input, S>
|
> + EvaluatorObservers<E, LlmpEventManager<EMH, S, SP>, <S::Corpus as Corpus>::Input, S>,
|
||||||
+ Evaluator<E, LlmpEventManager<EMH, S, SP>, <S::Corpus as Corpus>::Input, S>,
|
|
||||||
{
|
{
|
||||||
fn process(&mut self, fuzzer: &mut Z, state: &mut S, executor: &mut E) -> Result<usize, Error> {
|
fn process(&mut self, fuzzer: &mut Z, state: &mut S, executor: &mut E) -> Result<usize, Error> {
|
||||||
let res = self.llmp_mgr.process(fuzzer, state, executor)?;
|
let res = self.llmp_mgr.process(fuzzer, state, executor)?;
|
||||||
@ -217,28 +232,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, EMH, S, SP, Z> EventManager<E, Z> for LlmpRestartingEventManager<EMH, S, SP>
|
|
||||||
where
|
|
||||||
E: HasObservers + Executor<LlmpEventManager<EMH, S, SP>, <S::Corpus as Corpus>::Input, S, Z>,
|
|
||||||
E::Observers: ObserversTuple<S::Input, S> + Serialize,
|
|
||||||
for<'a> E::Observers: Deserialize<'a>,
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State + HasExecutions + HasMetadata + HasLastReportTime + HasImported + HasCorpus,
|
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
|
||||||
SP: ShMemProvider,
|
|
||||||
Z: ExecutionProcessor<
|
|
||||||
LlmpEventManager<EMH, S, SP>,
|
|
||||||
<S::Corpus as Corpus>::Input,
|
|
||||||
E::Observers,
|
|
||||||
S,
|
|
||||||
> + EvaluatorObservers<E, LlmpEventManager<EMH, S, SP>, <S::Corpus as Corpus>::Input, S>
|
|
||||||
+ Evaluator<E, LlmpEventManager<EMH, S, SP>, <S::Corpus as Corpus>::Input, S>,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<EMH, S, SP> HasEventManagerId for LlmpRestartingEventManager<EMH, S, SP>
|
impl<EMH, S, SP> HasEventManagerId for LlmpRestartingEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
fn mgr_id(&self) -> EventManagerId {
|
fn mgr_id(&self) -> EventManagerId {
|
||||||
@ -254,9 +249,8 @@ const _ENV_FUZZER_BROKER_CLIENT_INITIAL: &str = "_AFL_ENV_FUZZER_BROKER_CLIENT";
|
|||||||
|
|
||||||
impl<EMH, S, SP> LlmpRestartingEventManager<EMH, S, SP>
|
impl<EMH, S, SP> LlmpRestartingEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
//CE: CustomEvent<I>,
|
S: Serialize,
|
||||||
{
|
{
|
||||||
/// Create a new runner, the executed child doing the actual fuzzing.
|
/// Create a new runner, the executed child doing the actual fuzzing.
|
||||||
pub fn new(llmp_mgr: LlmpEventManager<EMH, S, SP>, staterestorer: StateRestorer<SP>) -> Self {
|
pub fn new(llmp_mgr: LlmpEventManager<EMH, S, SP>, staterestorer: StateRestorer<SP>) -> Self {
|
||||||
@ -334,7 +328,8 @@ pub fn setup_restarting_mgr_std<MT, S>(
|
|||||||
>
|
>
|
||||||
where
|
where
|
||||||
MT: Monitor + Clone,
|
MT: Monitor + Clone,
|
||||||
S: State,
|
S: HasCorpus + Serialize + DeserializeOwned,
|
||||||
|
<S::Corpus as Corpus>::Input: DeserializeOwned,
|
||||||
{
|
{
|
||||||
RestartingMgr::builder()
|
RestartingMgr::builder()
|
||||||
.shmem_provider(StdShMemProvider::new()?)
|
.shmem_provider(StdShMemProvider::new()?)
|
||||||
@ -366,7 +361,8 @@ pub fn setup_restarting_mgr_std_adaptive<MT, S>(
|
|||||||
>
|
>
|
||||||
where
|
where
|
||||||
MT: Monitor + Clone,
|
MT: Monitor + Clone,
|
||||||
S: State,
|
S: HasCorpus + Serialize + DeserializeOwned,
|
||||||
|
<S::Corpus as Corpus>::Input: DeserializeOwned,
|
||||||
{
|
{
|
||||||
RestartingMgr::builder()
|
RestartingMgr::builder()
|
||||||
.shmem_provider(StdShMemProvider::new()?)
|
.shmem_provider(StdShMemProvider::new()?)
|
||||||
@ -389,9 +385,6 @@ pub struct RestartingMgr<EMH, MT, S, SP> {
|
|||||||
/// The shared memory provider to use for the broker or client spawned by the restarting
|
/// The shared memory provider to use for the broker or client spawned by the restarting
|
||||||
/// manager.
|
/// manager.
|
||||||
shmem_provider: SP,
|
shmem_provider: SP,
|
||||||
#[builder(default = false)]
|
|
||||||
/// Consider this testcase as interesting always if true
|
|
||||||
always_interesting: bool,
|
|
||||||
/// The configuration
|
/// The configuration
|
||||||
configuration: EventConfig,
|
configuration: EventConfig,
|
||||||
/// The monitor to use
|
/// The monitor to use
|
||||||
@ -428,9 +421,10 @@ pub struct RestartingMgr<EMH, MT, S, SP> {
|
|||||||
#[expect(clippy::type_complexity, clippy::too_many_lines)]
|
#[expect(clippy::type_complexity, clippy::too_many_lines)]
|
||||||
impl<EMH, MT, S, SP> RestartingMgr<EMH, MT, S, SP>
|
impl<EMH, MT, S, SP> RestartingMgr<EMH, MT, S, SP>
|
||||||
where
|
where
|
||||||
EMH: EventManagerHooksTuple<S> + Copy + Clone,
|
EMH: EventManagerHooksTuple<<S::Corpus as Corpus>::Input, S> + Copy + Clone,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
S: State,
|
S: HasCorpus + Serialize + DeserializeOwned,
|
||||||
|
<S::Corpus as Corpus>::Input: DeserializeOwned,
|
||||||
MT: Monitor + Clone,
|
MT: Monitor + Clone,
|
||||||
{
|
{
|
||||||
/// Launch the broker and the clients and fuzz
|
/// Launch the broker and the clients and fuzz
|
||||||
@ -463,9 +457,10 @@ where
|
|||||||
LlmpConnection::on_port(self.shmem_provider.clone(), self.broker_port)?;
|
LlmpConnection::on_port(self.shmem_provider.clone(), self.broker_port)?;
|
||||||
match connection {
|
match connection {
|
||||||
LlmpConnection::IsBroker { broker } => {
|
LlmpConnection::IsBroker { broker } => {
|
||||||
let llmp_hook = StdLlmpEventHook::<S::Input, MT>::new(
|
let llmp_hook =
|
||||||
self.monitor.take().unwrap(),
|
StdLlmpEventHook::<<S::Corpus as Corpus>::Input, MT>::new(
|
||||||
)?;
|
self.monitor.take().unwrap(),
|
||||||
|
)?;
|
||||||
|
|
||||||
// Yep, broker. Just loop here.
|
// Yep, broker. Just loop here.
|
||||||
log::info!(
|
log::info!(
|
||||||
@ -481,7 +476,6 @@ where
|
|||||||
}
|
}
|
||||||
LlmpConnection::IsClient { client } => {
|
LlmpConnection::IsClient { client } => {
|
||||||
let mgr: LlmpEventManager<EMH, S, SP> = LlmpEventManager::builder()
|
let mgr: LlmpEventManager<EMH, S, SP> = LlmpEventManager::builder()
|
||||||
.always_interesting(self.always_interesting)
|
|
||||||
.hooks(self.hooks)
|
.hooks(self.hooks)
|
||||||
.build_from_client(
|
.build_from_client(
|
||||||
client,
|
client,
|
||||||
@ -507,7 +501,6 @@ where
|
|||||||
ManagerKind::Client { client_description } => {
|
ManagerKind::Client { client_description } => {
|
||||||
// We are a client
|
// We are a client
|
||||||
let mgr = LlmpEventManager::builder()
|
let mgr = LlmpEventManager::builder()
|
||||||
.always_interesting(self.always_interesting)
|
|
||||||
.hooks(self.hooks)
|
.hooks(self.hooks)
|
||||||
.build_on_port(
|
.build_on_port(
|
||||||
self.shmem_provider.clone(),
|
self.shmem_provider.clone(),
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//! An [`EventManager`] manages all events that go to other instances of the fuzzer.
|
//! An `EventManager` manages all events that go to other instances of the fuzzer.
|
||||||
//! The messages are commonly information about new Testcases as well as stats and other [`Event`]s.
|
//! The messages are commonly information about new Testcases as well as stats and other [`Event`]s.
|
||||||
|
|
||||||
pub mod events_hooks;
|
pub mod events_hooks;
|
||||||
@ -37,29 +37,21 @@ pub use launcher::*;
|
|||||||
use libafl_bolts::os::unix_signals::{siginfo_t, ucontext_t, Signal, SignalHandler};
|
use libafl_bolts::os::unix_signals::{siginfo_t, ucontext_t, Signal, SignalHandler};
|
||||||
#[cfg(all(unix, feature = "std"))]
|
#[cfg(all(unix, feature = "std"))]
|
||||||
use libafl_bolts::os::CTRL_C_EXIT;
|
use libafl_bolts::os::CTRL_C_EXIT;
|
||||||
use libafl_bolts::{
|
#[cfg(feature = "std")]
|
||||||
current_time,
|
use libafl_bolts::tuples::MatchNameRef;
|
||||||
tuples::{Handle, MatchNameRef},
|
use libafl_bolts::{current_time, tuples::Handle};
|
||||||
};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
#[cfg(feature = "introspection")]
|
|
||||||
use crate::state::HasClientPerfMonitor;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
corpus::Corpus,
|
||||||
executors::ExitKind,
|
executors::ExitKind,
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
monitors::UserStats,
|
monitors::UserStats,
|
||||||
observers::ObserversTuple,
|
state::{HasCorpus, HasExecutions, HasLastReportTime, MaybeHasClientPerfMonitor},
|
||||||
state::{HasExecutions, HasLastReportTime, State},
|
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "scalability_introspection")]
|
|
||||||
use crate::{
|
|
||||||
monitors::{AggregatorOps, UserStatsValue},
|
|
||||||
state::HasScalabilityMonitor,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Multi-machine mode
|
/// Multi-machine mode
|
||||||
#[cfg(all(unix, feature = "std", feature = "multi_machine"))]
|
#[cfg(all(unix, feature = "std", feature = "multi_machine"))]
|
||||||
@ -105,7 +97,7 @@ impl SignalHandler for ShutdownSignalData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A per-fuzzer unique `ID`, usually starting with `0` and increasing
|
/// A per-fuzzer unique `ID`, usually starting with `0` and increasing
|
||||||
/// by `1` in multiprocessed [`EventManager`]s, such as [`LlmpEventManager`].
|
/// by `1` in multiprocessed `EventManagers`, such as [`LlmpEventManager`].
|
||||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct EventManagerId(
|
pub struct EventManagerId(
|
||||||
@ -117,9 +109,7 @@ pub struct EventManagerId(
|
|||||||
use crate::events::multi_machine::NodeId;
|
use crate::events::multi_machine::NodeId;
|
||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
use crate::monitors::ClientPerfMonitor;
|
use crate::monitors::ClientPerfMonitor;
|
||||||
use crate::{
|
use crate::{observers::TimeObserver, stages::HasCurrentStageId};
|
||||||
inputs::UsesInput, observers::TimeObserver, stages::HasCurrentStageId, state::UsesState,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// The log event severity
|
/// The log event severity
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
|
||||||
@ -256,11 +246,7 @@ where
|
|||||||
// TODO remove forward_id as not anymore needed for centralized
|
// TODO remove forward_id as not anymore needed for centralized
|
||||||
/// Events sent around in the library
|
/// Events sent around in the library
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
#[serde(bound = "I: serde::de::DeserializeOwned")]
|
pub enum Event<I> {
|
||||||
pub enum Event<I>
|
|
||||||
where
|
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
// TODO use an ID to keep track of the original index in the sender Corpus
|
// TODO use an ID to keep track of the original index in the sender Corpus
|
||||||
// The sender can then use it to send Testcase metadata with CustomEvent
|
// The sender can then use it to send Testcase metadata with CustomEvent
|
||||||
/// A fuzzer found a new testcase. Rejoice!
|
/// A fuzzer found a new testcase. Rejoice!
|
||||||
@ -339,10 +325,7 @@ where
|
|||||||
},*/
|
},*/
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I> Event<I>
|
impl<I> Event<I> {
|
||||||
where
|
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
/// Event's corresponding name
|
/// Event's corresponding name
|
||||||
pub fn name(&self) -> &str {
|
pub fn name(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
@ -361,7 +344,10 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Event's corresponding name with additional info
|
/// Event's corresponding name with additional info
|
||||||
fn name_detailed(&self) -> Cow<'static, str> {
|
fn name_detailed(&self) -> Cow<'static, str>
|
||||||
|
where
|
||||||
|
I: Input,
|
||||||
|
{
|
||||||
match self {
|
match self {
|
||||||
Event::NewTestcase { input, .. } => {
|
Event::NewTestcase { input, .. } => {
|
||||||
Cow::Owned(format!("Testcase {}", input.generate_name(None)))
|
Cow::Owned(format!("Testcase {}", input.generate_name(None)))
|
||||||
@ -386,7 +372,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// [`EventFirer`] fires an event.
|
/// [`EventFirer`] fires an event.
|
||||||
pub trait EventFirer: UsesState {
|
pub trait EventFirer<I, S> {
|
||||||
/// Send off an [`Event`] to the broker
|
/// Send off an [`Event`] to the broker
|
||||||
///
|
///
|
||||||
/// For multi-processed managers, such as [`LlmpEventManager`],
|
/// For multi-processed managers, such as [`LlmpEventManager`],
|
||||||
@ -395,17 +381,13 @@ pub trait EventFirer: UsesState {
|
|||||||
/// (for example for each [`Input`], on multiple cores)
|
/// (for example for each [`Input`], on multiple cores)
|
||||||
/// the [`llmp`] shared map may fill up and the client will eventually OOM or [`panic`].
|
/// the [`llmp`] shared map may fill up and the client will eventually OOM or [`panic`].
|
||||||
/// This should not happen for a normal use-case.
|
/// This should not happen for a normal use-case.
|
||||||
fn fire(
|
fn fire(&mut self, state: &mut S, event: Event<I>) -> Result<(), Error>;
|
||||||
&mut self,
|
|
||||||
state: &mut Self::State,
|
|
||||||
event: Event<<Self::State as UsesInput>::Input>,
|
|
||||||
) -> Result<(), Error>;
|
|
||||||
|
|
||||||
/// Send off an [`Event::Log`] event to the broker.
|
/// Send off an [`Event::Log`] event to the broker.
|
||||||
/// This is a shortcut for [`EventFirer::fire`] with [`Event::Log`] as argument.
|
/// This is a shortcut for [`EventFirer::fire`] with [`Event::Log`] as argument.
|
||||||
fn log(
|
fn log(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut Self::State,
|
state: &mut S,
|
||||||
severity_level: LogSeverity,
|
severity_level: LogSeverity,
|
||||||
message: String,
|
message: String,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
@ -419,14 +401,6 @@ pub trait EventFirer: UsesState {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serialize all observers for this type and manager
|
|
||||||
fn serialize_observers<OT>(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error>
|
|
||||||
where
|
|
||||||
OT: ObserversTuple<<Self as UsesInput>::Input, Self::State> + Serialize,
|
|
||||||
{
|
|
||||||
Ok(Some(postcard::to_allocvec(observers)?))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the configuration
|
/// Get the configuration
|
||||||
fn configuration(&self) -> EventConfig {
|
fn configuration(&self) -> EventConfig {
|
||||||
EventConfig::AlwaysUnique
|
EventConfig::AlwaysUnique
|
||||||
@ -436,208 +410,249 @@ pub trait EventFirer: UsesState {
|
|||||||
fn should_send(&self) -> bool;
|
fn should_send(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`ProgressReporter`] report progress to the broker.
|
/// Serialize all observers for this type and manager
|
||||||
pub trait ProgressReporter: EventFirer
|
/// Serialize the observer using the `time_factor` and `percentage_threshold`.
|
||||||
|
/// These parameters are unique to each of the different types of `EventManager`
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
pub(crate) fn serialize_observers_adaptive<EM, OT>(
|
||||||
|
manager: &mut EM,
|
||||||
|
observers: &OT,
|
||||||
|
time_factor: u32,
|
||||||
|
percentage_threshold: usize,
|
||||||
|
) -> Result<Option<Vec<u8>>, Error>
|
||||||
where
|
where
|
||||||
Self::State: HasMetadata + HasExecutions + HasLastReportTime,
|
EM: AdaptiveSerializer,
|
||||||
|
OT: MatchNameRef + Serialize,
|
||||||
{
|
{
|
||||||
/// Given the last time, if `monitor_timeout` seconds passed, send off an info/monitor/heartbeat message to the broker.
|
match manager.time_ref() {
|
||||||
/// Returns the new `last` time (so the old one, unless `monitor_timeout` time has passed and monitor have been sent)
|
Some(t) => {
|
||||||
/// Will return an [`Error`], if the stats could not be sent.
|
let exec_time = observers
|
||||||
fn maybe_report_progress(
|
.get(t)
|
||||||
&mut self,
|
.map(|o| o.last_runtime().unwrap_or(Duration::ZERO))
|
||||||
state: &mut Self::State,
|
.unwrap();
|
||||||
monitor_timeout: Duration,
|
|
||||||
) -> Result<(), Error> {
|
let mut must_ser = (manager.serialization_time() + manager.deserialization_time())
|
||||||
let Some(last_report_time) = state.last_report_time() else {
|
* time_factor
|
||||||
// this is the first time we execute, no need to report progress just yet.
|
< exec_time;
|
||||||
*state.last_report_time_mut() = Some(current_time());
|
if must_ser {
|
||||||
return Ok(());
|
*manager.should_serialize_cnt_mut() += 1;
|
||||||
};
|
}
|
||||||
let cur = current_time();
|
|
||||||
// default to 0 here to avoid crashes on clock skew
|
if manager.serializations_cnt() > 32 {
|
||||||
if cur.checked_sub(*last_report_time).unwrap_or_default() > monitor_timeout {
|
must_ser = (manager.should_serialize_cnt() * 100 / manager.serializations_cnt())
|
||||||
// report_progress sets a new `last_report_time` internally.
|
> percentage_threshold;
|
||||||
self.report_progress(state)?;
|
}
|
||||||
|
|
||||||
|
if manager.serialization_time() == Duration::ZERO
|
||||||
|
|| must_ser
|
||||||
|
|| manager.serializations_cnt().trailing_zeros() >= 8
|
||||||
|
{
|
||||||
|
let start = current_time();
|
||||||
|
let ser = postcard::to_allocvec(observers)?;
|
||||||
|
*manager.serialization_time_mut() = current_time() - start;
|
||||||
|
|
||||||
|
*manager.serializations_cnt_mut() += 1;
|
||||||
|
Ok(Some(ser))
|
||||||
|
} else {
|
||||||
|
*manager.serializations_cnt_mut() += 1;
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
None => Ok(None),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Send off an info/monitor/heartbeat message to the broker.
|
/// Default implementation of [`ProgressReporter::maybe_report_progress`] for implementors with the
|
||||||
/// Will return an [`Error`], if the stats could not be sent.
|
/// given constraints
|
||||||
fn report_progress(&mut self, state: &mut Self::State) -> Result<(), Error> {
|
pub fn std_maybe_report_progress<PR, S>(
|
||||||
let executions = *state.executions();
|
reporter: &mut PR,
|
||||||
let cur = current_time();
|
state: &mut S,
|
||||||
|
monitor_timeout: Duration,
|
||||||
|
) -> Result<(), Error>
|
||||||
|
where
|
||||||
|
PR: ProgressReporter<S>,
|
||||||
|
S: HasMetadata + HasExecutions + HasLastReportTime,
|
||||||
|
{
|
||||||
|
let Some(last_report_time) = state.last_report_time() else {
|
||||||
|
// this is the first time we execute, no need to report progress just yet.
|
||||||
|
*state.last_report_time_mut() = Some(current_time());
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
let cur = current_time();
|
||||||
|
// default to 0 here to avoid crashes on clock skew
|
||||||
|
if cur.checked_sub(*last_report_time).unwrap_or_default() > monitor_timeout {
|
||||||
|
// report_progress sets a new `last_report_time` internally.
|
||||||
|
reporter.report_progress(state)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// Default no introspection implmentation
|
/// Default implementation of [`ProgressReporter::report_progress`] for implementors with the
|
||||||
#[cfg(not(feature = "introspection"))]
|
/// given constraints
|
||||||
self.fire(
|
pub fn std_report_progress<EM, S>(reporter: &mut EM, state: &mut S) -> Result<(), Error>
|
||||||
|
where
|
||||||
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
|
S: HasExecutions + HasLastReportTime + HasCorpus + MaybeHasClientPerfMonitor,
|
||||||
|
{
|
||||||
|
let executions = *state.executions();
|
||||||
|
let cur = current_time();
|
||||||
|
|
||||||
|
// Default no introspection implmentation
|
||||||
|
#[cfg(not(feature = "introspection"))]
|
||||||
|
reporter.fire(
|
||||||
|
state,
|
||||||
|
Event::UpdateExecStats {
|
||||||
|
executions,
|
||||||
|
time: cur,
|
||||||
|
phantom: PhantomData,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// If performance monitor are requested, fire the `UpdatePerfMonitor` event
|
||||||
|
#[cfg(feature = "introspection")]
|
||||||
|
{
|
||||||
|
state
|
||||||
|
.introspection_monitor_mut()
|
||||||
|
.set_current_time(libafl_bolts::cpu::read_time_counter());
|
||||||
|
|
||||||
|
// Send the current monitor over to the manager. This `.clone` shouldn't be
|
||||||
|
// costly as `ClientPerfMonitor` impls `Copy` since it only contains `u64`s
|
||||||
|
reporter.fire(
|
||||||
state,
|
state,
|
||||||
Event::UpdateExecStats {
|
Event::UpdatePerfMonitor {
|
||||||
executions,
|
executions,
|
||||||
time: cur,
|
time: cur,
|
||||||
|
introspection_monitor: Box::new(state.introspection_monitor().clone()),
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
// If performance monitor are requested, fire the `UpdatePerfMonitor` event
|
*state.last_report_time_mut() = Some(cur);
|
||||||
#[cfg(feature = "introspection")]
|
|
||||||
{
|
|
||||||
state
|
|
||||||
.introspection_monitor_mut()
|
|
||||||
.set_current_time(libafl_bolts::cpu::read_time_counter());
|
|
||||||
|
|
||||||
// Send the current monitor over to the manager. This `.clone` shouldn't be
|
Ok(())
|
||||||
// costly as `ClientPerfMonitor` impls `Copy` since it only contains `u64`s
|
}
|
||||||
self.fire(
|
|
||||||
state,
|
|
||||||
Event::UpdatePerfMonitor {
|
|
||||||
executions,
|
|
||||||
time: cur,
|
|
||||||
introspection_monitor: Box::new(state.introspection_monitor().clone()),
|
|
||||||
phantom: PhantomData,
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we are measuring scalability stuff..
|
/// [`ProgressReporter`] report progress to the broker.
|
||||||
#[cfg(feature = "scalability_introspection")]
|
pub trait ProgressReporter<S> {
|
||||||
{
|
/// Given the last time, if `monitor_timeout` seconds passed, send off an info/monitor/heartbeat message to the broker.
|
||||||
let imported_with_observer = state.scalability_monitor().testcase_with_observers;
|
/// Returns the new `last` time (so the old one, unless `monitor_timeout` time has passed and monitor have been sent)
|
||||||
let imported_without_observer = state.scalability_monitor().testcase_without_observers;
|
/// Will return an [`Error`], if the stats could not be sent.
|
||||||
|
/// [`std_maybe_report_progress`] is the standard implementation that you can call.
|
||||||
|
fn maybe_report_progress(
|
||||||
|
&mut self,
|
||||||
|
state: &mut S,
|
||||||
|
monitor_timeout: Duration,
|
||||||
|
) -> Result<(), Error>;
|
||||||
|
|
||||||
self.fire(
|
/// Send off an info/monitor/heartbeat message to the broker.
|
||||||
state,
|
/// Will return an [`Error`], if the stats could not be sent.
|
||||||
Event::UpdateUserStats {
|
/// [`std_report_progress`] is the standard implementation that you can call.
|
||||||
name: Cow::from("total imported"),
|
fn report_progress(&mut self, state: &mut S) -> Result<(), Error>;
|
||||||
value: UserStats::new(
|
}
|
||||||
UserStatsValue::Number(
|
|
||||||
(imported_with_observer + imported_without_observer) as u64,
|
|
||||||
),
|
|
||||||
AggregatorOps::Avg,
|
|
||||||
),
|
|
||||||
phantom: PhantomData,
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
*state.last_report_time_mut() = Some(cur);
|
/// Restartable trait
|
||||||
|
pub trait EventRestarter<S> {
|
||||||
|
/// For restarting event managers, implement a way to forward state to their next peers.
|
||||||
|
/// You *must* ensure that [`HasCurrentStageId::on_restart`] will be invoked in this method, by you
|
||||||
|
/// or an internal [`EventRestarter`], before the state is saved for recovery.
|
||||||
|
/// [`std_on_restart`] is the standard implementation that you can call.
|
||||||
|
fn on_restart(&mut self, state: &mut S) -> Result<(), Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Default implementation of [`EventRestarter::on_restart`] for implementors with the given
|
||||||
|
/// constraints
|
||||||
|
pub fn std_on_restart<S>(
|
||||||
|
restarter: &mut (impl EventRestarter<S> + ManagerExit),
|
||||||
|
state: &mut S,
|
||||||
|
) -> Result<(), Error>
|
||||||
|
where
|
||||||
|
S: HasCurrentStageId,
|
||||||
|
{
|
||||||
|
state.on_restart()?;
|
||||||
|
restarter.await_restart_safe();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The class that implements this must be able to serialize an observer.
|
||||||
|
pub trait CanSerializeObserver<OT> {
|
||||||
|
/// Do serialize the observer
|
||||||
|
fn serialize_observers(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Routines called before exiting
|
||||||
|
pub trait ManagerExit {
|
||||||
|
/// Send information that this client is exiting.
|
||||||
|
/// No need to restart us any longer, and no need to print an error, either.
|
||||||
|
fn send_exiting(&mut self) -> Result<(), Error>;
|
||||||
|
/// Block until we are safe to exit, usually called inside `on_restart`.
|
||||||
|
fn await_restart_safe(&mut self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`EventProcessor`] process all the incoming messages
|
||||||
|
pub trait EventProcessor<E, S, Z> {
|
||||||
|
/// Lookup for incoming events and process them.
|
||||||
|
/// Return the number of processes events or an error
|
||||||
|
fn process(&mut self, fuzzer: &mut Z, state: &mut S, executor: &mut E) -> Result<usize, Error>;
|
||||||
|
|
||||||
|
/// Shutdown gracefully; typically without saving state.
|
||||||
|
fn on_shutdown(&mut self) -> Result<(), Error>;
|
||||||
|
}
|
||||||
|
/// The id of this `EventManager`.
|
||||||
|
/// For multi processed `EventManagers`,
|
||||||
|
/// each connected client should have a unique ids.
|
||||||
|
pub trait HasEventManagerId {
|
||||||
|
/// The id of this manager. For Multiprocessed `EventManagers`,
|
||||||
|
/// each client should have a unique ids.
|
||||||
|
fn mgr_id(&self) -> EventManagerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An eventmgr for tests, and as placeholder if you really don't need an event manager.
|
||||||
|
#[derive(Copy, Clone, Debug, Default)]
|
||||||
|
pub struct NopEventManager {}
|
||||||
|
|
||||||
|
impl NopEventManager {
|
||||||
|
/// Creates a new [`NopEventManager`]
|
||||||
|
#[must_use]
|
||||||
|
pub fn new() -> Self {
|
||||||
|
NopEventManager {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I, S> EventFirer<I, S> for NopEventManager {
|
||||||
|
fn should_send(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fire(&mut self, _state: &mut S, _event: Event<I>) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Restartable trait
|
impl<S> EventRestarter<S> for NopEventManager
|
||||||
pub trait EventRestarter: UsesState {
|
where
|
||||||
/// For restarting event managers, implement a way to forward state to their next peers.
|
S: HasCurrentStageId,
|
||||||
/// You *must* ensure that [`HasCurrentStageId::on_restart`] will be invoked in this method, by you
|
{
|
||||||
/// or an internal [`EventRestarter`], before the state is saved for recovery.
|
fn on_restart(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
#[inline]
|
std_on_restart(self, state)
|
||||||
fn on_restart(&mut self, state: &mut Self::State) -> Result<(), Error> {
|
|
||||||
state.on_restart()?;
|
|
||||||
self.await_restart_safe();
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ManagerExit for NopEventManager {
|
||||||
/// Send information that this client is exiting.
|
/// Send information that this client is exiting.
|
||||||
/// No need to restart us any longer, and no need to print an error, either.
|
/// No need to restart us any longer, and no need to print an error, either.
|
||||||
fn send_exiting(&mut self) -> Result<(), Error> {
|
fn send_exiting(&mut self) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Block until we are safe to exit, usually called inside `on_restart`.
|
/// Block until we are safe to exit, usually called inside `on_restart`.
|
||||||
#[inline]
|
|
||||||
fn await_restart_safe(&mut self) {}
|
fn await_restart_safe(&mut self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`EventProcessor`] process all the incoming messages
|
impl<E, S, Z> EventProcessor<E, S, Z> for NopEventManager {
|
||||||
pub trait EventProcessor<E, Z>: UsesState {
|
|
||||||
/// Lookup for incoming events and process them.
|
|
||||||
/// Return the number of processes events or an error
|
|
||||||
fn process(
|
|
||||||
&mut self,
|
|
||||||
fuzzer: &mut Z,
|
|
||||||
state: &mut Self::State,
|
|
||||||
executor: &mut E,
|
|
||||||
) -> Result<usize, Error>;
|
|
||||||
|
|
||||||
/// Shutdown gracefully; typically without saving state.
|
|
||||||
fn on_shutdown(&mut self) -> Result<(), Error>;
|
|
||||||
}
|
|
||||||
/// The id of this [`EventManager`].
|
|
||||||
/// For multi processed [`EventManager`]s,
|
|
||||||
/// each connected client should have a unique ids.
|
|
||||||
pub trait HasEventManagerId {
|
|
||||||
/// The id of this manager. For Multiprocessed [`EventManager`]s,
|
|
||||||
/// each client should have a unique ids.
|
|
||||||
fn mgr_id(&self) -> EventManagerId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// [`EventManager`] is the main communications hub.
|
|
||||||
/// For the "normal" multi-processed mode, you may want to look into [`LlmpRestartingEventManager`]
|
|
||||||
pub trait EventManager<E, Z>:
|
|
||||||
EventFirer + EventProcessor<E, Z> + EventRestarter + HasEventManagerId + ProgressReporter
|
|
||||||
where
|
|
||||||
Self::State: HasMetadata + HasExecutions + HasLastReportTime,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An eventmgr for tests, and as placeholder if you really don't need an event manager.
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
pub struct NopEventManager<S> {
|
|
||||||
phantom: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S> NopEventManager<S> {
|
|
||||||
/// Creates a new [`NopEventManager`]
|
|
||||||
#[must_use]
|
|
||||||
pub fn new() -> Self {
|
|
||||||
NopEventManager {
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S> Default for NopEventManager<S> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S> UsesState for NopEventManager<S>
|
|
||||||
where
|
|
||||||
S: State,
|
|
||||||
{
|
|
||||||
type State = S;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S> EventFirer for NopEventManager<S>
|
|
||||||
where
|
|
||||||
S: State,
|
|
||||||
{
|
|
||||||
fn should_send(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fire(
|
|
||||||
&mut self,
|
|
||||||
_state: &mut Self::State,
|
|
||||||
_event: Event<<Self::State as UsesInput>::Input>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S> EventRestarter for NopEventManager<S> where S: State {}
|
|
||||||
|
|
||||||
impl<E, S, Z> EventProcessor<E, Z> for NopEventManager<S>
|
|
||||||
where
|
|
||||||
S: State + HasExecutions,
|
|
||||||
{
|
|
||||||
fn process(
|
fn process(
|
||||||
&mut self,
|
&mut self,
|
||||||
_fuzzer: &mut Z,
|
_fuzzer: &mut Z,
|
||||||
_state: &mut Self::State,
|
_state: &mut S,
|
||||||
_executor: &mut E,
|
_executor: &mut E,
|
||||||
) -> Result<usize, Error> {
|
) -> Result<usize, Error> {
|
||||||
Ok(0)
|
Ok(0)
|
||||||
@ -648,23 +663,36 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, S, Z> EventManager<E, Z> for NopEventManager<S> where
|
impl<OT> CanSerializeObserver<OT> for NopEventManager
|
||||||
S: State + HasExecutions + HasLastReportTime + HasMetadata
|
where
|
||||||
|
OT: Serialize,
|
||||||
{
|
{
|
||||||
|
fn serialize_observers(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error> {
|
||||||
|
Ok(Some(postcard::to_allocvec(observers)?))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> ProgressReporter for NopEventManager<S> where
|
impl<S> ProgressReporter<S> for NopEventManager {
|
||||||
S: State + HasExecutions + HasLastReportTime + HasMetadata
|
fn maybe_report_progress(
|
||||||
{
|
&mut self,
|
||||||
|
_state: &mut S,
|
||||||
|
_monitor_timeout: Duration,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn report_progress(&mut self, _state: &mut S) -> Result<(), Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> HasEventManagerId for NopEventManager<S> {
|
impl HasEventManagerId for NopEventManager {
|
||||||
fn mgr_id(&self) -> EventManagerId {
|
fn mgr_id(&self) -> EventManagerId {
|
||||||
EventManagerId(0)
|
EventManagerId(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An [`EventManager`] type that wraps another manager, but captures a `monitor` type as well.
|
/// An `EventManager` type that wraps another manager, but captures a `monitor` type as well.
|
||||||
/// This is useful to keep the same API between managers with and without an internal `monitor`.
|
/// This is useful to keep the same API between managers with and without an internal `monitor`.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct MonitorTypedEventManager<EM, M> {
|
pub struct MonitorTypedEventManager<EM, M> {
|
||||||
@ -673,7 +701,7 @@ pub struct MonitorTypedEventManager<EM, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<EM, M> MonitorTypedEventManager<EM, M> {
|
impl<EM, M> MonitorTypedEventManager<EM, M> {
|
||||||
/// Creates a new [`EventManager`] that wraps another manager, but captures a `monitor` type as well.
|
/// Creates a new `EventManager` that wraps another manager, but captures a `monitor` type as well.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(inner: EM) -> Self {
|
pub fn new(inner: EM) -> Self {
|
||||||
MonitorTypedEventManager {
|
MonitorTypedEventManager {
|
||||||
@ -683,63 +711,58 @@ impl<EM, M> MonitorTypedEventManager<EM, M> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EM, M> UsesState for MonitorTypedEventManager<EM, M>
|
impl<EM, M, OT> CanSerializeObserver<OT> for MonitorTypedEventManager<EM, M>
|
||||||
where
|
where
|
||||||
EM: UsesState,
|
OT: Serialize,
|
||||||
{
|
{
|
||||||
type State = EM::State;
|
fn serialize_observers(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error> {
|
||||||
|
Ok(Some(postcard::to_allocvec(observers)?))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EM, M> EventFirer for MonitorTypedEventManager<EM, M>
|
impl<EM, I, M, S> EventFirer<I, S> for MonitorTypedEventManager<EM, M>
|
||||||
where
|
where
|
||||||
EM: EventFirer,
|
EM: EventFirer<I, S>,
|
||||||
{
|
{
|
||||||
fn should_send(&self) -> bool {
|
fn should_send(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fire(
|
fn fire(&mut self, state: &mut S, event: Event<I>) -> Result<(), Error> {
|
||||||
&mut self,
|
|
||||||
state: &mut Self::State,
|
|
||||||
event: Event<<Self::State as UsesInput>::Input>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
self.inner.fire(state, event)
|
self.inner.fire(state, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn log(
|
fn log(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut Self::State,
|
state: &mut S,
|
||||||
severity_level: LogSeverity,
|
severity_level: LogSeverity,
|
||||||
message: String,
|
message: String,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
self.inner.log(state, severity_level, message)
|
self.inner.log(state, severity_level, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_observers<OT>(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error>
|
|
||||||
where
|
|
||||||
OT: ObserversTuple<<Self as UsesInput>::Input, Self::State> + Serialize,
|
|
||||||
{
|
|
||||||
self.inner.serialize_observers(observers)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn configuration(&self) -> EventConfig {
|
fn configuration(&self) -> EventConfig {
|
||||||
self.inner.configuration()
|
self.inner.configuration()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EM, M> EventRestarter for MonitorTypedEventManager<EM, M>
|
impl<EM, M, S> EventRestarter<S> for MonitorTypedEventManager<EM, M>
|
||||||
where
|
where
|
||||||
EM: EventRestarter,
|
EM: EventRestarter<S>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn on_restart(&mut self, state: &mut Self::State) -> Result<(), Error> {
|
fn on_restart(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
self.inner.on_restart(state)
|
self.inner.on_restart(state)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<EM, M> ManagerExit for MonitorTypedEventManager<EM, M>
|
||||||
|
where
|
||||||
|
EM: ManagerExit,
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn send_exiting(&mut self) -> Result<(), Error> {
|
fn send_exiting(&mut self) -> Result<(), Error> {
|
||||||
self.inner.send_exiting()
|
self.inner.send_exiting()
|
||||||
@ -751,17 +774,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, EM, M, Z> EventProcessor<E, Z> for MonitorTypedEventManager<EM, M>
|
impl<E, EM, M, S, Z> EventProcessor<E, S, Z> for MonitorTypedEventManager<EM, M>
|
||||||
where
|
where
|
||||||
EM: EventProcessor<E, Z>,
|
EM: EventProcessor<E, S, Z>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn process(
|
fn process(&mut self, fuzzer: &mut Z, state: &mut S, executor: &mut E) -> Result<usize, Error> {
|
||||||
&mut self,
|
|
||||||
fuzzer: &mut Z,
|
|
||||||
state: &mut Self::State,
|
|
||||||
executor: &mut E,
|
|
||||||
) -> Result<usize, Error> {
|
|
||||||
self.inner.process(fuzzer, state, executor)
|
self.inner.process(fuzzer, state, executor)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -770,30 +788,21 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, EM, M, Z> EventManager<E, Z> for MonitorTypedEventManager<EM, M>
|
impl<EM, M, S> ProgressReporter<S> for MonitorTypedEventManager<EM, M>
|
||||||
where
|
where
|
||||||
EM: EventManager<E, Z>,
|
EM: ProgressReporter<S>,
|
||||||
Self::State: HasLastReportTime + HasExecutions + HasMetadata,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<EM, M> ProgressReporter for MonitorTypedEventManager<EM, M>
|
|
||||||
where
|
|
||||||
Self: UsesState,
|
|
||||||
EM: ProgressReporter<State = Self::State>,
|
|
||||||
Self::State: HasLastReportTime + HasExecutions + HasMetadata,
|
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn maybe_report_progress(
|
fn maybe_report_progress(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut Self::State,
|
state: &mut S,
|
||||||
monitor_timeout: Duration,
|
monitor_timeout: Duration,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
self.inner.maybe_report_progress(state, monitor_timeout)
|
self.inner.maybe_report_progress(state, monitor_timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn report_progress(&mut self, state: &mut Self::State) -> Result<(), Error> {
|
fn report_progress(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
self.inner.report_progress(state)
|
self.inner.report_progress(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -830,56 +839,6 @@ pub trait AdaptiveSerializer {
|
|||||||
|
|
||||||
/// A [`Handle`] to the time observer to determine the `time_factor`
|
/// A [`Handle`] to the time observer to determine the `time_factor`
|
||||||
fn time_ref(&self) -> &Option<Handle<TimeObserver>>;
|
fn time_ref(&self) -> &Option<Handle<TimeObserver>>;
|
||||||
|
|
||||||
/// Serialize the observer using the `time_factor` and `percentage_threshold`.
|
|
||||||
/// These parameters are unique to each of the different types of `EventManager`
|
|
||||||
fn serialize_observers_adaptive<S, OT>(
|
|
||||||
&mut self,
|
|
||||||
observers: &OT,
|
|
||||||
time_factor: u32,
|
|
||||||
percentage_threshold: usize,
|
|
||||||
) -> Result<Option<Vec<u8>>, Error>
|
|
||||||
where
|
|
||||||
OT: ObserversTuple<S::Input, S> + Serialize,
|
|
||||||
S: UsesInput,
|
|
||||||
{
|
|
||||||
match self.time_ref() {
|
|
||||||
Some(t) => {
|
|
||||||
let exec_time = observers
|
|
||||||
.get(t)
|
|
||||||
.map(|o| o.last_runtime().unwrap_or(Duration::ZERO))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut must_ser = (self.serialization_time() + self.deserialization_time())
|
|
||||||
* time_factor
|
|
||||||
< exec_time;
|
|
||||||
if must_ser {
|
|
||||||
*self.should_serialize_cnt_mut() += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.serializations_cnt() > 32 {
|
|
||||||
must_ser = (self.should_serialize_cnt() * 100 / self.serializations_cnt())
|
|
||||||
> percentage_threshold;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.serialization_time() == Duration::ZERO
|
|
||||||
|| must_ser
|
|
||||||
|| self.serializations_cnt().trailing_zeros() >= 8
|
|
||||||
{
|
|
||||||
let start = current_time();
|
|
||||||
let ser = postcard::to_allocvec(observers)?;
|
|
||||||
*self.serialization_time_mut() = current_time() - start;
|
|
||||||
|
|
||||||
*self.serializations_cnt_mut() += 1;
|
|
||||||
Ok(Some(ser))
|
|
||||||
} else {
|
|
||||||
*self.serializations_cnt_mut() += 1;
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => Ok(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -51,10 +51,7 @@ const DUMMY_BYTE: u8 = 0x14;
|
|||||||
/// An owned TCP message for multi machine
|
/// An owned TCP message for multi machine
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
// #[serde(bound = "I: serde::de::DeserializeOwned")]
|
// #[serde(bound = "I: serde::de::DeserializeOwned")]
|
||||||
pub enum MultiMachineMsg<'a, I>
|
pub enum MultiMachineMsg<'a, I> {
|
||||||
where
|
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
/// A raw llmp message (not deserialized)
|
/// A raw llmp message (not deserialized)
|
||||||
LlmpMsg(OwnedRef<'a, [u8]>),
|
LlmpMsg(OwnedRef<'a, [u8]>),
|
||||||
|
|
||||||
@ -66,10 +63,7 @@ where
|
|||||||
unsafe impl<I: Input> Send for MultiMachineMsg<'_, I> {}
|
unsafe impl<I: Input> Send for MultiMachineMsg<'_, I> {}
|
||||||
unsafe impl<I: Input> Sync for MultiMachineMsg<'_, I> {}
|
unsafe impl<I: Input> Sync for MultiMachineMsg<'_, I> {}
|
||||||
|
|
||||||
impl<'a, I> MultiMachineMsg<'a, I>
|
impl<'a, I> MultiMachineMsg<'a, I> {
|
||||||
where
|
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
/// Create a new [`MultiMachineMsg`] as event.
|
/// Create a new [`MultiMachineMsg`] as event.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@ -165,10 +159,7 @@ pub struct NodeDescriptor<A> {
|
|||||||
/// passed to the `on_new_message` method (or rather, the memory it points to),
|
/// passed to the `on_new_message` method (or rather, the memory it points to),
|
||||||
/// lives sufficiently long for an async background task to process it.
|
/// lives sufficiently long for an async background task to process it.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TcpMultiMachineHooks<A, I>
|
pub struct TcpMultiMachineHooks<A, I> {
|
||||||
where
|
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
/// The sender hooks
|
/// The sender hooks
|
||||||
pub sender: TcpMultiMachineLlmpSenderHook<A, I>,
|
pub sender: TcpMultiMachineLlmpSenderHook<A, I>,
|
||||||
/// The hooks
|
/// The hooks
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
//! A very simple event manager, that just supports log outputs, but no multiprocessing
|
//! A very simple event manager, that just supports log outputs, but no multiprocessing
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::{fmt::Debug, marker::PhantomData};
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use core::{
|
use core::sync::atomic::{compiler_fence, Ordering};
|
||||||
sync::atomic::{compiler_fence, Ordering},
|
use core::{fmt::Debug, marker::PhantomData, time::Duration};
|
||||||
time::Duration,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(all(feature = "std", any(windows, not(feature = "fork"))))]
|
#[cfg(all(feature = "std", any(windows, not(feature = "fork"))))]
|
||||||
use libafl_bolts::os::startable_self;
|
use libafl_bolts::os::startable_self;
|
||||||
@ -18,25 +15,28 @@ use libafl_bolts::ClientId;
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use libafl_bolts::{os::CTRL_C_EXIT, shmem::ShMemProvider, staterestore::StateRestorer};
|
use libafl_bolts::{os::CTRL_C_EXIT, shmem::ShMemProvider, staterestore::StateRestorer};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
use serde::de::DeserializeOwned;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
use super::ProgressReporter;
|
use super::{std_on_restart, ProgressReporter};
|
||||||
#[cfg(all(unix, feature = "std", not(miri)))]
|
#[cfg(all(unix, feature = "std", not(miri)))]
|
||||||
use crate::events::EVENTMGR_SIGHANDLER_STATE;
|
use crate::events::EVENTMGR_SIGHANDLER_STATE;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
corpus::Corpus,
|
||||||
events::{
|
events::{
|
||||||
BrokerEventResult, Event, EventFirer, EventManager, EventManagerId, EventProcessor,
|
std_maybe_report_progress, std_report_progress, BrokerEventResult, CanSerializeObserver,
|
||||||
EventRestarter, HasEventManagerId,
|
Event, EventFirer, EventManagerId, EventProcessor, EventRestarter, HasEventManagerId,
|
||||||
|
ManagerExit,
|
||||||
},
|
},
|
||||||
inputs::UsesInput,
|
|
||||||
monitors::Monitor,
|
monitors::Monitor,
|
||||||
state::{HasExecutions, HasLastReportTime, State, Stoppable, UsesState},
|
stages::HasCurrentStageId,
|
||||||
|
state::{HasCorpus, HasExecutions, HasLastReportTime, MaybeHasClientPerfMonitor, Stoppable},
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use crate::{
|
use crate::{
|
||||||
monitors::{ClientStats, SimplePrintingMonitor},
|
monitors::{ClientStats, SimplePrintingMonitor},
|
||||||
state::{HasCorpus, HasSolutions},
|
state::HasSolutions,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The llmp connection from the actual fuzzer to the process supervising it
|
/// The llmp connection from the actual fuzzer to the process supervising it
|
||||||
@ -46,21 +46,18 @@ const _ENV_FUZZER_RECEIVER: &str = "_AFL_ENV_FUZZER_RECEIVER";
|
|||||||
const _ENV_FUZZER_BROKER_CLIENT_INITIAL: &str = "_AFL_ENV_FUZZER_BROKER_CLIENT";
|
const _ENV_FUZZER_BROKER_CLIENT_INITIAL: &str = "_AFL_ENV_FUZZER_BROKER_CLIENT";
|
||||||
|
|
||||||
/// A simple, single-threaded event manager that just logs
|
/// A simple, single-threaded event manager that just logs
|
||||||
pub struct SimpleEventManager<MT, S>
|
pub struct SimpleEventManager<I, MT, S> {
|
||||||
where
|
|
||||||
S: UsesInput + Stoppable,
|
|
||||||
{
|
|
||||||
/// The monitor
|
/// The monitor
|
||||||
monitor: MT,
|
monitor: MT,
|
||||||
/// The events that happened since the last `handle_in_broker`
|
/// The events that happened since the last `handle_in_broker`
|
||||||
events: Vec<Event<S::Input>>,
|
events: Vec<Event<I>>,
|
||||||
phantom: PhantomData<S>,
|
phantom: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MT, S> Debug for SimpleEventManager<MT, S>
|
impl<I, MT, S> Debug for SimpleEventManager<I, MT, S>
|
||||||
where
|
where
|
||||||
MT: Debug,
|
MT: Debug,
|
||||||
S: UsesInput + Stoppable,
|
I: Debug,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
f.debug_struct("SimpleEventManager")
|
f.debug_struct("SimpleEventManager")
|
||||||
@ -71,27 +68,17 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MT, S> UsesState for SimpleEventManager<MT, S>
|
impl<I, MT, S> EventFirer<I, S> for SimpleEventManager<I, MT, S>
|
||||||
where
|
|
||||||
S: State,
|
|
||||||
{
|
|
||||||
type State = S;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<MT, S> EventFirer for SimpleEventManager<MT, S>
|
|
||||||
where
|
where
|
||||||
|
I: Debug,
|
||||||
MT: Monitor,
|
MT: Monitor,
|
||||||
S: State,
|
S: Stoppable,
|
||||||
{
|
{
|
||||||
fn should_send(&self) -> bool {
|
fn should_send(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fire(
|
fn fire(&mut self, _state: &mut S, event: Event<I>) -> Result<(), Error> {
|
||||||
&mut self,
|
|
||||||
_state: &mut Self::State,
|
|
||||||
event: Event<<Self::State as UsesInput>::Input>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
match Self::handle_in_broker(&mut self.monitor, &event)? {
|
match Self::handle_in_broker(&mut self.monitor, &event)? {
|
||||||
BrokerEventResult::Forward => self.events.push(event),
|
BrokerEventResult::Forward => self.events.push(event),
|
||||||
BrokerEventResult::Handled => (),
|
BrokerEventResult::Handled => (),
|
||||||
@ -100,17 +87,28 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MT, S> EventRestarter for SimpleEventManager<MT, S>
|
impl<I, MT, S> ManagerExit for SimpleEventManager<I, MT, S> {
|
||||||
where
|
fn send_exiting(&mut self) -> Result<(), Error> {
|
||||||
MT: Monitor,
|
Ok(())
|
||||||
S: State,
|
}
|
||||||
{
|
|
||||||
|
fn await_restart_safe(&mut self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, MT, S, Z> EventProcessor<E, Z> for SimpleEventManager<MT, S>
|
impl<I, MT, S> EventRestarter<S> for SimpleEventManager<I, MT, S>
|
||||||
where
|
where
|
||||||
|
S: HasCurrentStageId,
|
||||||
|
{
|
||||||
|
fn on_restart(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
|
std_on_restart(self, state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E, I, MT, S, Z> EventProcessor<E, S, Z> for SimpleEventManager<I, MT, S>
|
||||||
|
where
|
||||||
|
I: Debug,
|
||||||
MT: Monitor,
|
MT: Monitor,
|
||||||
S: State,
|
S: Stoppable,
|
||||||
{
|
{
|
||||||
fn process(
|
fn process(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -130,34 +128,51 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, MT, S, Z> EventManager<E, Z> for SimpleEventManager<MT, S>
|
impl<I, MT, OT, S> CanSerializeObserver<OT> for SimpleEventManager<I, MT, S>
|
||||||
where
|
where
|
||||||
MT: Monitor,
|
OT: Serialize,
|
||||||
S: State + HasExecutions + HasLastReportTime + HasMetadata,
|
|
||||||
{
|
{
|
||||||
|
fn serialize_observers(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error> {
|
||||||
|
Ok(Some(postcard::to_allocvec(observers)?))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MT, S> ProgressReporter for SimpleEventManager<MT, S>
|
impl<I, MT, S> ProgressReporter<S> for SimpleEventManager<I, MT, S>
|
||||||
where
|
where
|
||||||
|
I: Debug,
|
||||||
MT: Monitor,
|
MT: Monitor,
|
||||||
S: State + HasExecutions + HasMetadata + HasLastReportTime,
|
S: HasMetadata
|
||||||
|
+ HasExecutions
|
||||||
|
+ HasLastReportTime
|
||||||
|
+ Stoppable
|
||||||
|
+ HasCorpus
|
||||||
|
+ MaybeHasClientPerfMonitor,
|
||||||
|
S::Corpus: Corpus<Input = I>,
|
||||||
{
|
{
|
||||||
|
fn maybe_report_progress(
|
||||||
|
&mut self,
|
||||||
|
state: &mut S,
|
||||||
|
monitor_timeout: Duration,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
std_maybe_report_progress(self, state, monitor_timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn report_progress(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
|
std_report_progress(self, state)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MT, S> HasEventManagerId for SimpleEventManager<MT, S>
|
impl<I, MT, S> HasEventManagerId for SimpleEventManager<I, MT, S> {
|
||||||
where
|
|
||||||
MT: Monitor,
|
|
||||||
S: UsesInput + Stoppable,
|
|
||||||
{
|
|
||||||
fn mgr_id(&self) -> EventManagerId {
|
fn mgr_id(&self) -> EventManagerId {
|
||||||
EventManagerId(0)
|
EventManagerId(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<S> SimpleEventManager<SimplePrintingMonitor, S>
|
impl<I, S> SimpleEventManager<I, SimplePrintingMonitor, S>
|
||||||
where
|
where
|
||||||
S: UsesInput + Stoppable,
|
I: Debug,
|
||||||
|
S: Stoppable,
|
||||||
{
|
{
|
||||||
/// Creates a [`SimpleEventManager`] that just prints to `stdout`.
|
/// Creates a [`SimpleEventManager`] that just prints to `stdout`.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
@ -166,10 +181,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MT, S> SimpleEventManager<MT, S>
|
impl<I, MT, S> SimpleEventManager<I, MT, S>
|
||||||
where
|
where
|
||||||
MT: Monitor, //TODO CE: CustomEvent,
|
I: Debug,
|
||||||
S: UsesInput + Stoppable,
|
MT: Monitor,
|
||||||
|
S: Stoppable,
|
||||||
{
|
{
|
||||||
/// Creates a new [`SimpleEventManager`].
|
/// Creates a new [`SimpleEventManager`].
|
||||||
pub fn new(monitor: MT) -> Self {
|
pub fn new(monitor: MT) -> Self {
|
||||||
@ -182,10 +198,7 @@ where
|
|||||||
|
|
||||||
/// Handle arriving events in the broker
|
/// Handle arriving events in the broker
|
||||||
#[expect(clippy::unnecessary_wraps)]
|
#[expect(clippy::unnecessary_wraps)]
|
||||||
fn handle_in_broker(
|
fn handle_in_broker(monitor: &mut MT, event: &Event<I>) -> Result<BrokerEventResult, Error> {
|
||||||
monitor: &mut MT,
|
|
||||||
event: &Event<S::Input>,
|
|
||||||
) -> Result<BrokerEventResult, Error> {
|
|
||||||
match event {
|
match event {
|
||||||
Event::NewTestcase { corpus_size, .. } => {
|
Event::NewTestcase { corpus_size, .. } => {
|
||||||
monitor.client_stats_insert(ClientId(0));
|
monitor.client_stats_insert(ClientId(0));
|
||||||
@ -254,7 +267,7 @@ where
|
|||||||
|
|
||||||
// Handle arriving events in the client
|
// Handle arriving events in the client
|
||||||
#[allow(clippy::unused_self)]
|
#[allow(clippy::unused_self)]
|
||||||
fn handle_in_client(&mut self, state: &mut S, event: &Event<S::Input>) -> Result<(), Error> {
|
fn handle_in_client(&mut self, state: &mut S, event: &Event<I>) -> Result<(), Error> {
|
||||||
match event {
|
match event {
|
||||||
Event::Stop => {
|
Event::Stop => {
|
||||||
state.request_stop();
|
state.request_stop();
|
||||||
@ -274,52 +287,39 @@ where
|
|||||||
/// `restarter` will start a new process each time the child crashes or times out.
|
/// `restarter` will start a new process each time the child crashes or times out.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SimpleRestartingEventManager<MT, S, SP>
|
pub struct SimpleRestartingEventManager<I, MT, S, SP>
|
||||||
where
|
where
|
||||||
S: UsesInput + Stoppable,
|
SP: ShMemProvider,
|
||||||
SP: ShMemProvider, //CE: CustomEvent<I, OT>,
|
|
||||||
{
|
{
|
||||||
/// The actual simple event mgr
|
/// The actual simple event mgr
|
||||||
simple_event_mgr: SimpleEventManager<MT, S>,
|
inner: SimpleEventManager<I, MT, S>,
|
||||||
/// [`StateRestorer`] for restarts
|
/// [`StateRestorer`] for restarts
|
||||||
staterestorer: StateRestorer<SP>,
|
staterestorer: StateRestorer<SP>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<MT, S, SP> UsesState for SimpleRestartingEventManager<MT, S, SP>
|
impl<I, MT, S, SP> EventFirer<I, S> for SimpleRestartingEventManager<I, MT, S, SP>
|
||||||
where
|
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
|
||||||
{
|
|
||||||
type State = S;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl<MT, S, SP> EventFirer for SimpleRestartingEventManager<MT, S, SP>
|
|
||||||
where
|
where
|
||||||
|
I: Debug,
|
||||||
MT: Monitor,
|
MT: Monitor,
|
||||||
S: State,
|
S: Stoppable,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
fn should_send(&self) -> bool {
|
fn should_send(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fire(
|
fn fire(&mut self, _state: &mut S, event: Event<I>) -> Result<(), Error> {
|
||||||
&mut self,
|
self.inner.fire(_state, event)
|
||||||
_state: &mut Self::State,
|
|
||||||
event: Event<<Self::State as UsesInput>::Input>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
self.simple_event_mgr.fire(_state, event)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<MT, S, SP> EventRestarter for SimpleRestartingEventManager<MT, S, SP>
|
impl<I, MT, S, SP> EventRestarter<S> for SimpleRestartingEventManager<I, MT, S, SP>
|
||||||
where
|
where
|
||||||
MT: Monitor,
|
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
|
S: HasCurrentStageId + Serialize,
|
||||||
|
MT: Monitor,
|
||||||
{
|
{
|
||||||
/// Reset the single page (we reuse it over and over from pos 0), then send the current state to the next runner.
|
/// Reset the single page (we reuse it over and over from pos 0), then send the current state to the next runner.
|
||||||
fn on_restart(&mut self, state: &mut S) -> Result<(), Error> {
|
fn on_restart(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
@ -329,84 +329,109 @@ where
|
|||||||
self.staterestorer.reset();
|
self.staterestorer.reset();
|
||||||
self.staterestorer.save(&(
|
self.staterestorer.save(&(
|
||||||
state,
|
state,
|
||||||
self.simple_event_mgr.monitor.start_time(),
|
self.inner.monitor.start_time(),
|
||||||
self.simple_event_mgr.monitor.client_stats(),
|
self.inner.monitor.client_stats(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_exiting(&mut self) -> Result<(), Error> {
|
|
||||||
self.staterestorer.send_exiting();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<E, MT, S, SP, Z> EventProcessor<E, Z> for SimpleRestartingEventManager<MT, S, SP>
|
impl<I, MT, OT, S, SP> CanSerializeObserver<OT> for SimpleRestartingEventManager<I, MT, S, SP>
|
||||||
|
where
|
||||||
|
SP: ShMemProvider,
|
||||||
|
OT: Serialize,
|
||||||
|
{
|
||||||
|
fn serialize_observers(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error> {
|
||||||
|
Ok(Some(postcard::to_allocvec(observers)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl<I, MT, S, SP> ManagerExit for SimpleRestartingEventManager<I, MT, S, SP>
|
||||||
where
|
where
|
||||||
MT: Monitor,
|
|
||||||
S: State + HasExecutions,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
fn process(
|
fn send_exiting(&mut self) -> Result<(), Error> {
|
||||||
&mut self,
|
self.staterestorer.send_exiting();
|
||||||
fuzzer: &mut Z,
|
Ok(())
|
||||||
state: &mut Self::State,
|
|
||||||
executor: &mut E,
|
|
||||||
) -> Result<usize, Error> {
|
|
||||||
self.simple_event_mgr.process(fuzzer, state, executor)
|
|
||||||
}
|
}
|
||||||
|
/// Block until we are safe to exit, usually called inside `on_restart`.
|
||||||
|
#[inline]
|
||||||
|
fn await_restart_safe(&mut self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl<E, I, MT, S, SP, Z> EventProcessor<E, S, Z> for SimpleRestartingEventManager<I, MT, S, SP>
|
||||||
|
where
|
||||||
|
I: Debug,
|
||||||
|
MT: Monitor,
|
||||||
|
SP: ShMemProvider,
|
||||||
|
S: Stoppable,
|
||||||
|
{
|
||||||
|
fn process(&mut self, fuzzer: &mut Z, state: &mut S, executor: &mut E) -> Result<usize, Error> {
|
||||||
|
self.inner.process(fuzzer, state, executor)
|
||||||
|
}
|
||||||
|
|
||||||
fn on_shutdown(&mut self) -> Result<(), Error> {
|
fn on_shutdown(&mut self) -> Result<(), Error> {
|
||||||
self.send_exiting()
|
self.send_exiting()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<E, MT, S, SP, Z> EventManager<E, Z> for SimpleRestartingEventManager<MT, S, SP>
|
impl<I, MT, S, SP> ProgressReporter<S> for SimpleRestartingEventManager<I, MT, S, SP>
|
||||||
where
|
where
|
||||||
|
I: Debug,
|
||||||
MT: Monitor,
|
MT: Monitor,
|
||||||
S: State + HasExecutions + HasMetadata + HasLastReportTime + Serialize,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
|
S: HasExecutions
|
||||||
|
+ HasMetadata
|
||||||
|
+ HasLastReportTime
|
||||||
|
+ Stoppable
|
||||||
|
+ HasCorpus
|
||||||
|
+ MaybeHasClientPerfMonitor,
|
||||||
|
S::Corpus: Corpus<Input = I>,
|
||||||
{
|
{
|
||||||
}
|
fn maybe_report_progress(
|
||||||
|
&mut self,
|
||||||
|
state: &mut S,
|
||||||
|
monitor_timeout: Duration,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
std_maybe_report_progress(self, state, monitor_timeout)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
fn report_progress(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
impl<MT, S, SP> ProgressReporter for SimpleRestartingEventManager<MT, S, SP>
|
std_report_progress(self, state)
|
||||||
where
|
|
||||||
MT: Monitor,
|
|
||||||
S: State + HasExecutions + HasMetadata + HasLastReportTime,
|
|
||||||
SP: ShMemProvider,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl<MT, S, SP> HasEventManagerId for SimpleRestartingEventManager<MT, S, SP>
|
|
||||||
where
|
|
||||||
MT: Monitor,
|
|
||||||
S: UsesInput + Stoppable,
|
|
||||||
SP: ShMemProvider,
|
|
||||||
{
|
|
||||||
fn mgr_id(&self) -> EventManagerId {
|
|
||||||
self.simple_event_mgr.mgr_id()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<MT, S, SP> SimpleRestartingEventManager<MT, S, SP>
|
impl<I, MT, S, SP> HasEventManagerId for SimpleRestartingEventManager<I, MT, S, SP>
|
||||||
where
|
where
|
||||||
S: UsesInput + Stoppable,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
MT: Monitor, //TODO CE: CustomEvent,
|
{
|
||||||
|
fn mgr_id(&self) -> EventManagerId {
|
||||||
|
self.inner.mgr_id()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl<I, MT, S, SP> SimpleRestartingEventManager<I, MT, S, SP>
|
||||||
|
where
|
||||||
|
I: Debug,
|
||||||
|
MT: Monitor,
|
||||||
|
S: Stoppable,
|
||||||
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
/// Creates a new [`SimpleEventManager`].
|
/// Creates a new [`SimpleEventManager`].
|
||||||
fn launched(monitor: MT, staterestorer: StateRestorer<SP>) -> Self {
|
fn launched(monitor: MT, staterestorer: StateRestorer<SP>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
staterestorer,
|
staterestorer,
|
||||||
simple_event_mgr: SimpleEventManager::new(monitor),
|
inner: SimpleEventManager::new(monitor),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Launch the simple restarting manager.
|
/// Launch the simple restarting manager.
|
||||||
/// This [`EventManager`] is simple and single threaded,
|
/// This `EventManager` is simple and single threaded,
|
||||||
/// but can still used shared maps to recover from crashes and timeouts.
|
/// but can still used shared maps to recover from crashes and timeouts.
|
||||||
pub fn launch(mut monitor: MT, shmem_provider: &mut SP) -> Result<(Option<S>, Self), Error>
|
pub fn launch(mut monitor: MT, shmem_provider: &mut SP) -> Result<(Option<S>, Self), Error>
|
||||||
where
|
where
|
||||||
|
@ -38,20 +38,25 @@ use tokio::{
|
|||||||
};
|
};
|
||||||
use typed_builder::TypedBuilder;
|
use typed_builder::TypedBuilder;
|
||||||
|
|
||||||
|
use super::{std_maybe_report_progress, std_report_progress, ManagerExit};
|
||||||
#[cfg(all(unix, not(miri)))]
|
#[cfg(all(unix, not(miri)))]
|
||||||
use crate::events::EVENTMGR_SIGHANDLER_STATE;
|
use crate::events::EVENTMGR_SIGHANDLER_STATE;
|
||||||
use crate::{
|
use crate::{
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
events::{
|
events::{
|
||||||
BrokerEventResult, Event, EventConfig, EventFirer, EventManager, EventManagerHooksTuple,
|
std_on_restart, BrokerEventResult, Event, EventConfig, EventFirer, EventManagerHooksTuple,
|
||||||
EventManagerId, EventProcessor, EventRestarter, HasEventManagerId, ProgressReporter,
|
EventManagerId, EventProcessor, EventRestarter, HasEventManagerId, ProgressReporter,
|
||||||
},
|
},
|
||||||
executors::{Executor, HasObservers},
|
executors::{Executor, HasObservers},
|
||||||
fuzzer::{EvaluatorObservers, ExecutionProcessor},
|
fuzzer::{EvaluatorObservers, ExecutionProcessor},
|
||||||
inputs::{Input, UsesInput},
|
inputs::Input,
|
||||||
monitors::Monitor,
|
monitors::Monitor,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
state::{HasCorpus, HasExecutions, HasImported, HasLastReportTime, State, UsesState},
|
stages::HasCurrentStageId,
|
||||||
|
state::{
|
||||||
|
HasCorpus, HasExecutions, HasImported, HasLastReportTime, MaybeHasClientPerfMonitor,
|
||||||
|
Stoppable,
|
||||||
|
},
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -403,12 +408,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An [`EventManager`] that forwards all events to other attached via tcp.
|
/// An `EventManager` that forwards all events to other attached via tcp.
|
||||||
pub struct TcpEventManager<EMH, S>
|
pub struct TcpEventManager<EMH, S> {
|
||||||
where
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State,
|
|
||||||
{
|
|
||||||
/// We send message every `throttle` second
|
/// We send message every `throttle` second
|
||||||
throttle: Option<Duration>,
|
throttle: Option<Duration>,
|
||||||
/// When we sent the last message
|
/// When we sent the last message
|
||||||
@ -427,10 +428,7 @@ where
|
|||||||
phantom: PhantomData<S>,
|
phantom: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> TcpEventManager<(), S>
|
impl<S> TcpEventManager<(), S> {
|
||||||
where
|
|
||||||
S: State,
|
|
||||||
{
|
|
||||||
/// Create a builder for [`TcpEventManager`]
|
/// Create a builder for [`TcpEventManager`]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn builder() -> TcpEventManagerBuilder<(), S> {
|
pub fn builder() -> TcpEventManagerBuilder<(), S> {
|
||||||
@ -474,11 +472,7 @@ impl<S> TcpEventManagerBuilder<(), S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EMH, S> TcpEventManagerBuilder<EMH, S>
|
impl<EMH, S> TcpEventManagerBuilder<EMH, S> {
|
||||||
where
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State + HasExecutions + HasMetadata,
|
|
||||||
{
|
|
||||||
/// Set the throttle
|
/// Set the throttle
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn throttle(mut self, throttle: Duration) -> Self {
|
pub fn throttle(mut self, throttle: Duration) -> Self {
|
||||||
@ -546,11 +540,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EMH, S> core::fmt::Debug for TcpEventManager<EMH, S>
|
impl<EMH, S> core::fmt::Debug for TcpEventManager<EMH, S> {
|
||||||
where
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State,
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
let mut debug_struct = f.debug_struct("TcpEventManager");
|
let mut debug_struct = f.debug_struct("TcpEventManager");
|
||||||
let debug = debug_struct.field("tcp", &self.tcp);
|
let debug = debug_struct.field("tcp", &self.tcp);
|
||||||
@ -564,11 +554,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EMH, S> Drop for TcpEventManager<EMH, S>
|
impl<EMH, S> Drop for TcpEventManager<EMH, S> {
|
||||||
where
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State,
|
|
||||||
{
|
|
||||||
/// TCP clients will have to wait until their pages are mapped by somebody.
|
/// TCP clients will have to wait until their pages are mapped by somebody.
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.await_restart_safe();
|
self.await_restart_safe();
|
||||||
@ -577,11 +563,10 @@ where
|
|||||||
|
|
||||||
impl<EMH, S> TcpEventManager<EMH, S>
|
impl<EMH, S> TcpEventManager<EMH, S>
|
||||||
where
|
where
|
||||||
EMH: EventManagerHooksTuple<S>,
|
EMH: EventManagerHooksTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
S: State + HasExecutions + HasMetadata + HasImported + HasCorpus,
|
S: HasExecutions + HasMetadata + HasImported + HasCorpus + Stoppable,
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
|
||||||
{
|
{
|
||||||
/// Write the client id for a client [`EventManager`] to env vars
|
/// Write the client id for a client `EventManager` to env vars
|
||||||
pub fn to_env(&self, env_name: &str) {
|
pub fn to_env(&self, env_name: &str) {
|
||||||
env::set_var(env_name, format!("{}", self.client_id.0));
|
env::set_var(env_name, format!("{}", self.client_id.0));
|
||||||
}
|
}
|
||||||
@ -593,11 +578,11 @@ where
|
|||||||
executor: &mut E,
|
executor: &mut E,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
event: Event<S::Input>,
|
event: Event<<S::Corpus as Corpus>::Input>,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
E: Executor<Self, <S::Corpus as Corpus>::Input, S, Z> + HasObservers,
|
E: Executor<Self, <S::Corpus as Corpus>::Input, S, Z> + HasObservers,
|
||||||
E::Observers: Serialize + ObserversTuple<S::Input, S>,
|
E::Observers: Serialize + ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
for<'a> E::Observers: Deserialize<'a>,
|
for<'a> E::Observers: Deserialize<'a>,
|
||||||
Z: ExecutionProcessor<Self, <S::Corpus as Corpus>::Input, E::Observers, S>
|
Z: ExecutionProcessor<Self, <S::Corpus as Corpus>::Input, E::Observers, S>
|
||||||
+ EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>,
|
+ EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>,
|
||||||
@ -621,16 +606,8 @@ where
|
|||||||
{
|
{
|
||||||
let observers: E::Observers =
|
let observers: E::Observers =
|
||||||
postcard::from_bytes(observers_buf.as_ref().unwrap())?;
|
postcard::from_bytes(observers_buf.as_ref().unwrap())?;
|
||||||
#[cfg(feature = "scalability_introspection")]
|
|
||||||
{
|
|
||||||
state.scalability_monitor_mut().testcase_with_observers += 1;
|
|
||||||
}
|
|
||||||
fuzzer.evaluate_execution(state, self, input, &observers, &exit_kind, false)?
|
fuzzer.evaluate_execution(state, self, input, &observers, &exit_kind, false)?
|
||||||
} else {
|
} else {
|
||||||
#[cfg(feature = "scalability_introspection")]
|
|
||||||
{
|
|
||||||
state.scalability_monitor_mut().testcase_without_observers += 1;
|
|
||||||
}
|
|
||||||
fuzzer.evaluate_input_with_observers(state, executor, self, input, false)?
|
fuzzer.evaluate_input_with_observers(state, executor, self, input, false)?
|
||||||
};
|
};
|
||||||
if let Some(item) = _res.1 {
|
if let Some(item) = _res.1 {
|
||||||
@ -653,11 +630,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EMH, S> TcpEventManager<EMH, S>
|
impl<EMH, S> TcpEventManager<EMH, S> {
|
||||||
where
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State,
|
|
||||||
{
|
|
||||||
/// Send information that this client is exiting.
|
/// Send information that this client is exiting.
|
||||||
/// The other side may free up all allocated memory.
|
/// The other side may free up all allocated memory.
|
||||||
/// We are no longer allowed to send anything afterwards.
|
/// We are no longer allowed to send anything afterwards.
|
||||||
@ -668,18 +641,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EMH, S> UsesState for TcpEventManager<EMH, S>
|
impl<EMH, S> EventFirer<<S::Corpus as Corpus>::Input, S> for TcpEventManager<EMH, S>
|
||||||
where
|
where
|
||||||
EMH: EventManagerHooksTuple<S>,
|
EMH: EventManagerHooksTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
S: State,
|
S: HasCorpus,
|
||||||
{
|
<S::Corpus as Corpus>::Input: Serialize,
|
||||||
type State = S;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<EMH, S> EventFirer for TcpEventManager<EMH, S>
|
|
||||||
where
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State,
|
|
||||||
{
|
{
|
||||||
fn should_send(&self) -> bool {
|
fn should_send(&self) -> bool {
|
||||||
if let Some(throttle) = self.throttle {
|
if let Some(throttle) = self.throttle {
|
||||||
@ -691,8 +657,8 @@ where
|
|||||||
|
|
||||||
fn fire(
|
fn fire(
|
||||||
&mut self,
|
&mut self,
|
||||||
_state: &mut Self::State,
|
_state: &mut S,
|
||||||
event: Event<<Self::State as UsesInput>::Input>,
|
event: Event<<S::Corpus as Corpus>::Input>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let serialized = postcard::to_allocvec(&event)?;
|
let serialized = postcard::to_allocvec(&event)?;
|
||||||
|
|
||||||
@ -713,36 +679,27 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EMH, S> EventRestarter for TcpEventManager<EMH, S>
|
impl<EMH, S> EventRestarter<S> for TcpEventManager<EMH, S>
|
||||||
where
|
where
|
||||||
EMH: EventManagerHooksTuple<S>,
|
S: HasCurrentStageId,
|
||||||
S: State,
|
|
||||||
{
|
{
|
||||||
/// The TCP client needs to wait until a broker has mapped all pages before shutting down.
|
fn on_restart(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
/// Otherwise, the OS may already have removed the shared maps.
|
std_on_restart(self, state)
|
||||||
fn await_restart_safe(&mut self) {
|
|
||||||
// wait until we can drop the message safely.
|
|
||||||
//self.tcp.await_safe_to_unmap_blocking();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, EMH, S, Z> EventProcessor<E, Z> for TcpEventManager<EMH, S>
|
impl<E, EMH, S, Z> EventProcessor<E, S, Z> for TcpEventManager<EMH, S>
|
||||||
where
|
where
|
||||||
E: HasObservers + Executor<Self, <S::Corpus as Corpus>::Input, S, Z>,
|
E: HasObservers + Executor<Self, <S::Corpus as Corpus>::Input, S, Z>,
|
||||||
E::Observers: Serialize + ObserversTuple<S::Input, S>,
|
E::Observers: Serialize + ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
for<'a> E::Observers: Deserialize<'a>,
|
for<'a> E::Observers: Deserialize<'a>,
|
||||||
EMH: EventManagerHooksTuple<S>,
|
EMH: EventManagerHooksTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
S: State + HasExecutions + HasMetadata + HasImported + HasCorpus,
|
S: HasExecutions + HasMetadata + HasImported + HasCorpus + Stoppable,
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
<S::Corpus as Corpus>::Input: DeserializeOwned,
|
||||||
Z: ExecutionProcessor<Self, <S::Corpus as Corpus>::Input, E::Observers, S>
|
Z: ExecutionProcessor<Self, <S::Corpus as Corpus>::Input, E::Observers, S>
|
||||||
+ EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>,
|
+ EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>,
|
||||||
{
|
{
|
||||||
fn process(
|
fn process(&mut self, fuzzer: &mut Z, state: &mut S, executor: &mut E) -> Result<usize, Error> {
|
||||||
&mut self,
|
|
||||||
fuzzer: &mut Z,
|
|
||||||
state: &mut Self::State,
|
|
||||||
executor: &mut E,
|
|
||||||
) -> Result<usize, Error> {
|
|
||||||
// TODO: Get around local event copy by moving handle_in_client
|
// TODO: Get around local event copy by moving handle_in_client
|
||||||
let self_id = self.client_id;
|
let self_id = self.client_id;
|
||||||
let mut len_buf = [0_u8; 4];
|
let mut len_buf = [0_u8; 4];
|
||||||
@ -801,31 +758,41 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, EMH, S, Z> EventManager<E, Z> for TcpEventManager<EMH, S>
|
impl<EMH, S> ManagerExit for TcpEventManager<EMH, S> {
|
||||||
where
|
/// The TCP client needs to wait until a broker has mapped all pages before shutting down.
|
||||||
E: HasObservers + Executor<Self, <S::Corpus as Corpus>::Input, S, Z>,
|
/// Otherwise, the OS may already have removed the shared maps.
|
||||||
E::Observers: Serialize + ObserversTuple<S::Input, S>,
|
fn await_restart_safe(&mut self) {
|
||||||
for<'a> E::Observers: Deserialize<'a>,
|
// wait until we can drop the message safely.
|
||||||
EMH: EventManagerHooksTuple<S>,
|
//self.tcp.await_safe_to_unmap_blocking();
|
||||||
S: State + HasExecutions + HasMetadata + HasLastReportTime + HasImported + HasCorpus,
|
}
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
|
||||||
Z: ExecutionProcessor<Self, <S::Corpus as Corpus>::Input, E::Observers, S>
|
fn send_exiting(&mut self) -> Result<(), Error> {
|
||||||
+ EvaluatorObservers<E, Self, <S::Corpus as Corpus>::Input, S>,
|
//TODO: Should not be needed since TCP does that for us
|
||||||
{
|
//self.tcp.sender.send_exiting()
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EMH, S> ProgressReporter for TcpEventManager<EMH, S>
|
impl<EMH, S> ProgressReporter<S> for TcpEventManager<EMH, S>
|
||||||
where
|
where
|
||||||
EMH: EventManagerHooksTuple<S>,
|
EMH: EventManagerHooksTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
S: State + HasExecutions + HasMetadata + HasLastReportTime,
|
<S::Corpus as Corpus>::Input: Serialize,
|
||||||
|
S: HasExecutions + HasMetadata + HasLastReportTime + HasCorpus + MaybeHasClientPerfMonitor,
|
||||||
{
|
{
|
||||||
|
fn maybe_report_progress(
|
||||||
|
&mut self,
|
||||||
|
state: &mut S,
|
||||||
|
monitor_timeout: Duration,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
std_maybe_report_progress(self, state, monitor_timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn report_progress(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
|
std_report_progress(self, state)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EMH, S> HasEventManagerId for TcpEventManager<EMH, S>
|
impl<EMH, S> HasEventManagerId for TcpEventManager<EMH, S> {
|
||||||
where
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State,
|
|
||||||
{
|
|
||||||
/// Gets the id assigned to this staterestorer.
|
/// Gets the id assigned to this staterestorer.
|
||||||
fn mgr_id(&self) -> EventManagerId {
|
fn mgr_id(&self) -> EventManagerId {
|
||||||
EventManagerId(self.client_id.0 as usize)
|
EventManagerId(self.client_id.0 as usize)
|
||||||
@ -836,10 +803,7 @@ where
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TcpRestartingEventManager<EMH, S, SP>
|
pub struct TcpRestartingEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
EMH: EventManagerHooksTuple<S>,
|
SP: ShMemProvider,
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider + 'static,
|
|
||||||
//CE: CustomEvent<I>,
|
|
||||||
{
|
{
|
||||||
/// The embedded TCP event manager
|
/// The embedded TCP event manager
|
||||||
tcp_mgr: TcpEventManager<EMH, S>,
|
tcp_mgr: TcpEventManager<EMH, S>,
|
||||||
@ -849,29 +813,33 @@ where
|
|||||||
save_state: bool,
|
save_state: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EMH, S, SP> UsesState for TcpRestartingEventManager<EMH, S, SP>
|
impl<EMH, S, SP> ProgressReporter<S> for TcpRestartingEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
EMH: EventManagerHooksTuple<S>,
|
EMH: EventManagerHooksTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
S: State,
|
S: HasMetadata + HasExecutions + HasLastReportTime + HasCorpus + MaybeHasClientPerfMonitor,
|
||||||
SP: ShMemProvider + 'static,
|
<S::Corpus as Corpus>::Input: Serialize,
|
||||||
{
|
|
||||||
type State = S;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<EMH, S, SP> ProgressReporter for TcpRestartingEventManager<EMH, S, SP>
|
|
||||||
where
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State + HasExecutions + HasMetadata + HasLastReportTime,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
|
fn maybe_report_progress(
|
||||||
|
&mut self,
|
||||||
|
state: &mut S,
|
||||||
|
monitor_timeout: Duration,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
std_maybe_report_progress(self, state, monitor_timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn report_progress(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
|
std_report_progress(self, state)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EMH, S, SP> EventFirer for TcpRestartingEventManager<EMH, S, SP>
|
impl<EMH, S, SP> EventFirer<<S::Corpus as Corpus>::Input, S>
|
||||||
|
for TcpRestartingEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
EMH: EventManagerHooksTuple<S>,
|
EMH: EventManagerHooksTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
|
S: HasCorpus,
|
||||||
|
<S::Corpus as Corpus>::Input: Serialize,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
S: State,
|
|
||||||
//CE: CustomEvent<I>,
|
|
||||||
{
|
{
|
||||||
fn should_send(&self) -> bool {
|
fn should_send(&self) -> bool {
|
||||||
self.tcp_mgr.should_send()
|
self.tcp_mgr.should_send()
|
||||||
@ -879,8 +847,8 @@ where
|
|||||||
|
|
||||||
fn fire(
|
fn fire(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut Self::State,
|
state: &mut S,
|
||||||
event: Event<<Self::State as UsesInput>::Input>,
|
event: Event<<S::Corpus as Corpus>::Input>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
// Check if we are going to crash in the event, in which case we store our current state for the next runner
|
// Check if we are going to crash in the event, in which case we store our current state for the next runner
|
||||||
self.tcp_mgr.fire(state, event)
|
self.tcp_mgr.fire(state, event)
|
||||||
@ -891,12 +859,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EMH, S, SP> EventRestarter for TcpRestartingEventManager<EMH, S, SP>
|
impl<EMH, S, SP> ManagerExit for TcpRestartingEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State + HasExecutions,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
//CE: CustomEvent<I>,
|
|
||||||
{
|
{
|
||||||
/// The tcp client needs to wait until a broker mapped all pages, before shutting down.
|
/// The tcp client needs to wait until a broker mapped all pages, before shutting down.
|
||||||
/// Otherwise, the OS may already have removed the shared maps,
|
/// Otherwise, the OS may already have removed the shared maps,
|
||||||
@ -905,6 +870,20 @@ where
|
|||||||
self.tcp_mgr.await_restart_safe();
|
self.tcp_mgr.await_restart_safe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_exiting(&mut self) -> Result<(), Error> {
|
||||||
|
self.staterestorer.send_exiting();
|
||||||
|
// Also inform the broker that we are about to exit.
|
||||||
|
// This way, the broker can clean up the pages, and eventually exit.
|
||||||
|
self.tcp_mgr.send_exiting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<EMH, S, SP> EventRestarter<S> for TcpRestartingEventManager<EMH, S, SP>
|
||||||
|
where
|
||||||
|
EMH: EventManagerHooksTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
|
S: HasCorpus + HasExecutions + HasCurrentStageId + Serialize,
|
||||||
|
SP: ShMemProvider,
|
||||||
|
{
|
||||||
/// Reset the single page (we reuse it over and over from pos 0), then send the current state to the next runner.
|
/// Reset the single page (we reuse it over and over from pos 0), then send the current state to the next runner.
|
||||||
fn on_restart(&mut self, state: &mut S) -> Result<(), Error> {
|
fn on_restart(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
state.on_restart()?;
|
state.on_restart()?;
|
||||||
@ -920,24 +899,17 @@ where
|
|||||||
self.await_restart_safe();
|
self.await_restart_safe();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_exiting(&mut self) -> Result<(), Error> {
|
|
||||||
self.staterestorer.send_exiting();
|
|
||||||
// Also inform the broker that we are about to exit.
|
|
||||||
// This way, the broker can clean up the pages, and eventually exit.
|
|
||||||
self.tcp_mgr.send_exiting()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, EMH, S, SP, Z> EventProcessor<E, Z> for TcpRestartingEventManager<EMH, S, SP>
|
impl<E, EMH, S, SP, Z> EventProcessor<E, S, Z> for TcpRestartingEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
E: HasObservers + Executor<TcpEventManager<EMH, S>, <S::Corpus as Corpus>::Input, S, Z>,
|
E: HasObservers + Executor<TcpEventManager<EMH, S>, <S::Corpus as Corpus>::Input, S, Z>,
|
||||||
for<'a> E::Observers: Deserialize<'a>,
|
for<'a> E::Observers: Deserialize<'a>,
|
||||||
E::Observers: ObserversTuple<S::Input, S> + Serialize,
|
E::Observers: ObserversTuple<<S::Corpus as Corpus>::Input, S> + Serialize,
|
||||||
EMH: EventManagerHooksTuple<S>,
|
EMH: EventManagerHooksTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
S: State + HasExecutions + HasMetadata + HasImported + HasCorpus,
|
S: HasExecutions + HasMetadata + HasImported + HasCorpus + Stoppable,
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
<S::Corpus as Corpus>::Input: DeserializeOwned,
|
||||||
SP: ShMemProvider + 'static,
|
SP: ShMemProvider,
|
||||||
Z: ExecutionProcessor<TcpEventManager<EMH, S>, <S::Corpus as Corpus>::Input, E::Observers, S>
|
Z: ExecutionProcessor<TcpEventManager<EMH, S>, <S::Corpus as Corpus>::Input, E::Observers, S>
|
||||||
+ EvaluatorObservers<E, TcpEventManager<EMH, S>, <S::Corpus as Corpus>::Input, S>,
|
+ EvaluatorObservers<E, TcpEventManager<EMH, S>, <S::Corpus as Corpus>::Input, S>,
|
||||||
{
|
{
|
||||||
@ -950,25 +922,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, EMH, S, SP, Z> EventManager<E, Z> for TcpRestartingEventManager<EMH, S, SP>
|
|
||||||
where
|
|
||||||
E: HasObservers + Executor<TcpEventManager<EMH, S>, <S::Corpus as Corpus>::Input, S, Z>,
|
|
||||||
E::Observers: ObserversTuple<S::Input, S> + Serialize,
|
|
||||||
for<'a> E::Observers: Deserialize<'a>,
|
|
||||||
EMH: EventManagerHooksTuple<S>,
|
|
||||||
S: State + HasExecutions + HasMetadata + HasLastReportTime + HasImported + HasCorpus,
|
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
|
||||||
SP: ShMemProvider + 'static,
|
|
||||||
Z: ExecutionProcessor<TcpEventManager<EMH, S>, <S::Corpus as Corpus>::Input, E::Observers, S>
|
|
||||||
+ EvaluatorObservers<E, TcpEventManager<EMH, S>, <S::Corpus as Corpus>::Input, S>,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<EMH, S, SP> HasEventManagerId for TcpRestartingEventManager<EMH, S, SP>
|
impl<EMH, S, SP> HasEventManagerId for TcpRestartingEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
EMH: EventManagerHooksTuple<S>,
|
SP: ShMemProvider,
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider + 'static,
|
|
||||||
{
|
{
|
||||||
fn mgr_id(&self) -> EventManagerId {
|
fn mgr_id(&self) -> EventManagerId {
|
||||||
self.tcp_mgr.mgr_id()
|
self.tcp_mgr.mgr_id()
|
||||||
@ -983,9 +939,9 @@ const _ENV_FUZZER_BROKER_CLIENT_INITIAL: &str = "_AFL_ENV_FUZZER_BROKER_CLIENT";
|
|||||||
|
|
||||||
impl<EMH, S, SP> TcpRestartingEventManager<EMH, S, SP>
|
impl<EMH, S, SP> TcpRestartingEventManager<EMH, S, SP>
|
||||||
where
|
where
|
||||||
EMH: EventManagerHooksTuple<S>,
|
EMH: EventManagerHooksTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
S: State,
|
S: HasCorpus,
|
||||||
SP: ShMemProvider + 'static,
|
SP: ShMemProvider,
|
||||||
//CE: CustomEvent<I>,
|
//CE: CustomEvent<I>,
|
||||||
{
|
{
|
||||||
/// Create a new runner, the executed child doing the actual fuzzing.
|
/// Create a new runner, the executed child doing the actual fuzzing.
|
||||||
@ -1053,8 +1009,8 @@ pub fn setup_restarting_mgr_tcp<MT, S>(
|
|||||||
>
|
>
|
||||||
where
|
where
|
||||||
MT: Monitor + Clone,
|
MT: Monitor + Clone,
|
||||||
S: State + HasExecutions + HasMetadata + HasImported + HasCorpus,
|
S: HasExecutions + HasMetadata + HasImported + HasCorpus + DeserializeOwned + Stoppable,
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
<S::Corpus as Corpus>::Input: Input,
|
||||||
{
|
{
|
||||||
TcpRestartingMgr::builder()
|
TcpRestartingMgr::builder()
|
||||||
.shmem_provider(StdShMemProvider::new()?)
|
.shmem_provider(StdShMemProvider::new()?)
|
||||||
@ -1074,10 +1030,9 @@ where
|
|||||||
#[derive(TypedBuilder, Debug)]
|
#[derive(TypedBuilder, Debug)]
|
||||||
pub struct TcpRestartingMgr<EMH, MT, S, SP>
|
pub struct TcpRestartingMgr<EMH, MT, S, SP>
|
||||||
where
|
where
|
||||||
S: UsesInput + DeserializeOwned,
|
S: DeserializeOwned,
|
||||||
SP: ShMemProvider + 'static,
|
SP: ShMemProvider + 'static,
|
||||||
MT: Monitor,
|
MT: Monitor,
|
||||||
//CE: CustomEvent<I>,
|
|
||||||
{
|
{
|
||||||
/// The shared memory provider to use for the broker or client spawned by the restarting
|
/// The shared memory provider to use for the broker or client spawned by the restarting
|
||||||
/// manager.
|
/// manager.
|
||||||
@ -1116,10 +1071,10 @@ where
|
|||||||
#[expect(clippy::type_complexity, clippy::too_many_lines)]
|
#[expect(clippy::type_complexity, clippy::too_many_lines)]
|
||||||
impl<EMH, MT, S, SP> TcpRestartingMgr<EMH, MT, S, SP>
|
impl<EMH, MT, S, SP> TcpRestartingMgr<EMH, MT, S, SP>
|
||||||
where
|
where
|
||||||
EMH: EventManagerHooksTuple<S> + Copy + Clone,
|
EMH: EventManagerHooksTuple<<S::Corpus as Corpus>::Input, S> + Copy + Clone,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
S: State + HasExecutions + HasMetadata + HasImported + HasCorpus,
|
S: HasExecutions + HasMetadata + HasImported + HasCorpus + DeserializeOwned + Stoppable,
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
<S::Corpus as Corpus>::Input: Input,
|
||||||
MT: Monitor + Clone,
|
MT: Monitor + Clone,
|
||||||
{
|
{
|
||||||
/// Launch the restarting manager
|
/// Launch the restarting manager
|
||||||
@ -1127,7 +1082,8 @@ where
|
|||||||
// We start ourself as child process to actually fuzz
|
// We start ourself as child process to actually fuzz
|
||||||
let (staterestorer, _new_shmem_provider, core_id) = if env::var(_ENV_FUZZER_SENDER).is_err()
|
let (staterestorer, _new_shmem_provider, core_id) = if env::var(_ENV_FUZZER_SENDER).is_err()
|
||||||
{
|
{
|
||||||
let broker_things = |mut broker: TcpEventBroker<S::Input, MT>, _remote_broker_addr| {
|
let broker_things = |mut broker: TcpEventBroker<<S::Corpus as Corpus>::Input, MT>,
|
||||||
|
_remote_broker_addr| {
|
||||||
if let Some(exit_cleanly_after) = self.exit_cleanly_after {
|
if let Some(exit_cleanly_after) = self.exit_cleanly_after {
|
||||||
broker.set_exit_cleanly_after(exit_cleanly_after);
|
broker.set_exit_cleanly_after(exit_cleanly_after);
|
||||||
}
|
}
|
||||||
@ -1141,10 +1097,11 @@ where
|
|||||||
let connection = create_nonblocking_listener(("127.0.0.1", self.broker_port));
|
let connection = create_nonblocking_listener(("127.0.0.1", self.broker_port));
|
||||||
match connection {
|
match connection {
|
||||||
Ok(listener) => {
|
Ok(listener) => {
|
||||||
let event_broker = TcpEventBroker::<S::Input, MT>::with_listener(
|
let event_broker =
|
||||||
listener,
|
TcpEventBroker::<<S::Corpus as Corpus>::Input, MT>::with_listener(
|
||||||
self.monitor.take().unwrap(),
|
listener,
|
||||||
);
|
self.monitor.take().unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
// Yep, broker. Just loop here.
|
// Yep, broker. Just loop here.
|
||||||
log::info!(
|
log::info!(
|
||||||
@ -1172,7 +1129,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TcpManagerKind::Broker => {
|
TcpManagerKind::Broker => {
|
||||||
let event_broker = TcpEventBroker::<S::Input, MT>::new(
|
let event_broker = TcpEventBroker::<<S::Corpus as Corpus>::Input, MT>::new(
|
||||||
format!("127.0.0.1:{}", self.broker_port),
|
format!("127.0.0.1:{}", self.broker_port),
|
||||||
self.monitor.take().unwrap(),
|
self.monitor.take().unwrap(),
|
||||||
)?;
|
)?;
|
||||||
|
@ -747,7 +747,7 @@ impl CommandExecutorBuilder {
|
|||||||
/// # Example
|
/// # Example
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::{io::Write, process::{Stdio, Command, Child}, time::Duration};
|
/// use std::{io::Write, process::{Stdio, Command, Child}, time::Duration};
|
||||||
/// use libafl::{Error, corpus::Corpus, inputs::{BytesInput, HasTargetBytes, Input, UsesInput}, executors::{Executor, command::CommandConfigurator}, state::{HasCorpus, UsesState, HasExecutions}};
|
/// use libafl::{Error, corpus::Corpus, inputs::{BytesInput, HasTargetBytes, Input}, executors::{Executor, command::CommandConfigurator}, state::{HasCorpus, HasExecutions}};
|
||||||
/// use libafl_bolts::AsSlice;
|
/// use libafl_bolts::AsSlice;
|
||||||
/// #[derive(Debug)]
|
/// #[derive(Debug)]
|
||||||
/// struct MyExecutor;
|
/// struct MyExecutor;
|
||||||
@ -779,10 +779,8 @@ impl CommandExecutorBuilder {
|
|||||||
///
|
///
|
||||||
/// fn make_executor<EM, S, Z>() -> impl Executor<EM, BytesInput, S, Z>
|
/// fn make_executor<EM, S, Z>() -> impl Executor<EM, BytesInput, S, Z>
|
||||||
/// where
|
/// where
|
||||||
/// EM: UsesState,
|
|
||||||
/// EM::State: UsesInput<Input = BytesInput> + HasExecutions,
|
|
||||||
/// S: HasCorpus + HasExecutions,
|
/// S: HasCorpus + HasExecutions,
|
||||||
/// S::Corpus: Corpus<Input = BytesInput>,
|
/// S::Corpus: Corpus<Input = BytesInput>
|
||||||
/// {
|
/// {
|
||||||
/// MyExecutor.into_executor(())
|
/// MyExecutor.into_executor(())
|
||||||
/// }
|
/// }
|
||||||
@ -877,7 +875,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[cfg_attr(miri, ignore)]
|
#[cfg_attr(miri, ignore)]
|
||||||
fn test_builder() {
|
fn test_builder() {
|
||||||
let mut mgr: SimpleEventManager<_, NopState<NopInput>> =
|
let mut mgr: SimpleEventManager<NopInput, _, NopState<NopInput>> =
|
||||||
SimpleEventManager::new(SimpleMonitor::new(|status| {
|
SimpleEventManager::new(SimpleMonitor::new(|status| {
|
||||||
log::info!("{status}");
|
log::info!("{status}");
|
||||||
}));
|
}));
|
||||||
|
@ -29,7 +29,6 @@ use crate::{
|
|||||||
events::{EventFirer, EventRestarter},
|
events::{EventFirer, EventRestarter},
|
||||||
executors::{hooks::ExecutorHook, inprocess::HasInProcessHooks, Executor, HasObservers},
|
executors::{hooks::ExecutorHook, inprocess::HasInProcessHooks, Executor, HasObservers},
|
||||||
feedbacks::Feedback,
|
feedbacks::Feedback,
|
||||||
inputs::UsesInput,
|
|
||||||
state::{HasCorpus, HasExecutions, HasSolutions},
|
state::{HasCorpus, HasExecutions, HasSolutions},
|
||||||
Error, HasObjective,
|
Error, HasObjective,
|
||||||
};
|
};
|
||||||
@ -222,9 +221,9 @@ impl<I, S> InProcessHooks<I, S> {
|
|||||||
where
|
where
|
||||||
E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>,
|
E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>,
|
||||||
E::Observers: ObserversTuple<I, S>,
|
E::Observers: ObserversTuple<I, S>,
|
||||||
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, E::Observers, S>,
|
OF: Feedback<EM, I, E::Observers, S>,
|
||||||
S: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase + UsesInput<Input = I>,
|
S: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
I: Input + Clone,
|
I: Input + Clone,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
@ -266,10 +265,10 @@ impl<I, S> InProcessHooks<I, S> {
|
|||||||
where
|
where
|
||||||
E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>,
|
E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>,
|
||||||
E::Observers: ObserversTuple<I, S>,
|
E::Observers: ObserversTuple<I, S>,
|
||||||
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
I: Input + Clone,
|
I: Input + Clone,
|
||||||
OF: Feedback<EM, I, E::Observers, S>,
|
OF: Feedback<EM, I, E::Observers, S>,
|
||||||
S: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase + UsesInput<Input = I>,
|
S: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
@ -329,9 +328,9 @@ impl<I, S> InProcessHooks<I, S> {
|
|||||||
pub fn new<E, EM, OF, Z>(exec_tmout: Duration) -> Result<Self, Error>
|
pub fn new<E, EM, OF, Z>(exec_tmout: Duration) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>,
|
E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>,
|
||||||
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, E::Observers, S>,
|
OF: Feedback<EM, I, E::Observers, S>,
|
||||||
S: HasExecutions + HasSolutions + HasCorpus + UsesInput<Input = I>,
|
S: HasExecutions + HasSolutions + HasCorpus,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
#[cfg_attr(miri, allow(unused_variables))]
|
#[cfg_attr(miri, allow(unused_variables))]
|
||||||
@ -469,7 +468,7 @@ pub(crate) static mut GLOBAL_STATE: InProcessExecutorHandlerData = InProcessExec
|
|||||||
critical: null_mut(),
|
critical: null_mut(),
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Get the inprocess [`crate::state::State`]
|
/// Get the inprocess State
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// Only safe if not called twice and if the state is not accessed from another borrow while this one is alive.
|
/// Only safe if not called twice and if the state is not accessed from another borrow while this one is alive.
|
||||||
@ -478,7 +477,7 @@ pub unsafe fn inprocess_get_state<'a, S>() -> Option<&'a mut S> {
|
|||||||
unsafe { (GLOBAL_STATE.state_ptr as *mut S).as_mut() }
|
unsafe { (GLOBAL_STATE.state_ptr as *mut S).as_mut() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the [`crate::events::EventManager`]
|
/// Get the `EventManager`
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// Only safe if not called twice and if the event manager is not accessed from another borrow while this one is alive.
|
/// Only safe if not called twice and if the event manager is not accessed from another borrow while this one is alive.
|
||||||
|
@ -19,7 +19,7 @@ pub mod unix_signal_handler {
|
|||||||
},
|
},
|
||||||
feedbacks::Feedback,
|
feedbacks::Feedback,
|
||||||
fuzzer::HasObjective,
|
fuzzer::HasObjective,
|
||||||
inputs::{Input, UsesInput},
|
inputs::Input,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions},
|
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions},
|
||||||
};
|
};
|
||||||
@ -81,9 +81,9 @@ pub mod unix_signal_handler {
|
|||||||
where
|
where
|
||||||
E: Executor<EM, I, S, Z> + HasObservers,
|
E: Executor<EM, I, S, Z> + HasObservers,
|
||||||
E::Observers: ObserversTuple<I, S>,
|
E::Observers: ObserversTuple<I, S>,
|
||||||
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, E::Observers, S>,
|
OF: Feedback<EM, I, E::Observers, S>,
|
||||||
S: HasExecutions + HasSolutions + HasCurrentTestcase + HasCorpus + UsesInput<Input = I>,
|
S: HasExecutions + HasSolutions + HasCurrentTestcase + HasCorpus,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
I: Input + Clone,
|
I: Input + Clone,
|
||||||
@ -131,9 +131,9 @@ pub mod unix_signal_handler {
|
|||||||
) where
|
) where
|
||||||
E: Executor<EM, I, S, Z> + HasInProcessHooks<I, S> + HasObservers,
|
E: Executor<EM, I, S, Z> + HasInProcessHooks<I, S> + HasObservers,
|
||||||
E::Observers: ObserversTuple<I, S>,
|
E::Observers: ObserversTuple<I, S>,
|
||||||
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, E::Observers, S>,
|
OF: Feedback<EM, I, E::Observers, S>,
|
||||||
S: HasExecutions + HasSolutions + HasCurrentTestcase + HasCorpus + UsesInput<Input = I>,
|
S: HasExecutions + HasSolutions + HasCurrentTestcase + HasCorpus,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
I: Input + Clone,
|
I: Input + Clone,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
@ -188,9 +188,9 @@ pub mod unix_signal_handler {
|
|||||||
) where
|
) where
|
||||||
E: Executor<EM, I, S, Z> + HasObservers,
|
E: Executor<EM, I, S, Z> + HasObservers,
|
||||||
E::Observers: ObserversTuple<I, S>,
|
E::Observers: ObserversTuple<I, S>,
|
||||||
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, E::Observers, S>,
|
OF: Feedback<EM, I, E::Observers, S>,
|
||||||
S: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase + UsesInput<Input = I>,
|
S: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
I: Input + Clone,
|
I: Input + Clone,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
|
@ -17,7 +17,7 @@ pub mod windows_asan_handler {
|
|||||||
},
|
},
|
||||||
feedbacks::Feedback,
|
feedbacks::Feedback,
|
||||||
fuzzer::HasObjective,
|
fuzzer::HasObjective,
|
||||||
inputs::{Input, UsesInput},
|
inputs::Input,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions},
|
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions},
|
||||||
};
|
};
|
||||||
@ -28,10 +28,10 @@ pub mod windows_asan_handler {
|
|||||||
where
|
where
|
||||||
E: Executor<EM, I, S, Z> + HasObservers,
|
E: Executor<EM, I, S, Z> + HasObservers,
|
||||||
E::Observers: ObserversTuple<I, S>,
|
E::Observers: ObserversTuple<I, S>,
|
||||||
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
I: Input + Clone,
|
I: Input + Clone,
|
||||||
OF: Feedback<EM, I, E::Observers, S>,
|
OF: Feedback<EM, I, E::Observers, S>,
|
||||||
S: HasExecutions + HasSolutions + HasCurrentTestcase + HasCorpus + UsesInput<Input = I>,
|
S: HasExecutions + HasSolutions + HasCurrentTestcase + HasCorpus,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
@ -136,7 +136,7 @@ pub mod windows_exception_handler {
|
|||||||
},
|
},
|
||||||
feedbacks::Feedback,
|
feedbacks::Feedback,
|
||||||
fuzzer::HasObjective,
|
fuzzer::HasObjective,
|
||||||
inputs::{Input, UsesInput},
|
inputs::Input,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions},
|
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions},
|
||||||
};
|
};
|
||||||
@ -186,10 +186,10 @@ pub mod windows_exception_handler {
|
|||||||
where
|
where
|
||||||
E: Executor<EM, I, S, Z> + HasObservers,
|
E: Executor<EM, I, S, Z> + HasObservers,
|
||||||
E::Observers: ObserversTuple<I, S>,
|
E::Observers: ObserversTuple<I, S>,
|
||||||
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
I: Input + Clone,
|
I: Input + Clone,
|
||||||
OF: Feedback<EM, I, E::Observers, S>,
|
OF: Feedback<EM, I, E::Observers, S>,
|
||||||
S: HasExecutions + HasSolutions + HasCurrentTestcase + HasCorpus + UsesInput<Input = I>,
|
S: HasExecutions + HasSolutions + HasCurrentTestcase + HasCorpus,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
@ -249,10 +249,10 @@ pub mod windows_exception_handler {
|
|||||||
) where
|
) where
|
||||||
E: Executor<EM, I, S, Z> + HasInProcessHooks<I, S> + HasObservers,
|
E: Executor<EM, I, S, Z> + HasInProcessHooks<I, S> + HasObservers,
|
||||||
E::Observers: ObserversTuple<I, S>,
|
E::Observers: ObserversTuple<I, S>,
|
||||||
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
I: Input + Clone,
|
I: Input + Clone,
|
||||||
OF: Feedback<EM, I, E::Observers, S>,
|
OF: Feedback<EM, I, E::Observers, S>,
|
||||||
S: HasExecutions + HasSolutions + HasCurrentTestcase + HasCorpus + UsesInput<Input = I>,
|
S: HasExecutions + HasSolutions + HasCurrentTestcase + HasCorpus,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
{
|
{
|
||||||
@ -319,10 +319,10 @@ pub mod windows_exception_handler {
|
|||||||
) where
|
) where
|
||||||
E: Executor<EM, I, S, Z> + HasObservers,
|
E: Executor<EM, I, S, Z> + HasObservers,
|
||||||
E::Observers: ObserversTuple<I, S>,
|
E::Observers: ObserversTuple<I, S>,
|
||||||
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
I: Input + Clone,
|
I: Input + Clone,
|
||||||
OF: Feedback<EM, I, E::Observers, S>,
|
OF: Feedback<EM, I, E::Observers, S>,
|
||||||
S: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase + UsesInput<Input = I>,
|
S: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
feedbacks::Feedback,
|
feedbacks::Feedback,
|
||||||
fuzzer::HasObjective,
|
fuzzer::HasObjective,
|
||||||
inputs::{Input, UsesInput},
|
inputs::Input,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions},
|
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions},
|
||||||
Error,
|
Error,
|
||||||
@ -145,10 +145,10 @@ where
|
|||||||
where
|
where
|
||||||
E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>,
|
E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>,
|
||||||
E::Observers: ObserversTuple<I, S>,
|
E::Observers: ObserversTuple<I, S>,
|
||||||
EM: EventFirer<State = S> + EventRestarter,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
I: Input + Clone,
|
I: Input + Clone,
|
||||||
OF: Feedback<EM, I, E::Observers, S>,
|
OF: Feedback<EM, I, E::Observers, S>,
|
||||||
S: HasCurrentTestcase + HasCorpus + HasSolutions + UsesInput<Input = I>,
|
S: HasCurrentTestcase + HasCorpus + HasSolutions,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
@ -175,10 +175,10 @@ where
|
|||||||
where
|
where
|
||||||
E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>,
|
E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>,
|
||||||
E::Observers: ObserversTuple<I, S>,
|
E::Observers: ObserversTuple<I, S>,
|
||||||
EM: EventFirer<State = S> + EventRestarter,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
I: Input + Clone,
|
I: Input + Clone,
|
||||||
OF: Feedback<EM, I, E::Observers, S>,
|
OF: Feedback<EM, I, E::Observers, S>,
|
||||||
S: HasCurrentTestcase + HasCorpus + HasSolutions + UsesInput<Input = I>,
|
S: HasCurrentTestcase + HasCorpus + HasSolutions,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
@ -208,9 +208,9 @@ where
|
|||||||
where
|
where
|
||||||
E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>,
|
E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>,
|
||||||
E::Observers: ObserversTuple<I, S>,
|
E::Observers: ObserversTuple<I, S>,
|
||||||
EM: EventFirer<State = S> + EventRestarter,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, E::Observers, S>,
|
OF: Feedback<EM, I, E::Observers, S>,
|
||||||
S: HasCurrentTestcase + HasCorpus + HasSolutions + UsesInput<Input = I>,
|
S: HasCurrentTestcase + HasCorpus + HasSolutions,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
I: Input + Clone,
|
I: Input + Clone,
|
||||||
|
@ -28,7 +28,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
feedbacks::Feedback,
|
feedbacks::Feedback,
|
||||||
fuzzer::HasObjective,
|
fuzzer::HasObjective,
|
||||||
inputs::{Input, UsesInput},
|
inputs::Input,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions},
|
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions},
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
@ -124,7 +124,7 @@ impl<'a, H, I, OT, S> InProcessExecutor<'a, H, I, OT, S>
|
|||||||
where
|
where
|
||||||
H: FnMut(&I) -> ExitKind + Sized,
|
H: FnMut(&I) -> ExitKind + Sized,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasCorpus + HasCurrentTestcase + UsesInput<Input = I> + HasExecutions + HasSolutions,
|
S: HasCorpus + HasCurrentTestcase + HasExecutions + HasSolutions,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
@ -137,7 +137,7 @@ where
|
|||||||
event_mgr: &mut EM,
|
event_mgr: &mut EM,
|
||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S> + EventRestarter,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, OT, S>,
|
OF: Feedback<EM, I, OT, S>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
@ -163,7 +163,7 @@ where
|
|||||||
exec_tmout: Duration,
|
exec_tmout: Duration,
|
||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S> + EventRestarter,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, OT, S>,
|
OF: Feedback<EM, I, OT, S>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
@ -200,7 +200,7 @@ where
|
|||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S> + EventRestarter,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, OT, S>,
|
OF: Feedback<EM, I, OT, S>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
@ -227,7 +227,7 @@ where
|
|||||||
HB: BorrowMut<H>,
|
HB: BorrowMut<H>,
|
||||||
HT: ExecutorHooksTuple<I, S>,
|
HT: ExecutorHooksTuple<I, S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasCorpus + HasCurrentTestcase + UsesInput<Input = I> + HasExecutions + HasSolutions,
|
S: HasCorpus + HasCurrentTestcase + HasExecutions + HasSolutions,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
@ -241,7 +241,7 @@ where
|
|||||||
event_mgr: &mut EM,
|
event_mgr: &mut EM,
|
||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S> + EventRestarter,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, OT, S>,
|
OF: Feedback<EM, I, OT, S>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
@ -268,7 +268,8 @@ where
|
|||||||
exec_tmout: Duration,
|
exec_tmout: Duration,
|
||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S> + EventRestarter,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
|
|
||||||
OF: Feedback<EM, I, OT, S>,
|
OF: Feedback<EM, I, OT, S>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
@ -301,7 +302,7 @@ where
|
|||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S> + EventRestarter,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, OT, S>,
|
OF: Feedback<EM, I, OT, S>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
@ -378,9 +379,9 @@ pub fn run_observers_and_save_state<E, EM, I, OF, S, Z>(
|
|||||||
) where
|
) where
|
||||||
E: Executor<EM, I, S, Z> + HasObservers,
|
E: Executor<EM, I, S, Z> + HasObservers,
|
||||||
E::Observers: ObserversTuple<I, S>,
|
E::Observers: ObserversTuple<I, S>,
|
||||||
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, E::Observers, S>,
|
OF: Feedback<EM, I, E::Observers, S>,
|
||||||
S: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase + UsesInput<Input = I>,
|
S: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
I: Input + Clone,
|
I: Input + Clone,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
@ -440,9 +441,9 @@ pub unsafe fn generic_inproc_crash_handler<E, EM, I, OF, S, Z>()
|
|||||||
where
|
where
|
||||||
E: Executor<EM, I, S, Z> + HasObservers,
|
E: Executor<EM, I, S, Z> + HasObservers,
|
||||||
E::Observers: ObserversTuple<I, S>,
|
E::Observers: ObserversTuple<I, S>,
|
||||||
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, E::Observers, S>,
|
OF: Feedback<EM, I, E::Observers, S>,
|
||||||
S: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase + UsesInput<Input = I>,
|
S: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase,
|
||||||
I: Input + Clone,
|
I: Input + Clone,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
Z: HasObjective<Objective = OF> + ExecutionProcessor<EM, I, E::Observers, S>,
|
Z: HasObjective<Objective = OF> + ExecutionProcessor<EM, I, E::Observers, S>,
|
||||||
@ -479,16 +480,12 @@ mod tests {
|
|||||||
events::NopEventManager,
|
events::NopEventManager,
|
||||||
executors::{Executor, ExitKind, InProcessExecutor},
|
executors::{Executor, ExitKind, InProcessExecutor},
|
||||||
feedbacks::CrashFeedback,
|
feedbacks::CrashFeedback,
|
||||||
inputs::{NopInput, UsesInput},
|
inputs::NopInput,
|
||||||
schedulers::RandScheduler,
|
schedulers::RandScheduler,
|
||||||
state::{NopState, StdState},
|
state::{NopState, StdState},
|
||||||
StdFuzzer,
|
StdFuzzer,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl UsesInput for () {
|
|
||||||
type Input = NopInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_inmem_exec() {
|
fn test_inmem_exec() {
|
||||||
let mut harness = |_buf: &NopInput| ExitKind::Ok;
|
let mut harness = |_buf: &NopInput| ExitKind::Ok;
|
||||||
|
@ -20,7 +20,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
feedbacks::Feedback,
|
feedbacks::Feedback,
|
||||||
fuzzer::HasObjective,
|
fuzzer::HasObjective,
|
||||||
inputs::{Input, UsesInput},
|
inputs::Input,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions},
|
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions},
|
||||||
Error,
|
Error,
|
||||||
@ -124,7 +124,7 @@ impl<'a, H, I, OT, S, ES> StatefulInProcessExecutor<'a, H, I, OT, S, ES>
|
|||||||
where
|
where
|
||||||
H: FnMut(&mut ES, &mut S, &I) -> ExitKind + Sized,
|
H: FnMut(&mut ES, &mut S, &I) -> ExitKind + Sized,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase + UsesInput<Input = I>,
|
S: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase,
|
||||||
I: Clone + Input,
|
I: Clone + Input,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
{
|
{
|
||||||
@ -138,7 +138,7 @@ where
|
|||||||
event_mgr: &mut EM,
|
event_mgr: &mut EM,
|
||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S> + EventRestarter,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, OT, S>,
|
OF: Feedback<EM, I, OT, S>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
@ -166,7 +166,7 @@ where
|
|||||||
exec_tmout: Duration,
|
exec_tmout: Duration,
|
||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S> + EventRestarter,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, OT, S>,
|
OF: Feedback<EM, I, OT, S>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
@ -205,7 +205,7 @@ where
|
|||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S> + EventRestarter,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, OT, S>,
|
OF: Feedback<EM, I, OT, S>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
@ -246,12 +246,7 @@ where
|
|||||||
HT: ExecutorHooksTuple<I, S>,
|
HT: ExecutorHooksTuple<I, S>,
|
||||||
I: Input + Clone,
|
I: Input + Clone,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasCorpus
|
S: HasCorpus + HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase,
|
||||||
+ HasExecutions
|
|
||||||
+ HasSolutions
|
|
||||||
+ HasCorpus
|
|
||||||
+ HasCurrentTestcase
|
|
||||||
+ UsesInput<Input = I>,
|
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
{
|
{
|
||||||
/// Create a new in mem executor with the default timeout (5 sec)
|
/// Create a new in mem executor with the default timeout (5 sec)
|
||||||
@ -265,7 +260,7 @@ where
|
|||||||
event_mgr: &mut EM,
|
event_mgr: &mut EM,
|
||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S> + EventRestarter,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, OT, S>,
|
OF: Feedback<EM, I, OT, S>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
@ -295,7 +290,7 @@ where
|
|||||||
exec_tmout: Duration,
|
exec_tmout: Duration,
|
||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S> + EventRestarter,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, OT, S>,
|
OF: Feedback<EM, I, OT, S>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
@ -331,7 +326,7 @@ where
|
|||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S> + EventRestarter,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, OT, S>,
|
OF: Feedback<EM, I, OT, S>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
|
@ -382,7 +382,8 @@ mod tests {
|
|||||||
let input = NopInput {};
|
let input = NopInput {};
|
||||||
let mut fuzzer = NopFuzzer::new();
|
let mut fuzzer = NopFuzzer::new();
|
||||||
let mut state = NopState::new();
|
let mut state = NopState::new();
|
||||||
let mut mgr: SimpleEventManager<_, NopState<NopInput>> = SimpleEventManager::printing();
|
let mut mgr: SimpleEventManager<NopInput, _, NopState<NopInput>> =
|
||||||
|
SimpleEventManager::printing();
|
||||||
in_process_fork_executor
|
in_process_fork_executor
|
||||||
.run_target(&mut fuzzer, &mut state, &mut mgr, &input)
|
.run_target(&mut fuzzer, &mut state, &mut mgr, &input)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -221,7 +221,7 @@ mod test {
|
|||||||
let nonempty_input = BytesInput::new(vec![1u8]);
|
let nonempty_input = BytesInput::new(vec![1u8]);
|
||||||
let mut executor = NopExecutor::new();
|
let mut executor = NopExecutor::new();
|
||||||
let mut fuzzer = NopFuzzer::new();
|
let mut fuzzer = NopFuzzer::new();
|
||||||
let mut mgr: NopEventManager<NopState<BytesInput>> = NopEventManager::new();
|
let mut mgr: NopEventManager = NopEventManager::new();
|
||||||
let mut state: NopState<BytesInput> = NopState::new();
|
let mut state: NopState<BytesInput> = NopState::new();
|
||||||
|
|
||||||
executor
|
executor
|
||||||
|
@ -237,7 +237,7 @@ mod tests {
|
|||||||
DiffFeedback::<_, _, _>::is_interesting(
|
DiffFeedback::<_, _, _>::is_interesting(
|
||||||
&mut diff_feedback,
|
&mut diff_feedback,
|
||||||
&mut nop_state,
|
&mut nop_state,
|
||||||
&mut NopEventManager::<NopState<BytesInput>>::default(),
|
&mut NopEventManager::default(),
|
||||||
&BytesInput::new(vec![0]),
|
&BytesInput::new(vec![0]),
|
||||||
&observers,
|
&observers,
|
||||||
&ExitKind::Ok
|
&ExitKind::Ok
|
||||||
|
@ -21,13 +21,13 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
|||||||
#[cfg(feature = "track_hit_feedbacks")]
|
#[cfg(feature = "track_hit_feedbacks")]
|
||||||
use crate::feedbacks::premature_last_result_err;
|
use crate::feedbacks::premature_last_result_err;
|
||||||
use crate::{
|
use crate::{
|
||||||
corpus::Testcase,
|
corpus::{Corpus, Testcase},
|
||||||
events::{Event, EventFirer},
|
events::{Event, EventFirer},
|
||||||
executors::ExitKind,
|
executors::ExitKind,
|
||||||
feedbacks::{Feedback, HasObserverHandle, StateInitializer},
|
feedbacks::{Feedback, HasObserverHandle, StateInitializer},
|
||||||
inputs::UsesInput,
|
|
||||||
monitors::{AggregatorOps, UserStats, UserStatsValue},
|
monitors::{AggregatorOps, UserStats, UserStatsValue},
|
||||||
observers::{CanTrack, MapObserver},
|
observers::{CanTrack, MapObserver},
|
||||||
|
state::HasCorpus,
|
||||||
Error, HasMetadata, HasNamedMetadata,
|
Error, HasMetadata, HasNamedMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -395,13 +395,13 @@ where
|
|||||||
impl<C, EM, I, N, O, OT, R, S> Feedback<EM, I, OT, S> for MapFeedback<C, N, O, R>
|
impl<C, EM, I, N, O, OT, R, S> Feedback<EM, I, OT, S> for MapFeedback<C, N, O, R>
|
||||||
where
|
where
|
||||||
C: CanTrack + AsRef<O>,
|
C: CanTrack + AsRef<O>,
|
||||||
EM: EventFirer<State = S>,
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
N: IsNovel<O::Entry>,
|
N: IsNovel<O::Entry>,
|
||||||
O: MapObserver + for<'it> AsIter<'it, Item = O::Entry>,
|
O: MapObserver + for<'it> AsIter<'it, Item = O::Entry>,
|
||||||
O::Entry: 'static + Default + Debug + DeserializeOwned + Serialize,
|
O::Entry: 'static + Default + Debug + DeserializeOwned + Serialize,
|
||||||
OT: MatchName,
|
OT: MatchName,
|
||||||
R: Reducer<O::Entry>,
|
R: Reducer<O::Entry>,
|
||||||
S: HasNamedMetadata + UsesInput, // delete me
|
S: HasNamedMetadata + HasCorpus, // delete me
|
||||||
{
|
{
|
||||||
#[rustversion::nightly]
|
#[rustversion::nightly]
|
||||||
default fn is_interesting(
|
default fn is_interesting(
|
||||||
@ -538,10 +538,10 @@ where
|
|||||||
impl<C, O, EM, I, OT, S> Feedback<EM, I, OT, S> for MapFeedback<C, DifferentIsNovel, O, MaxReducer>
|
impl<C, O, EM, I, OT, S> Feedback<EM, I, OT, S> for MapFeedback<C, DifferentIsNovel, O, MaxReducer>
|
||||||
where
|
where
|
||||||
C: CanTrack + AsRef<O>,
|
C: CanTrack + AsRef<O>,
|
||||||
EM: EventFirer<State = S>,
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
O: MapObserver<Entry = u8> + for<'a> AsSlice<'a, Entry = u8> + for<'a> AsIter<'a, Item = u8>,
|
O: MapObserver<Entry = u8> + for<'a> AsSlice<'a, Entry = u8> + for<'a> AsIter<'a, Item = u8>,
|
||||||
OT: MatchName,
|
OT: MatchName,
|
||||||
S: HasNamedMetadata + UsesInput,
|
S: HasNamedMetadata + HasCorpus,
|
||||||
{
|
{
|
||||||
fn is_interesting(
|
fn is_interesting(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -14,10 +14,12 @@ use serde::Serialize;
|
|||||||
use crate::monitors::PerfFeature;
|
use crate::monitors::PerfFeature;
|
||||||
use crate::{
|
use crate::{
|
||||||
corpus::{Corpus, CorpusId, HasCurrentCorpusId, HasTestcase, Testcase},
|
corpus::{Corpus, CorpusId, HasCurrentCorpusId, HasTestcase, Testcase},
|
||||||
events::{Event, EventConfig, EventFirer, EventProcessor, ProgressReporter},
|
events::{
|
||||||
|
CanSerializeObserver, Event, EventConfig, EventFirer, EventProcessor, ProgressReporter,
|
||||||
|
},
|
||||||
executors::{Executor, ExitKind, HasObservers},
|
executors::{Executor, ExitKind, HasObservers},
|
||||||
feedbacks::Feedback,
|
feedbacks::Feedback,
|
||||||
inputs::{Input, UsesInput},
|
inputs::Input,
|
||||||
mark_feature_time,
|
mark_feature_time,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
schedulers::Scheduler,
|
schedulers::Scheduler,
|
||||||
@ -25,7 +27,7 @@ use crate::{
|
|||||||
start_timer,
|
start_timer,
|
||||||
state::{
|
state::{
|
||||||
HasCorpus, HasCurrentTestcase, HasExecutions, HasLastFoundTime, HasLastReportTime,
|
HasCorpus, HasCurrentTestcase, HasExecutions, HasLastFoundTime, HasLastReportTime,
|
||||||
HasSolutions, MaybeHasClientPerfMonitor, State, UsesState,
|
HasSolutions, MaybeHasClientPerfMonitor, Stoppable,
|
||||||
},
|
},
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
};
|
};
|
||||||
@ -307,13 +309,8 @@ impl<CS, EM, F, IF, OF, OT, S> ExecutionProcessor<EM, <S::Corpus as Corpus>::Inp
|
|||||||
for StdFuzzer<CS, F, IF, OF>
|
for StdFuzzer<CS, F, IF, OF>
|
||||||
where
|
where
|
||||||
CS: Scheduler<<S::Corpus as Corpus>::Input, S>,
|
CS: Scheduler<<S::Corpus as Corpus>::Input, S>,
|
||||||
EM: EventFirer<State = S>,
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S> + CanSerializeObserver<OT>,
|
||||||
S: HasCorpus
|
S: HasCorpus + MaybeHasClientPerfMonitor + HasCurrentTestcase + HasSolutions + HasLastFoundTime,
|
||||||
+ MaybeHasClientPerfMonitor
|
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>
|
|
||||||
+ HasCurrentTestcase
|
|
||||||
+ HasSolutions
|
|
||||||
+ HasLastFoundTime,
|
|
||||||
F: Feedback<EM, <S::Corpus as Corpus>::Input, OT, S>,
|
F: Feedback<EM, <S::Corpus as Corpus>::Input, OT, S>,
|
||||||
OF: Feedback<EM, <S::Corpus as Corpus>::Input, OT, S>,
|
OF: Feedback<EM, <S::Corpus as Corpus>::Input, OT, S>,
|
||||||
OT: ObserversTuple<<S::Corpus as Corpus>::Input, S> + Serialize,
|
OT: ObserversTuple<<S::Corpus as Corpus>::Input, S> + Serialize,
|
||||||
@ -397,7 +394,7 @@ where
|
|||||||
if manager.configuration() == EventConfig::AlwaysUnique {
|
if manager.configuration() == EventConfig::AlwaysUnique {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
manager.serialize_observers::<OT>(observers)?
|
manager.serialize_observers(observers)?
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -515,14 +512,13 @@ where
|
|||||||
CS: Scheduler<<S::Corpus as Corpus>::Input, S>,
|
CS: Scheduler<<S::Corpus as Corpus>::Input, S>,
|
||||||
E: HasObservers + Executor<EM, <S::Corpus as Corpus>::Input, S, Self>,
|
E: HasObservers + Executor<EM, <S::Corpus as Corpus>::Input, S, Self>,
|
||||||
E::Observers: MatchName + ObserversTuple<<S::Corpus as Corpus>::Input, S> + Serialize,
|
E::Observers: MatchName + ObserversTuple<<S::Corpus as Corpus>::Input, S> + Serialize,
|
||||||
EM: EventFirer<State = S>,
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S> + CanSerializeObserver<E::Observers>,
|
||||||
F: Feedback<EM, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
F: Feedback<EM, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
||||||
OF: Feedback<EM, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
OF: Feedback<EM, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
||||||
S: HasCorpus
|
S: HasCorpus
|
||||||
+ HasSolutions
|
+ HasSolutions
|
||||||
+ MaybeHasClientPerfMonitor
|
+ MaybeHasClientPerfMonitor
|
||||||
+ HasCurrentTestcase
|
+ HasCurrentTestcase
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>
|
|
||||||
+ HasExecutions
|
+ HasExecutions
|
||||||
+ HasLastFoundTime,
|
+ HasLastFoundTime,
|
||||||
<S::Corpus as Corpus>::Input: Input,
|
<S::Corpus as Corpus>::Input: Input,
|
||||||
@ -593,7 +589,7 @@ where
|
|||||||
CS: Scheduler<<S::Corpus as Corpus>::Input, S>,
|
CS: Scheduler<<S::Corpus as Corpus>::Input, S>,
|
||||||
E: HasObservers + Executor<EM, <S::Corpus as Corpus>::Input, S, Self>,
|
E: HasObservers + Executor<EM, <S::Corpus as Corpus>::Input, S, Self>,
|
||||||
E::Observers: MatchName + ObserversTuple<<S::Corpus as Corpus>::Input, S> + Serialize,
|
E::Observers: MatchName + ObserversTuple<<S::Corpus as Corpus>::Input, S> + Serialize,
|
||||||
EM: EventFirer<State = S>,
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S> + CanSerializeObserver<E::Observers>,
|
||||||
F: Feedback<EM, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
F: Feedback<EM, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
||||||
OF: Feedback<EM, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
OF: Feedback<EM, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
||||||
S: HasCorpus
|
S: HasCorpus
|
||||||
@ -601,8 +597,7 @@ where
|
|||||||
+ MaybeHasClientPerfMonitor
|
+ MaybeHasClientPerfMonitor
|
||||||
+ HasCurrentTestcase
|
+ HasCurrentTestcase
|
||||||
+ HasLastFoundTime
|
+ HasLastFoundTime
|
||||||
+ HasExecutions
|
+ HasExecutions,
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
<S::Corpus as Corpus>::Input: Input,
|
<S::Corpus as Corpus>::Input: Input,
|
||||||
S::Solutions: Corpus<Input = <S::Corpus as Corpus>::Input>,
|
S::Solutions: Corpus<Input = <S::Corpus as Corpus>::Input>,
|
||||||
IF: InputFilter<<S::Corpus as Corpus>::Input>,
|
IF: InputFilter<<S::Corpus as Corpus>::Input>,
|
||||||
@ -725,7 +720,7 @@ where
|
|||||||
let observers_buf = if manager.configuration() == EventConfig::AlwaysUnique {
|
let observers_buf = if manager.configuration() == EventConfig::AlwaysUnique {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
manager.serialize_observers::<E::Observers>(&*observers)?
|
manager.serialize_observers(&*observers)?
|
||||||
};
|
};
|
||||||
manager.fire(
|
manager.fire(
|
||||||
state,
|
state,
|
||||||
@ -747,8 +742,8 @@ where
|
|||||||
|
|
||||||
impl<CS, E, EM, F, IF, OF, S, ST> Fuzzer<E, EM, S, ST> for StdFuzzer<CS, F, IF, OF>
|
impl<CS, E, EM, F, IF, OF, S, ST> Fuzzer<E, EM, S, ST> for StdFuzzer<CS, F, IF, OF>
|
||||||
where
|
where
|
||||||
CS: Scheduler<S::Input, S>,
|
CS: Scheduler<<S::Corpus as Corpus>::Input, S>,
|
||||||
EM: ProgressReporter + EventProcessor<E, Self, State = S>,
|
EM: ProgressReporter<S> + EventProcessor<E, S, Self>,
|
||||||
S: HasExecutions
|
S: HasExecutions
|
||||||
+ HasMetadata
|
+ HasMetadata
|
||||||
+ HasCorpus
|
+ HasCorpus
|
||||||
@ -756,7 +751,8 @@ where
|
|||||||
+ HasTestcase
|
+ HasTestcase
|
||||||
+ HasCurrentCorpusId
|
+ HasCurrentCorpusId
|
||||||
+ HasCurrentStageId
|
+ HasCurrentStageId
|
||||||
+ State,
|
+ Stoppable
|
||||||
|
+ MaybeHasClientPerfMonitor,
|
||||||
ST: StagesTuple<E, EM, S, Self>,
|
ST: StagesTuple<E, EM, S, Self>,
|
||||||
{
|
{
|
||||||
fn fuzz_one(
|
fn fuzz_one(
|
||||||
@ -924,11 +920,7 @@ where
|
|||||||
CS: Scheduler<<S::Corpus as Corpus>::Input, S>,
|
CS: Scheduler<<S::Corpus as Corpus>::Input, S>,
|
||||||
E: Executor<EM, <S::Corpus as Corpus>::Input, S, Self> + HasObservers,
|
E: Executor<EM, <S::Corpus as Corpus>::Input, S, Self> + HasObservers,
|
||||||
E::Observers: ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
E::Observers: ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
EM: UsesState<State = S>,
|
S: HasExecutions + HasCorpus + MaybeHasClientPerfMonitor,
|
||||||
S: UsesInput<Input = <S::Corpus as Corpus>::Input>
|
|
||||||
+ HasExecutions
|
|
||||||
+ HasCorpus
|
|
||||||
+ MaybeHasClientPerfMonitor,
|
|
||||||
{
|
{
|
||||||
/// Runs the input and triggers observers and feedback
|
/// Runs the input and triggers observers and feedback
|
||||||
fn execute_input(
|
fn execute_input(
|
||||||
@ -976,15 +968,15 @@ impl Default for NopFuzzer {
|
|||||||
|
|
||||||
impl<E, EM, S, ST> Fuzzer<E, EM, S, ST> for NopFuzzer
|
impl<E, EM, S, ST> Fuzzer<E, EM, S, ST> for NopFuzzer
|
||||||
where
|
where
|
||||||
EM: ProgressReporter<State = S> + EventProcessor<E, Self>,
|
EM: ProgressReporter<S> + EventProcessor<E, S, Self>,
|
||||||
ST: StagesTuple<E, EM, S, Self>,
|
ST: StagesTuple<E, EM, S, Self>,
|
||||||
S: HasMetadata + HasExecutions + HasLastReportTime + HasCurrentStageId + UsesInput,
|
S: HasMetadata + HasExecutions + HasLastReportTime + HasCurrentStageId,
|
||||||
{
|
{
|
||||||
fn fuzz_one(
|
fn fuzz_one(
|
||||||
&mut self,
|
&mut self,
|
||||||
_stages: &mut ST,
|
_stages: &mut ST,
|
||||||
_executor: &mut E,
|
_executor: &mut E,
|
||||||
_state: &mut EM::State,
|
_state: &mut S,
|
||||||
_manager: &mut EM,
|
_manager: &mut EM,
|
||||||
) -> Result<CorpusId, Error> {
|
) -> Result<CorpusId, Error> {
|
||||||
unimplemented!("NopFuzzer cannot fuzz");
|
unimplemented!("NopFuzzer cannot fuzz");
|
||||||
|
@ -277,13 +277,6 @@ impl HasMutatorBytes for &mut Vec<u8> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines the input type shared across traits of the type.
|
|
||||||
/// Needed for consistency across HasCorpus/HasSolutions and friends.
|
|
||||||
pub trait UsesInput {
|
|
||||||
/// Type which will be used throughout this state.
|
|
||||||
type Input: Input;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// Basic `InputConverter` with just one type that is not converting
|
/// Basic `InputConverter` with just one type that is not converting
|
||||||
pub struct NopInputConverter<I> {
|
pub struct NopInputConverter<I> {
|
||||||
|
@ -914,26 +914,6 @@ pub struct ClientPerfMonitor {
|
|||||||
timer_start: Option<u64>,
|
timer_start: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
|
||||||
/// Count the imported testcase from other nodes that came with observers
|
|
||||||
pub struct ScalabilityMonitor {
|
|
||||||
/// Imported testcase received with observer
|
|
||||||
pub testcase_with_observers: usize,
|
|
||||||
/// Imported testcase received without observer
|
|
||||||
pub testcase_without_observers: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ScalabilityMonitor {
|
|
||||||
/// Constructor
|
|
||||||
#[must_use]
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
testcase_with_observers: 0,
|
|
||||||
testcase_without_observers: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Various features that are measured for performance
|
/// Various features that are measured for performance
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
|
@ -28,12 +28,12 @@ use crate::{observers::Observer, Error};
|
|||||||
/// events::{EventFirer, NopEventManager},
|
/// events::{EventFirer, NopEventManager},
|
||||||
/// executors::{CommandExecutor, ExitKind},
|
/// executors::{CommandExecutor, ExitKind},
|
||||||
/// feedbacks::{Feedback, StateInitializer},
|
/// feedbacks::{Feedback, StateInitializer},
|
||||||
/// inputs::{BytesInput, UsesInput},
|
/// inputs::BytesInput,
|
||||||
/// mutators::{MutationResult, NopMutator},
|
/// mutators::{MutationResult, NopMutator},
|
||||||
/// observers::{ObserversTuple, StdErrObserver, StdOutObserver},
|
/// observers::{ObserversTuple, StdErrObserver, StdOutObserver},
|
||||||
/// schedulers::QueueScheduler,
|
/// schedulers::QueueScheduler,
|
||||||
/// stages::StdMutationalStage,
|
/// stages::StdMutationalStage,
|
||||||
/// state::{HasCorpus, State, StdState},
|
/// state::{HasCorpus, StdState},
|
||||||
/// Error, Fuzzer, StdFuzzer,
|
/// Error, Fuzzer, StdFuzzer,
|
||||||
/// };
|
/// };
|
||||||
///
|
///
|
||||||
@ -58,7 +58,6 @@ use crate::{observers::Observer, Error};
|
|||||||
///
|
///
|
||||||
/// impl<EM, I, OT, S> Feedback<EM, I, OT, S> for ExportStdXObserver
|
/// impl<EM, I, OT, S> Feedback<EM, I, OT, S> for ExportStdXObserver
|
||||||
/// where
|
/// where
|
||||||
/// S: State,
|
|
||||||
/// OT: MatchNameRef
|
/// OT: MatchNameRef
|
||||||
/// {
|
/// {
|
||||||
/// fn is_interesting(
|
/// fn is_interesting(
|
||||||
|
@ -16,7 +16,7 @@ use crate::{
|
|||||||
on_add_metadata_default, on_evaluation_metadata_default, on_next_metadata_default,
|
on_add_metadata_default, on_evaluation_metadata_default, on_next_metadata_default,
|
||||||
AflScheduler, HasQueueCycles, RemovableScheduler, Scheduler,
|
AflScheduler, HasQueueCycles, RemovableScheduler, Scheduler,
|
||||||
},
|
},
|
||||||
state::{HasCorpus, State},
|
state::HasCorpus,
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -327,7 +327,7 @@ impl<C, O> HasQueueCycles for PowerQueueScheduler<C, O> {
|
|||||||
|
|
||||||
impl<C, I, O, S> Scheduler<I, S> for PowerQueueScheduler<C, O>
|
impl<C, I, O, S> Scheduler<I, S> for PowerQueueScheduler<C, O>
|
||||||
where
|
where
|
||||||
S: HasCorpus + HasMetadata + HasTestcase + State,
|
S: HasCorpus + HasMetadata + HasTestcase,
|
||||||
O: MapObserver,
|
O: MapObserver,
|
||||||
C: AsRef<O>,
|
C: AsRef<O>,
|
||||||
{
|
{
|
||||||
|
@ -26,7 +26,6 @@ use crate::{
|
|||||||
corpus::{Corpus, HasCurrentCorpusId, SchedulerTestcaseMetadata, Testcase},
|
corpus::{Corpus, HasCurrentCorpusId, SchedulerTestcaseMetadata, Testcase},
|
||||||
events::{Event, EventFirer},
|
events::{Event, EventFirer},
|
||||||
executors::HasObservers,
|
executors::HasObservers,
|
||||||
inputs::UsesInput,
|
|
||||||
monitors::{AggregatorOps, UserStats, UserStatsValue},
|
monitors::{AggregatorOps, UserStats, UserStatsValue},
|
||||||
mutators::Tokens,
|
mutators::Tokens,
|
||||||
observers::MapObserver,
|
observers::MapObserver,
|
||||||
@ -240,7 +239,7 @@ pub struct AFLPlotData<'a> {
|
|||||||
impl<C, E, EM, O, S, Z> Stage<E, EM, S, Z> for AflStatsStage<C, E, EM, O, S, Z>
|
impl<C, E, EM, O, S, Z> Stage<E, EM, S, Z> for AflStatsStage<C, E, EM, O, S, Z>
|
||||||
where
|
where
|
||||||
E: HasObservers,
|
E: HasObservers,
|
||||||
EM: EventFirer<State = S>,
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
Z: HasScheduler<<S::Corpus as Corpus>::Input, S>,
|
Z: HasScheduler<<S::Corpus as Corpus>::Input, S>,
|
||||||
S: HasImported
|
S: HasImported
|
||||||
+ HasCorpus
|
+ HasCorpus
|
||||||
@ -249,8 +248,7 @@ where
|
|||||||
+ HasExecutions
|
+ HasExecutions
|
||||||
+ HasNamedMetadata
|
+ HasNamedMetadata
|
||||||
+ Stoppable
|
+ Stoppable
|
||||||
+ HasCurrentCorpusId
|
+ HasCurrentCorpusId,
|
||||||
+ UsesInput,
|
|
||||||
E::Observers: MatchNameRef,
|
E::Observers: MatchNameRef,
|
||||||
O: MapObserver,
|
O: MapObserver,
|
||||||
C: AsRef<O> + Named,
|
C: AsRef<O> + Named,
|
||||||
@ -446,7 +444,7 @@ where
|
|||||||
impl<C, E, EM, O, S, Z> AflStatsStage<C, E, EM, O, S, Z>
|
impl<C, E, EM, O, S, Z> AflStatsStage<C, E, EM, O, S, Z>
|
||||||
where
|
where
|
||||||
E: HasObservers,
|
E: HasObservers,
|
||||||
EM: EventFirer,
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
S: HasImported + HasCorpus + HasMetadata + HasExecutions,
|
S: HasImported + HasCorpus + HasMetadata + HasExecutions,
|
||||||
C: AsRef<O> + Named,
|
C: AsRef<O> + Named,
|
||||||
O: MapObserver,
|
O: MapObserver,
|
||||||
@ -672,7 +670,7 @@ pub struct AflStatsStageBuilder<C, E, EM, O, S, Z> {
|
|||||||
impl<C, E, EM, O, S, Z> AflStatsStageBuilder<C, E, EM, O, S, Z>
|
impl<C, E, EM, O, S, Z> AflStatsStageBuilder<C, E, EM, O, S, Z>
|
||||||
where
|
where
|
||||||
E: HasObservers,
|
E: HasObservers,
|
||||||
EM: EventFirer,
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
S: HasImported + HasCorpus + HasMetadata + HasExecutions,
|
S: HasImported + HasCorpus + HasMetadata + HasExecutions,
|
||||||
C: AsRef<O> + Named,
|
C: AsRef<O> + Named,
|
||||||
O: MapObserver,
|
O: MapObserver,
|
||||||
|
@ -18,7 +18,7 @@ use crate::{
|
|||||||
executors::{Executor, ExitKind, HasObservers},
|
executors::{Executor, ExitKind, HasObservers},
|
||||||
feedbacks::{map::MapFeedbackMetadata, HasObserverHandle},
|
feedbacks::{map::MapFeedbackMetadata, HasObserverHandle},
|
||||||
fuzzer::Evaluator,
|
fuzzer::Evaluator,
|
||||||
inputs::{Input, UsesInput},
|
inputs::Input,
|
||||||
monitors::{AggregatorOps, UserStats, UserStatsValue},
|
monitors::{AggregatorOps, UserStats, UserStatsValue},
|
||||||
observers::{MapObserver, ObserversTuple},
|
observers::{MapObserver, ObserversTuple},
|
||||||
schedulers::powersched::SchedulerMetadata,
|
schedulers::powersched::SchedulerMetadata,
|
||||||
@ -92,7 +92,7 @@ pub struct CalibrationStage<C, E, O, OT, S> {
|
|||||||
impl<C, E, EM, O, OT, S, Z> Stage<E, EM, S, Z> for CalibrationStage<C, E, O, OT, S>
|
impl<C, E, EM, O, OT, S, Z> Stage<E, EM, S, Z> for CalibrationStage<C, E, O, OT, S>
|
||||||
where
|
where
|
||||||
E: Executor<EM, <S::Corpus as Corpus>::Input, S, Z> + HasObservers<Observers = OT>,
|
E: Executor<EM, <S::Corpus as Corpus>::Input, S, Z> + HasObservers<Observers = OT>,
|
||||||
EM: EventFirer<State = S>,
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
O: MapObserver,
|
O: MapObserver,
|
||||||
C: AsRef<O>,
|
C: AsRef<O>,
|
||||||
for<'de> <O as MapObserver>::Entry:
|
for<'de> <O as MapObserver>::Entry:
|
||||||
@ -103,8 +103,7 @@ where
|
|||||||
+ HasNamedMetadata
|
+ HasNamedMetadata
|
||||||
+ HasExecutions
|
+ HasExecutions
|
||||||
+ HasCurrentTestcase
|
+ HasCurrentTestcase
|
||||||
+ HasCurrentCorpusId
|
+ HasCurrentCorpusId,
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
Z: Evaluator<E, EM, <S::Corpus as Corpus>::Input, S>,
|
Z: Evaluator<E, EM, <S::Corpus as Corpus>::Input, S>,
|
||||||
<S::Corpus as Corpus>::Input: Input,
|
<S::Corpus as Corpus>::Input: Input,
|
||||||
{
|
{
|
||||||
|
@ -17,7 +17,7 @@ use crate::{
|
|||||||
corpus::{Corpus, HasCurrentCorpusId},
|
corpus::{Corpus, HasCurrentCorpusId},
|
||||||
events::EventFirer,
|
events::EventFirer,
|
||||||
executors::{Executor, HasObservers},
|
executors::{Executor, HasObservers},
|
||||||
inputs::{HasMutatorBytes, UsesInput},
|
inputs::HasMutatorBytes,
|
||||||
mutators::mutations::buffer_copy,
|
mutators::mutations::buffer_copy,
|
||||||
nonzero,
|
nonzero,
|
||||||
observers::{MapObserver, ObserversTuple},
|
observers::{MapObserver, ObserversTuple},
|
||||||
@ -76,14 +76,9 @@ impl<C, E, EM, O, S, Z> Named for ColorizationStage<C, E, EM, O, S, Z> {
|
|||||||
|
|
||||||
impl<C, E, EM, O, S, Z> Stage<E, EM, S, Z> for ColorizationStage<C, E, EM, O, S, Z>
|
impl<C, E, EM, O, S, Z> Stage<E, EM, S, Z> for ColorizationStage<C, E, EM, O, S, Z>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S>,
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
E: HasObservers + Executor<EM, <S::Corpus as Corpus>::Input, S, Z>,
|
E: HasObservers + Executor<EM, <S::Corpus as Corpus>::Input, S, Z>,
|
||||||
S: HasCorpus
|
S: HasCorpus + HasMetadata + HasRand + HasNamedMetadata + HasCurrentCorpusId,
|
||||||
+ HasMetadata
|
|
||||||
+ HasRand
|
|
||||||
+ HasNamedMetadata
|
|
||||||
+ HasCurrentCorpusId
|
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
E::Observers: ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
E::Observers: ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
<S::Corpus as Corpus>::Input: HasMutatorBytes + Clone,
|
<S::Corpus as Corpus>::Input: HasMutatorBytes + Clone,
|
||||||
O: MapObserver,
|
O: MapObserver,
|
||||||
@ -156,17 +151,12 @@ libafl_bolts::impl_serdeany!(TaintMetadata);
|
|||||||
|
|
||||||
impl<C, E, EM, O, S, Z> ColorizationStage<C, E, EM, O, S, Z>
|
impl<C, E, EM, O, S, Z> ColorizationStage<C, E, EM, O, S, Z>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S>,
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
O: MapObserver,
|
O: MapObserver,
|
||||||
C: AsRef<O> + Named,
|
C: AsRef<O> + Named,
|
||||||
E: HasObservers + Executor<EM, <S::Corpus as Corpus>::Input, S, Z>,
|
E: HasObservers + Executor<EM, <S::Corpus as Corpus>::Input, S, Z>,
|
||||||
E::Observers: ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
E::Observers: ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
S: HasCorpus
|
S: HasCorpus + HasMetadata + HasRand + HasCurrentCorpusId + HasCurrentTestcase,
|
||||||
+ HasMetadata
|
|
||||||
+ HasRand
|
|
||||||
+ HasCurrentCorpusId
|
|
||||||
+ HasCurrentTestcase
|
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
<S::Corpus as Corpus>::Input: HasMutatorBytes + Clone,
|
<S::Corpus as Corpus>::Input: HasMutatorBytes + Clone,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -17,10 +17,9 @@ use crate::monitors::PerfFeature;
|
|||||||
use crate::{
|
use crate::{
|
||||||
corpus::{Corpus, HasCurrentCorpusId},
|
corpus::{Corpus, HasCurrentCorpusId},
|
||||||
executors::{Executor, HasObservers},
|
executors::{Executor, HasObservers},
|
||||||
inputs::UsesInput,
|
|
||||||
observers::{concolic::ConcolicObserver, ObserversTuple},
|
observers::{concolic::ConcolicObserver, ObserversTuple},
|
||||||
stages::{RetryCountRestartHelper, Stage, TracingStage},
|
stages::{RetryCountRestartHelper, Stage, TracingStage},
|
||||||
state::{HasCorpus, HasCurrentTestcase, HasExecutions, MaybeHasClientPerfMonitor, UsesState},
|
state::{HasCorpus, HasCurrentTestcase, HasExecutions, MaybeHasClientPerfMonitor},
|
||||||
Error, HasMetadata, HasNamedMetadata,
|
Error, HasMetadata, HasNamedMetadata,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "concolic_mutation")]
|
#[cfg(feature = "concolic_mutation")]
|
||||||
@ -57,9 +56,7 @@ where
|
|||||||
+ HasNamedMetadata
|
+ HasNamedMetadata
|
||||||
+ HasCurrentTestcase
|
+ HasCurrentTestcase
|
||||||
+ HasCurrentCorpusId
|
+ HasCurrentCorpusId
|
||||||
+ MaybeHasClientPerfMonitor
|
+ MaybeHasClientPerfMonitor,
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
EM: UsesState<State = S>,
|
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn perform(
|
fn perform(
|
||||||
@ -387,8 +384,7 @@ where
|
|||||||
+ HasNamedMetadata
|
+ HasNamedMetadata
|
||||||
+ HasCurrentTestcase
|
+ HasCurrentTestcase
|
||||||
+ MaybeHasClientPerfMonitor
|
+ MaybeHasClientPerfMonitor
|
||||||
+ HasCurrentCorpusId
|
+ HasCurrentCorpusId,
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn perform(
|
fn perform(
|
||||||
|
@ -17,13 +17,13 @@ use crate::{
|
|||||||
corpus::{Corpus, HasCurrentCorpusId},
|
corpus::{Corpus, HasCurrentCorpusId},
|
||||||
executors::{Executor, HasObservers},
|
executors::{Executor, HasObservers},
|
||||||
feedbacks::map::MapNoveltiesMetadata,
|
feedbacks::map::MapNoveltiesMetadata,
|
||||||
inputs::{BytesInput, GeneralizedInputMetadata, GeneralizedItem, HasMutatorBytes, UsesInput},
|
inputs::{BytesInput, GeneralizedInputMetadata, GeneralizedItem, HasMutatorBytes},
|
||||||
mark_feature_time,
|
mark_feature_time,
|
||||||
observers::{CanTrack, MapObserver, ObserversTuple},
|
observers::{CanTrack, MapObserver, ObserversTuple},
|
||||||
require_novelties_tracking,
|
require_novelties_tracking,
|
||||||
stages::{RetryCountRestartHelper, Stage},
|
stages::{RetryCountRestartHelper, Stage},
|
||||||
start_timer,
|
start_timer,
|
||||||
state::{HasCorpus, HasExecutions, MaybeHasClientPerfMonitor, UsesState},
|
state::{HasCorpus, HasExecutions, MaybeHasClientPerfMonitor},
|
||||||
Error, HasMetadata, HasNamedMetadata,
|
Error, HasMetadata, HasNamedMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -71,10 +71,8 @@ where
|
|||||||
+ HasCorpus
|
+ HasCorpus
|
||||||
+ HasNamedMetadata
|
+ HasNamedMetadata
|
||||||
+ HasCurrentCorpusId
|
+ HasCurrentCorpusId
|
||||||
+ MaybeHasClientPerfMonitor
|
+ MaybeHasClientPerfMonitor,
|
||||||
+ UsesInput<Input = BytesInput>,
|
|
||||||
S::Corpus: Corpus<Input = BytesInput>,
|
S::Corpus: Corpus<Input = BytesInput>,
|
||||||
EM: UsesState<State = S>,
|
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
#[expect(clippy::too_many_lines)]
|
#[expect(clippy::too_many_lines)]
|
||||||
@ -343,14 +341,9 @@ impl<C, EM, O, OT, S, Z> GeneralizationStage<C, EM, O, OT, S, Z>
|
|||||||
where
|
where
|
||||||
O: MapObserver,
|
O: MapObserver,
|
||||||
C: CanTrack + AsRef<O> + Named,
|
C: CanTrack + AsRef<O> + Named,
|
||||||
S: HasExecutions
|
S: HasExecutions + HasMetadata + HasCorpus + MaybeHasClientPerfMonitor,
|
||||||
+ HasMetadata
|
|
||||||
+ HasCorpus
|
|
||||||
+ MaybeHasClientPerfMonitor
|
|
||||||
+ UsesInput<Input = BytesInput>,
|
|
||||||
S::Corpus: Corpus<Input = BytesInput>,
|
S::Corpus: Corpus<Input = BytesInput>,
|
||||||
OT: ObserversTuple<BytesInput, S>,
|
OT: ObserversTuple<BytesInput, S>,
|
||||||
EM: UsesState<State = S>,
|
|
||||||
{
|
{
|
||||||
/// Create a new [`GeneralizationStage`].
|
/// Create a new [`GeneralizationStage`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -9,7 +9,6 @@ use core::marker::PhantomData;
|
|||||||
use crate::{
|
use crate::{
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
generators::Generator,
|
generators::Generator,
|
||||||
inputs::UsesInput,
|
|
||||||
stages::Stage,
|
stages::Stage,
|
||||||
state::{HasCorpus, HasRand},
|
state::{HasCorpus, HasRand},
|
||||||
Error, Evaluator,
|
Error, Evaluator,
|
||||||
@ -32,7 +31,7 @@ impl<G, S, Z> GenStage<G, S, Z> {
|
|||||||
impl<E, EM, G, S, Z> Stage<E, EM, S, Z> for GenStage<G, S, Z>
|
impl<E, EM, G, S, Z> Stage<E, EM, S, Z> for GenStage<G, S, Z>
|
||||||
where
|
where
|
||||||
Z: Evaluator<E, EM, <S::Corpus as Corpus>::Input, S>,
|
Z: Evaluator<E, EM, <S::Corpus as Corpus>::Input, S>,
|
||||||
S: HasCorpus + HasRand + UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
S: HasCorpus + HasRand,
|
||||||
G: Generator<<S::Corpus as Corpus>::Input, S>,
|
G: Generator<<S::Corpus as Corpus>::Input, S>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -49,7 +49,7 @@ pub use verify_timeouts::{TimeoutsToVerify, VerifyTimeoutsStage};
|
|||||||
use crate::{
|
use crate::{
|
||||||
corpus::{CorpusId, HasCurrentCorpusId},
|
corpus::{CorpusId, HasCurrentCorpusId},
|
||||||
events::EventProcessor,
|
events::EventProcessor,
|
||||||
state::{HasExecutions, State, Stoppable},
|
state::{HasExecutions, Stoppable},
|
||||||
Error, HasNamedMetadata,
|
Error, HasNamedMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ where
|
|||||||
Head: Stage<E, EM, S, Z>,
|
Head: Stage<E, EM, S, Z>,
|
||||||
Tail: StagesTuple<E, EM, S, Z> + HasConstLen,
|
Tail: StagesTuple<E, EM, S, Z> + HasConstLen,
|
||||||
S: HasCurrentStageId + Stoppable,
|
S: HasCurrentStageId + Stoppable,
|
||||||
EM: EventProcessor<E, Z>,
|
EM: EventProcessor<E, S, Z>,
|
||||||
{
|
{
|
||||||
/// Performs all stages in the tuple,
|
/// Performs all stages in the tuple,
|
||||||
/// Checks after every stage if state wants to stop
|
/// Checks after every stage if state wants to stop
|
||||||
@ -248,8 +248,8 @@ impl<E, EM, S, Z> IntoVec<Box<dyn Stage<E, EM, S, Z>>> for Vec<Box<dyn Stage<E,
|
|||||||
|
|
||||||
impl<E, EM, S, Z> StagesTuple<E, EM, S, Z> for Vec<Box<dyn Stage<E, EM, S, Z>>>
|
impl<E, EM, S, Z> StagesTuple<E, EM, S, Z> for Vec<Box<dyn Stage<E, EM, S, Z>>>
|
||||||
where
|
where
|
||||||
EM: EventProcessor<E, Z>,
|
EM: EventProcessor<E, S, Z>,
|
||||||
S: HasCurrentStageId + State,
|
S: HasCurrentStageId + Stoppable,
|
||||||
{
|
{
|
||||||
/// Performs all stages in the `Vec`
|
/// Performs all stages in the `Vec`
|
||||||
/// Checks after every stage if state wants to stop
|
/// Checks after every stage if state wants to stop
|
||||||
|
@ -14,7 +14,7 @@ use crate::monitors::PerfFeature;
|
|||||||
use crate::{
|
use crate::{
|
||||||
corpus::{Corpus, CorpusId, HasCurrentCorpusId, Testcase},
|
corpus::{Corpus, CorpusId, HasCurrentCorpusId, Testcase},
|
||||||
fuzzer::Evaluator,
|
fuzzer::Evaluator,
|
||||||
inputs::{Input, UsesInput},
|
inputs::Input,
|
||||||
mark_feature_time,
|
mark_feature_time,
|
||||||
mutators::{MultiMutator, MutationResult, Mutator},
|
mutators::{MultiMutator, MutationResult, Mutator},
|
||||||
nonzero,
|
nonzero,
|
||||||
@ -156,11 +156,9 @@ where
|
|||||||
+ HasExecutions
|
+ HasExecutions
|
||||||
+ HasNamedMetadata
|
+ HasNamedMetadata
|
||||||
+ HasCurrentCorpusId
|
+ HasCurrentCorpusId
|
||||||
+ MaybeHasClientPerfMonitor
|
+ MaybeHasClientPerfMonitor,
|
||||||
+ UsesInput,
|
|
||||||
I: MutatedTransform<<S::Corpus as Corpus>::Input, S> + Clone,
|
I: MutatedTransform<<S::Corpus as Corpus>::Input, S> + Clone,
|
||||||
<S::Corpus as Corpus>::Input: Input,
|
<S::Corpus as Corpus>::Input: Input,
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn perform(
|
fn perform(
|
||||||
@ -191,9 +189,8 @@ impl<E, EM, M, S, Z> StdMutationalStage<E, EM, <S::Corpus as Corpus>::Input, M,
|
|||||||
where
|
where
|
||||||
M: Mutator<<S::Corpus as Corpus>::Input, S>,
|
M: Mutator<<S::Corpus as Corpus>::Input, S>,
|
||||||
Z: Evaluator<E, EM, <S::Corpus as Corpus>::Input, S>,
|
Z: Evaluator<E, EM, <S::Corpus as Corpus>::Input, S>,
|
||||||
S: HasCorpus + HasRand + HasCurrentCorpusId + UsesInput + MaybeHasClientPerfMonitor,
|
S: HasCorpus + HasRand + HasCurrentCorpusId + MaybeHasClientPerfMonitor,
|
||||||
<S::Corpus as Corpus>::Input: Input + Clone,
|
<S::Corpus as Corpus>::Input: Input + Clone,
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
|
||||||
{
|
{
|
||||||
/// Creates a new default mutational stage
|
/// Creates a new default mutational stage
|
||||||
pub fn new(mutator: M) -> Self {
|
pub fn new(mutator: M) -> Self {
|
||||||
@ -212,10 +209,9 @@ impl<E, EM, I, M, S, Z> StdMutationalStage<E, EM, I, M, S, Z>
|
|||||||
where
|
where
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
Z: Evaluator<E, EM, <S::Corpus as Corpus>::Input, S>,
|
Z: Evaluator<E, EM, <S::Corpus as Corpus>::Input, S>,
|
||||||
S: HasCorpus + HasRand + HasCurrentTestcase + MaybeHasClientPerfMonitor + UsesInput,
|
S: HasCorpus + HasRand + HasCurrentTestcase + MaybeHasClientPerfMonitor,
|
||||||
I: MutatedTransform<<S::Corpus as Corpus>::Input, S> + Clone,
|
I: MutatedTransform<<S::Corpus as Corpus>::Input, S> + Clone,
|
||||||
<S::Corpus as Corpus>::Input: Input,
|
<S::Corpus as Corpus>::Input: Input,
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
|
||||||
{
|
{
|
||||||
/// Creates a new transforming mutational stage with the default max iterations
|
/// Creates a new transforming mutational stage with the default max iterations
|
||||||
pub fn transforming(mutator: M) -> Self {
|
pub fn transforming(mutator: M) -> Self {
|
||||||
@ -313,10 +309,9 @@ impl<E, EM, I, M, S, Z> Stage<E, EM, S, Z> for MultiMutationalStage<E, EM, I, M,
|
|||||||
where
|
where
|
||||||
M: MultiMutator<I, S>,
|
M: MultiMutator<I, S>,
|
||||||
Z: Evaluator<E, EM, <S::Corpus as Corpus>::Input, S>,
|
Z: Evaluator<E, EM, <S::Corpus as Corpus>::Input, S>,
|
||||||
S: HasCorpus + HasRand + HasNamedMetadata + HasCurrentTestcase + HasCurrentCorpusId + UsesInput,
|
S: HasCorpus + HasRand + HasNamedMetadata + HasCurrentTestcase + HasCurrentCorpusId,
|
||||||
I: MutatedTransform<<S::Corpus as Corpus>::Input, S> + Clone,
|
I: MutatedTransform<<S::Corpus as Corpus>::Input, S> + Clone,
|
||||||
<S::Corpus as Corpus>::Input: Input,
|
<S::Corpus as Corpus>::Input: Input,
|
||||||
S::Corpus: Corpus<Input = S::Input>,
|
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn should_restart(&mut self, state: &mut S) -> Result<bool, Error> {
|
fn should_restart(&mut self, state: &mut S) -> Result<bool, Error> {
|
||||||
|
@ -14,7 +14,7 @@ use crate::{
|
|||||||
corpus::{Corpus, HasCurrentCorpusId},
|
corpus::{Corpus, HasCurrentCorpusId},
|
||||||
executors::{Executor, HasObservers},
|
executors::{Executor, HasObservers},
|
||||||
fuzzer::Evaluator,
|
fuzzer::Evaluator,
|
||||||
inputs::{Input, UsesInput},
|
inputs::Input,
|
||||||
mark_feature_time,
|
mark_feature_time,
|
||||||
mutators::{MutationResult, Mutator},
|
mutators::{MutationResult, Mutator},
|
||||||
schedulers::{testcase_score::CorpusPowerTestcaseScore, TestcaseScore},
|
schedulers::{testcase_score::CorpusPowerTestcaseScore, TestcaseScore},
|
||||||
@ -23,9 +23,7 @@ use crate::{
|
|||||||
MutationalStage, RetryCountRestartHelper, Stage,
|
MutationalStage, RetryCountRestartHelper, Stage,
|
||||||
},
|
},
|
||||||
start_timer,
|
start_timer,
|
||||||
state::{
|
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasRand, MaybeHasClientPerfMonitor},
|
||||||
HasCorpus, HasCurrentTestcase, HasExecutions, HasRand, MaybeHasClientPerfMonitor, UsesState,
|
|
||||||
},
|
|
||||||
Error, HasMetadata, HasNamedMetadata,
|
Error, HasMetadata, HasNamedMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -80,7 +78,6 @@ where
|
|||||||
impl<E, F, EM, I, M, S, Z> Stage<E, EM, S, Z> for PowerMutationalStage<E, F, EM, I, M, S, Z>
|
impl<E, F, EM, I, M, S, Z> Stage<E, EM, S, Z> for PowerMutationalStage<E, F, EM, I, M, S, Z>
|
||||||
where
|
where
|
||||||
E: Executor<EM, <S::Corpus as Corpus>::Input, S, Z> + HasObservers,
|
E: Executor<EM, <S::Corpus as Corpus>::Input, S, Z> + HasObservers,
|
||||||
EM: UsesState<State = S>,
|
|
||||||
F: TestcaseScore<S>,
|
F: TestcaseScore<S>,
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
S: HasCorpus
|
S: HasCorpus
|
||||||
@ -90,8 +87,7 @@ where
|
|||||||
+ HasNamedMetadata
|
+ HasNamedMetadata
|
||||||
+ HasCurrentTestcase
|
+ HasCurrentTestcase
|
||||||
+ HasCurrentCorpusId
|
+ HasCurrentCorpusId
|
||||||
+ MaybeHasClientPerfMonitor
|
+ MaybeHasClientPerfMonitor,
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
Z: Evaluator<E, EM, <S::Corpus as Corpus>::Input, S>,
|
Z: Evaluator<E, EM, <S::Corpus as Corpus>::Input, S>,
|
||||||
I: MutatedTransform<<S::Corpus as Corpus>::Input, S> + Clone + Input,
|
I: MutatedTransform<<S::Corpus as Corpus>::Input, S> + Clone + Input,
|
||||||
<S::Corpus as Corpus>::Input: Input,
|
<S::Corpus as Corpus>::Input: Input,
|
||||||
@ -122,16 +118,10 @@ where
|
|||||||
impl<E, F, EM, I, M, S, Z> PowerMutationalStage<E, F, EM, I, M, S, Z>
|
impl<E, F, EM, I, M, S, Z> PowerMutationalStage<E, F, EM, I, M, S, Z>
|
||||||
where
|
where
|
||||||
E: Executor<EM, <S::Corpus as Corpus>::Input, S, Z> + HasObservers,
|
E: Executor<EM, <S::Corpus as Corpus>::Input, S, Z> + HasObservers,
|
||||||
EM: UsesState<State = S>,
|
|
||||||
F: TestcaseScore<S>,
|
F: TestcaseScore<S>,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
S: HasCorpus
|
S: HasCorpus + HasMetadata + HasRand + HasCurrentTestcase + MaybeHasClientPerfMonitor,
|
||||||
+ HasMetadata
|
|
||||||
+ HasRand
|
|
||||||
+ HasCurrentTestcase
|
|
||||||
+ MaybeHasClientPerfMonitor
|
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
I: MutatedTransform<<S::Corpus as Corpus>::Input, S> + Clone + Input,
|
I: MutatedTransform<<S::Corpus as Corpus>::Input, S> + Clone + Input,
|
||||||
Z: Evaluator<E, EM, <S::Corpus as Corpus>::Input, S>,
|
Z: Evaluator<E, EM, <S::Corpus as Corpus>::Input, S>,
|
||||||
<S::Corpus as Corpus>::Input: Input,
|
<S::Corpus as Corpus>::Input: Input,
|
||||||
|
@ -26,7 +26,6 @@ use crate::{
|
|||||||
corpus::{Corpus, CorpusId, HasCurrentCorpusId},
|
corpus::{Corpus, CorpusId, HasCurrentCorpusId},
|
||||||
events::{EventFirer, EventRestarter, HasEventManagerId, ProgressReporter},
|
events::{EventFirer, EventRestarter, HasEventManagerId, ProgressReporter},
|
||||||
executors::{Executor, ExitKind, HasObservers},
|
executors::{Executor, ExitKind, HasObservers},
|
||||||
inputs::UsesInput,
|
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
schedulers::Scheduler,
|
schedulers::Scheduler,
|
||||||
stages::{RetryCountRestartHelper, Stage},
|
stages::{RetryCountRestartHelper, Stage},
|
||||||
@ -38,11 +37,11 @@ use crate::{
|
|||||||
/// Should be stored inside a `[Rc<RefCell<_>>`]
|
/// Should be stored inside a `[Rc<RefCell<_>>`]
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct PushStageSharedState<EM, I, OT, S, Z> {
|
pub struct PushStageSharedState<EM, I, OT, S, Z> {
|
||||||
/// The [`crate::state::State`]
|
/// The state
|
||||||
pub state: S,
|
pub state: S,
|
||||||
/// The [`crate::fuzzer::Fuzzer`] instance
|
/// The [`crate::fuzzer::Fuzzer`] instance
|
||||||
pub fuzzer: Z,
|
pub fuzzer: Z,
|
||||||
/// The [`crate::events::EventManager`]
|
/// The event manager
|
||||||
pub event_mgr: EM,
|
pub event_mgr: EM,
|
||||||
/// The [`crate::observers::ObserversTuple`]
|
/// The [`crate::observers::ObserversTuple`]
|
||||||
pub observers: OT,
|
pub observers: OT,
|
||||||
@ -254,10 +253,12 @@ where
|
|||||||
+ HasLastReportTime
|
+ HasLastReportTime
|
||||||
+ HasCurrentCorpusId
|
+ HasCurrentCorpusId
|
||||||
+ HasNamedMetadata
|
+ HasNamedMetadata
|
||||||
+ HasMetadata
|
+ HasMetadata,
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
E: Executor<EM, <S::Corpus as Corpus>::Input, S, Z> + HasObservers<Observers = OT>,
|
E: Executor<EM, <S::Corpus as Corpus>::Input, S, Z> + HasObservers<Observers = OT>,
|
||||||
EM: EventFirer<State = S> + EventRestarter + HasEventManagerId + ProgressReporter<State = S>,
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S>
|
||||||
|
+ EventRestarter<S>
|
||||||
|
+ HasEventManagerId
|
||||||
|
+ ProgressReporter<S>,
|
||||||
OT: ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
OT: ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
PS: PushStage<EM, <S::Corpus as Corpus>::Input, OT, S, Z>,
|
PS: PushStage<EM, <S::Corpus as Corpus>::Input, OT, S, Z>,
|
||||||
Z: ExecutesInput<E, EM, <S::Corpus as Corpus>::Input, S>
|
Z: ExecutesInput<E, EM, <S::Corpus as Corpus>::Input, S>
|
||||||
|
@ -18,7 +18,7 @@ use crate::{
|
|||||||
events::{EventFirer, ProgressReporter},
|
events::{EventFirer, ProgressReporter},
|
||||||
executors::ExitKind,
|
executors::ExitKind,
|
||||||
fuzzer::STATS_TIMEOUT_DEFAULT,
|
fuzzer::STATS_TIMEOUT_DEFAULT,
|
||||||
inputs::{Input, UsesInput},
|
inputs::Input,
|
||||||
mark_feature_time,
|
mark_feature_time,
|
||||||
mutators::Mutator,
|
mutators::Mutator,
|
||||||
nonzero,
|
nonzero,
|
||||||
@ -79,13 +79,10 @@ where
|
|||||||
impl<EM, M, OT, S, Z> PushStage<EM, <S::Corpus as Corpus>::Input, OT, S, Z>
|
impl<EM, M, OT, S, Z> PushStage<EM, <S::Corpus as Corpus>::Input, OT, S, Z>
|
||||||
for StdMutationalPushStage<EM, M, OT, S, Z>
|
for StdMutationalPushStage<EM, M, OT, S, Z>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S>,
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
Z: HasScheduler<<S::Corpus as Corpus>::Input, S>
|
Z: HasScheduler<<S::Corpus as Corpus>::Input, S>
|
||||||
+ ExecutionProcessor<EM, <S::Corpus as Corpus>::Input, OT, S>,
|
+ ExecutionProcessor<EM, <S::Corpus as Corpus>::Input, OT, S>,
|
||||||
S: HasCorpus
|
S: HasCorpus + HasRand + MaybeHasClientPerfMonitor,
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>
|
|
||||||
+ HasRand
|
|
||||||
+ MaybeHasClientPerfMonitor,
|
|
||||||
M: Mutator<<S::Corpus as Corpus>::Input, S>,
|
M: Mutator<<S::Corpus as Corpus>::Input, S>,
|
||||||
OT: ObserversTuple<<S::Corpus as Corpus>::Input, S> + Serialize,
|
OT: ObserversTuple<<S::Corpus as Corpus>::Input, S> + Serialize,
|
||||||
<S::Corpus as Corpus>::Input: Input + Clone,
|
<S::Corpus as Corpus>::Input: Input + Clone,
|
||||||
@ -193,14 +190,13 @@ where
|
|||||||
|
|
||||||
impl<EM, M, OT, S, Z> Iterator for StdMutationalPushStage<EM, M, OT, S, Z>
|
impl<EM, M, OT, S, Z> Iterator for StdMutationalPushStage<EM, M, OT, S, Z>
|
||||||
where
|
where
|
||||||
EM: ProgressReporter<State = S>,
|
EM: ProgressReporter<S> + EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
S: HasCorpus
|
S: HasCorpus
|
||||||
+ HasMetadata
|
+ HasMetadata
|
||||||
+ HasExecutions
|
+ HasExecutions
|
||||||
+ HasLastReportTime
|
+ HasLastReportTime
|
||||||
+ HasRand
|
+ HasRand
|
||||||
+ MaybeHasClientPerfMonitor
|
+ MaybeHasClientPerfMonitor,
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
OT: ObserversTuple<<S::Corpus as Corpus>::Input, S> + Serialize,
|
OT: ObserversTuple<<S::Corpus as Corpus>::Input, S> + Serialize,
|
||||||
M: Mutator<<S::Corpus as Corpus>::Input, S>,
|
M: Mutator<<S::Corpus as Corpus>::Input, S>,
|
||||||
<S::Corpus as Corpus>::Input: Clone + Debug + Input,
|
<S::Corpus as Corpus>::Input: Clone + Debug + Input,
|
||||||
@ -216,14 +212,13 @@ where
|
|||||||
|
|
||||||
impl<EM, M, OT, S, Z> StdMutationalPushStage<EM, M, OT, S, Z>
|
impl<EM, M, OT, S, Z> StdMutationalPushStage<EM, M, OT, S, Z>
|
||||||
where
|
where
|
||||||
EM: ProgressReporter<State = S>,
|
EM: ProgressReporter<S> + EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
S: HasCorpus
|
S: HasCorpus
|
||||||
+ HasMetadata
|
+ HasMetadata
|
||||||
+ HasExecutions
|
+ HasExecutions
|
||||||
+ HasLastReportTime
|
+ HasLastReportTime
|
||||||
+ HasRand
|
+ HasRand
|
||||||
+ MaybeHasClientPerfMonitor
|
+ MaybeHasClientPerfMonitor,
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
OT: ObserversTuple<<S::Corpus as Corpus>::Input, S> + Serialize,
|
OT: ObserversTuple<<S::Corpus as Corpus>::Input, S> + Serialize,
|
||||||
M: Mutator<<S::Corpus as Corpus>::Input, S>,
|
M: Mutator<<S::Corpus as Corpus>::Input, S>,
|
||||||
<S::Corpus as Corpus>::Input: Clone + Debug + Input,
|
<S::Corpus as Corpus>::Input: Clone + Debug + Input,
|
||||||
|
@ -15,9 +15,9 @@ use crate::{
|
|||||||
events::{llmp::LlmpEventConverter, Event, EventConfig, EventFirer},
|
events::{llmp::LlmpEventConverter, Event, EventConfig, EventFirer},
|
||||||
executors::{Executor, ExitKind, HasObservers},
|
executors::{Executor, ExitKind, HasObservers},
|
||||||
fuzzer::{Evaluator, EvaluatorObservers, ExecutionProcessor},
|
fuzzer::{Evaluator, EvaluatorObservers, ExecutionProcessor},
|
||||||
inputs::{Input, InputConverter, UsesInput},
|
inputs::{Input, InputConverter},
|
||||||
stages::{RetryCountRestartHelper, Stage},
|
stages::{RetryCountRestartHelper, Stage},
|
||||||
state::{HasCorpus, HasExecutions, HasRand, MaybeHasClientPerfMonitor, State, Stoppable},
|
state::{HasCorpus, HasExecutions, HasRand, MaybeHasClientPerfMonitor, Stoppable},
|
||||||
Error, HasMetadata, HasNamedMetadata,
|
Error, HasMetadata, HasNamedMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -74,7 +74,6 @@ where
|
|||||||
+ HasRand
|
+ HasRand
|
||||||
+ HasMetadata
|
+ HasMetadata
|
||||||
+ HasNamedMetadata
|
+ HasNamedMetadata
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>
|
|
||||||
+ HasCurrentCorpusId
|
+ HasCurrentCorpusId
|
||||||
+ MaybeHasClientPerfMonitor,
|
+ MaybeHasClientPerfMonitor,
|
||||||
{
|
{
|
||||||
@ -221,27 +220,17 @@ impl SyncFromBrokerMetadata {
|
|||||||
|
|
||||||
/// A stage that loads testcases from disk to sync with other fuzzers such as AFL++
|
/// A stage that loads testcases from disk to sync with other fuzzers such as AFL++
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SyncFromBrokerStage<DI, IC, ICB, S, SP>
|
pub struct SyncFromBrokerStage<IC, ICB, S, SP>
|
||||||
where
|
where
|
||||||
SP: ShMemProvider + 'static,
|
SP: ShMemProvider,
|
||||||
S: UsesInput,
|
|
||||||
IC: InputConverter<From = S::Input, To = DI>,
|
|
||||||
ICB: InputConverter<From = DI, To = S::Input>,
|
|
||||||
DI: Input,
|
|
||||||
{
|
{
|
||||||
client: LlmpEventConverter<DI, IC, ICB, S, SP>,
|
client: LlmpEventConverter<IC, ICB, S, SP>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, EM, IC, ICB, DI, S, SP, Z> Stage<E, EM, S, Z> for SyncFromBrokerStage<DI, IC, ICB, S, SP>
|
impl<E, EM, IC, ICB, DI, S, SP, Z> Stage<E, EM, S, Z> for SyncFromBrokerStage<IC, ICB, S, SP>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S>,
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
S: HasExecutions
|
S: HasExecutions + HasCorpus + HasRand + HasMetadata + Stoppable + MaybeHasClientPerfMonitor,
|
||||||
+ HasCorpus
|
|
||||||
+ HasRand
|
|
||||||
+ HasMetadata
|
|
||||||
+ Stoppable
|
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>
|
|
||||||
+ State,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
E: HasObservers + Executor<EM, <S::Corpus as Corpus>::Input, S, Z>,
|
E: HasObservers + Executor<EM, <S::Corpus as Corpus>::Input, S, Z>,
|
||||||
for<'a> E::Observers: Deserialize<'a>,
|
for<'a> E::Observers: Deserialize<'a>,
|
||||||
@ -323,17 +312,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DI, IC, ICB, S, SP> SyncFromBrokerStage<DI, IC, ICB, S, SP>
|
impl<IC, ICB, S, SP> SyncFromBrokerStage<IC, ICB, S, SP>
|
||||||
where
|
where
|
||||||
SP: ShMemProvider + 'static,
|
SP: ShMemProvider,
|
||||||
S: UsesInput,
|
|
||||||
IC: InputConverter<From = S::Input, To = DI>,
|
|
||||||
ICB: InputConverter<From = DI, To = S::Input>,
|
|
||||||
DI: Input,
|
|
||||||
{
|
{
|
||||||
/// Creates a new [`SyncFromBrokerStage`]
|
/// Creates a new [`SyncFromBrokerStage`]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(client: LlmpEventConverter<DI, IC, ICB, S, SP>) -> Self {
|
pub fn new(client: LlmpEventConverter<IC, ICB, S, SP>) -> Self {
|
||||||
Self { client }
|
Self { client }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ use crate::{
|
|||||||
events::EventFirer,
|
events::EventFirer,
|
||||||
executors::{ExitKind, HasObservers},
|
executors::{ExitKind, HasObservers},
|
||||||
feedbacks::{Feedback, FeedbackFactory, HasObserverHandle, StateInitializer},
|
feedbacks::{Feedback, FeedbackFactory, HasObserverHandle, StateInitializer},
|
||||||
inputs::{Input, UsesInput},
|
inputs::Input,
|
||||||
mark_feature_time,
|
mark_feature_time,
|
||||||
mutators::{MutationResult, Mutator},
|
mutators::{MutationResult, Mutator},
|
||||||
observers::{MapObserver, ObserversTuple},
|
observers::{MapObserver, ObserversTuple},
|
||||||
@ -34,7 +34,7 @@ use crate::{
|
|||||||
start_timer,
|
start_timer,
|
||||||
state::{
|
state::{
|
||||||
HasCorpus, HasCurrentTestcase, HasExecutions, HasMaxSize, HasSolutions,
|
HasCorpus, HasCurrentTestcase, HasExecutions, HasMaxSize, HasSolutions,
|
||||||
MaybeHasClientPerfMonitor, State,
|
MaybeHasClientPerfMonitor,
|
||||||
},
|
},
|
||||||
Error, ExecutesInput, ExecutionProcessor, HasFeedback, HasMetadata, HasNamedMetadata,
|
Error, ExecutesInput, ExecutionProcessor, HasFeedback, HasMetadata, HasNamedMetadata,
|
||||||
HasScheduler,
|
HasScheduler,
|
||||||
@ -65,7 +65,7 @@ where
|
|||||||
Z::Scheduler: RemovableScheduler<<S::Corpus as Corpus>::Input, S>,
|
Z::Scheduler: RemovableScheduler<<S::Corpus as Corpus>::Input, S>,
|
||||||
E: HasObservers,
|
E: HasObservers,
|
||||||
E::Observers: ObserversTuple<<S::Corpus as Corpus>::Input, S> + Serialize,
|
E::Observers: ObserversTuple<<S::Corpus as Corpus>::Input, S> + Serialize,
|
||||||
EM: EventFirer<State = S>,
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
FF: FeedbackFactory<F, E::Observers>,
|
FF: FeedbackFactory<F, E::Observers>,
|
||||||
F: Feedback<EM, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
F: Feedback<EM, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
||||||
S: HasMetadata
|
S: HasMetadata
|
||||||
@ -75,8 +75,7 @@ where
|
|||||||
+ HasMaxSize
|
+ HasMaxSize
|
||||||
+ HasNamedMetadata
|
+ HasNamedMetadata
|
||||||
+ HasCurrentCorpusId
|
+ HasCurrentCorpusId
|
||||||
+ MaybeHasClientPerfMonitor
|
+ MaybeHasClientPerfMonitor,
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
Z::Feedback: Feedback<EM, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
Z::Feedback: Feedback<EM, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
||||||
M: Mutator<<S::Corpus as Corpus>::Input, S>,
|
M: Mutator<<S::Corpus as Corpus>::Input, S>,
|
||||||
<<S as HasCorpus>::Corpus as Corpus>::Input: Input + Hash + HasLen,
|
<<S as HasCorpus>::Corpus as Corpus>::Input: Input + Hash + HasLen,
|
||||||
@ -136,7 +135,7 @@ where
|
|||||||
Z::Scheduler: RemovableScheduler<<S::Corpus as Corpus>::Input, S>,
|
Z::Scheduler: RemovableScheduler<<S::Corpus as Corpus>::Input, S>,
|
||||||
E: HasObservers,
|
E: HasObservers,
|
||||||
E::Observers: ObserversTuple<<S::Corpus as Corpus>::Input, S> + Serialize,
|
E::Observers: ObserversTuple<<S::Corpus as Corpus>::Input, S> + Serialize,
|
||||||
EM: EventFirer<State = S>,
|
EM: EventFirer<<S::Corpus as Corpus>::Input, S>,
|
||||||
FF: FeedbackFactory<F, E::Observers>,
|
FF: FeedbackFactory<F, E::Observers>,
|
||||||
F: Feedback<EM, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
F: Feedback<EM, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
||||||
S: HasMetadata
|
S: HasMetadata
|
||||||
@ -147,8 +146,7 @@ where
|
|||||||
+ HasNamedMetadata
|
+ HasNamedMetadata
|
||||||
+ HasCurrentTestcase
|
+ HasCurrentTestcase
|
||||||
+ HasCurrentCorpusId
|
+ HasCurrentCorpusId
|
||||||
+ MaybeHasClientPerfMonitor
|
+ MaybeHasClientPerfMonitor,
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
Z::Feedback: Feedback<EM, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
Z::Feedback: Feedback<EM, <S::Corpus as Corpus>::Input, E::Observers, S>,
|
||||||
M: Mutator<<S::Corpus as Corpus>::Input, S>,
|
M: Mutator<<S::Corpus as Corpus>::Input, S>,
|
||||||
<S::Corpus as Corpus>::Input: Hash + HasLen + Input,
|
<S::Corpus as Corpus>::Input: Hash + HasLen + Input,
|
||||||
@ -364,7 +362,6 @@ impl<C, EM, I, M, OT, S> Feedback<EM, I, OT, S> for MapEqualityFeedback<C, M, S>
|
|||||||
where
|
where
|
||||||
M: MapObserver,
|
M: MapObserver,
|
||||||
C: AsRef<M>,
|
C: AsRef<M>,
|
||||||
S: State,
|
|
||||||
OT: MatchName,
|
OT: MatchName,
|
||||||
{
|
{
|
||||||
fn is_interesting(
|
fn is_interesting(
|
||||||
@ -424,8 +421,8 @@ impl<C, M, OT, S> FeedbackFactory<MapEqualityFeedback<C, M, S>, OT> for MapEqual
|
|||||||
where
|
where
|
||||||
M: MapObserver,
|
M: MapObserver,
|
||||||
C: AsRef<M> + Handled,
|
C: AsRef<M> + Handled,
|
||||||
OT: ObserversTuple<S::Input, S>,
|
OT: ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
S: UsesInput,
|
S: HasCorpus,
|
||||||
{
|
{
|
||||||
fn create_feedback(&self, observers: &OT) -> MapEqualityFeedback<C, M, S> {
|
fn create_feedback(&self, observers: &OT) -> MapEqualityFeedback<C, M, S> {
|
||||||
let obs = observers
|
let obs = observers
|
||||||
|
@ -13,12 +13,12 @@ use crate::monitors::PerfFeature;
|
|||||||
use crate::{
|
use crate::{
|
||||||
corpus::{Corpus, HasCurrentCorpusId},
|
corpus::{Corpus, HasCurrentCorpusId},
|
||||||
executors::{Executor, HasObservers, ShadowExecutor},
|
executors::{Executor, HasObservers, ShadowExecutor},
|
||||||
inputs::{Input, UsesInput},
|
inputs::Input,
|
||||||
mark_feature_time,
|
mark_feature_time,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
stages::{RetryCountRestartHelper, Stage},
|
stages::{RetryCountRestartHelper, Stage},
|
||||||
start_timer,
|
start_timer,
|
||||||
state::{HasCorpus, HasCurrentTestcase, HasExecutions, MaybeHasClientPerfMonitor, UsesState},
|
state::{HasCorpus, HasCurrentTestcase, HasExecutions, MaybeHasClientPerfMonitor},
|
||||||
Error, HasNamedMetadata,
|
Error, HasNamedMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -38,9 +38,7 @@ where
|
|||||||
+ HasCorpus
|
+ HasCorpus
|
||||||
+ HasNamedMetadata
|
+ HasNamedMetadata
|
||||||
+ HasCurrentTestcase
|
+ HasCurrentTestcase
|
||||||
+ MaybeHasClientPerfMonitor
|
+ MaybeHasClientPerfMonitor,
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
EM: UsesState<State = S>, //delete me
|
|
||||||
{
|
{
|
||||||
/// Perform tracing on the given `CorpusId`. Useful for if wrapping [`TracingStage`] with your
|
/// Perform tracing on the given `CorpusId`. Useful for if wrapping [`TracingStage`] with your
|
||||||
/// own stage and you need to manage [`super::NestedStageRetryCountRestartHelper`] differently
|
/// own stage and you need to manage [`super::NestedStageRetryCountRestartHelper`] differently
|
||||||
@ -82,9 +80,7 @@ where
|
|||||||
+ HasCorpus
|
+ HasCorpus
|
||||||
+ HasNamedMetadata
|
+ HasNamedMetadata
|
||||||
+ HasCurrentCorpusId
|
+ HasCurrentCorpusId
|
||||||
+ MaybeHasClientPerfMonitor
|
+ MaybeHasClientPerfMonitor,
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
EM: UsesState<State = S>,
|
|
||||||
<S::Corpus as Corpus>::Input: Input,
|
<S::Corpus as Corpus>::Input: Input,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -176,9 +172,7 @@ where
|
|||||||
+ Debug
|
+ Debug
|
||||||
+ HasCurrentTestcase
|
+ HasCurrentTestcase
|
||||||
+ HasCurrentCorpusId
|
+ HasCurrentCorpusId
|
||||||
+ MaybeHasClientPerfMonitor
|
+ MaybeHasClientPerfMonitor,
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
EM: UsesState<State = S>,
|
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn perform(
|
fn perform(
|
||||||
@ -228,9 +222,8 @@ where
|
|||||||
impl<E, EM, SOT, S, Z> ShadowTracingStage<E, EM, SOT, S, Z>
|
impl<E, EM, SOT, S, Z> ShadowTracingStage<E, EM, SOT, S, Z>
|
||||||
where
|
where
|
||||||
E: Executor<EM, <S::Corpus as Corpus>::Input, S, Z> + HasObservers,
|
E: Executor<EM, <S::Corpus as Corpus>::Input, S, Z> + HasObservers,
|
||||||
S: HasExecutions + HasCorpus + UsesInput,
|
S: HasExecutions + HasCorpus,
|
||||||
SOT: ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
SOT: ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
EM: UsesState<State = S>,
|
|
||||||
{
|
{
|
||||||
/// Creates a new default stage
|
/// Creates a new default stage
|
||||||
pub fn new(_executor: &mut ShadowExecutor<E, S, SOT>) -> Self {
|
pub fn new(_executor: &mut ShadowExecutor<E, S, SOT>) -> Self {
|
||||||
|
@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use crate::monitors::PerfFeature;
|
use crate::monitors::PerfFeature;
|
||||||
use crate::{
|
use crate::{
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
inputs::{Input, UsesInput},
|
inputs::Input,
|
||||||
mark_feature_time,
|
mark_feature_time,
|
||||||
mutators::{MutationResult, Mutator},
|
mutators::{MutationResult, Mutator},
|
||||||
nonzero,
|
nonzero,
|
||||||
@ -203,8 +203,7 @@ where
|
|||||||
+ HasMetadata
|
+ HasMetadata
|
||||||
+ HasExecutions
|
+ HasExecutions
|
||||||
+ HasCurrentTestcase
|
+ HasCurrentTestcase
|
||||||
+ MaybeHasClientPerfMonitor
|
+ MaybeHasClientPerfMonitor,
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
I: MutatedTransform<<S::Corpus as Corpus>::Input, S> + Clone,
|
I: MutatedTransform<<S::Corpus as Corpus>::Input, S> + Clone,
|
||||||
<S::Corpus as Corpus>::Input: Input,
|
<S::Corpus as Corpus>::Input: Input,
|
||||||
{
|
{
|
||||||
@ -243,8 +242,7 @@ where
|
|||||||
+ HasExecutions
|
+ HasExecutions
|
||||||
+ HasMetadata
|
+ HasMetadata
|
||||||
+ HasCurrentTestcase
|
+ HasCurrentTestcase
|
||||||
+ MaybeHasClientPerfMonitor
|
+ MaybeHasClientPerfMonitor,
|
||||||
+ UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
I: MutatedTransform<<S::Corpus as Corpus>::Input, S> + Clone,
|
I: MutatedTransform<<S::Corpus as Corpus>::Input, S> + Clone,
|
||||||
<S::Corpus as Corpus>::Input: Input,
|
<S::Corpus as Corpus>::Input: Input,
|
||||||
{
|
{
|
||||||
|
@ -12,10 +12,10 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
|||||||
use crate::{
|
use crate::{
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
executors::{Executor, HasObservers, HasTimeout},
|
executors::{Executor, HasObservers, HasTimeout},
|
||||||
inputs::{BytesInput, UsesInput},
|
inputs::BytesInput,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
stages::Stage,
|
stages::Stage,
|
||||||
state::{HasCorpus, UsesState},
|
state::HasCorpus,
|
||||||
Evaluator, HasMetadata,
|
Evaluator, HasMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -85,9 +85,8 @@ impl<E, EM, S, Z> Stage<E, EM, S, Z> for VerifyTimeoutsStage<E, S>
|
|||||||
where
|
where
|
||||||
E::Observers: ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
E::Observers: ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
E: Executor<EM, <S::Corpus as Corpus>::Input, S, Z> + HasObservers + HasTimeout,
|
E: Executor<EM, <S::Corpus as Corpus>::Input, S, Z> + HasObservers + HasTimeout,
|
||||||
EM: UsesState<State = S>,
|
|
||||||
Z: Evaluator<E, EM, <S::Corpus as Corpus>::Input, S>,
|
Z: Evaluator<E, EM, <S::Corpus as Corpus>::Input, S>,
|
||||||
S: HasCorpus + HasMetadata + UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
S: HasCorpus + HasMetadata,
|
||||||
<S::Corpus as Corpus>::Input: Debug + Serialize + DeserializeOwned + Default + 'static + Clone,
|
<S::Corpus as Corpus>::Input: Debug + Serialize + DeserializeOwned + Default + 'static + Clone,
|
||||||
{
|
{
|
||||||
fn perform(
|
fn perform(
|
||||||
|
@ -28,15 +28,13 @@ pub use stack::StageStack;
|
|||||||
|
|
||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
use crate::monitors::ClientPerfMonitor;
|
use crate::monitors::ClientPerfMonitor;
|
||||||
#[cfg(feature = "scalability_introspection")]
|
|
||||||
use crate::monitors::ScalabilityMonitor;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
corpus::{Corpus, CorpusId, HasCurrentCorpusId, HasTestcase, InMemoryCorpus, Testcase},
|
corpus::{Corpus, CorpusId, HasCurrentCorpusId, HasTestcase, InMemoryCorpus, Testcase},
|
||||||
events::{Event, EventFirer, LogSeverity},
|
events::{Event, EventFirer, LogSeverity},
|
||||||
feedbacks::StateInitializer,
|
feedbacks::StateInitializer,
|
||||||
fuzzer::{Evaluator, ExecuteInputResult},
|
fuzzer::{Evaluator, ExecuteInputResult},
|
||||||
generators::Generator,
|
generators::Generator,
|
||||||
inputs::{Input, NopInput, UsesInput},
|
inputs::{Input, NopInput},
|
||||||
stages::{HasCurrentStageId, HasNestedStageStatus, StageId},
|
stages::{HasCurrentStageId, HasNestedStageStatus, StageId},
|
||||||
Error, HasMetadata, HasNamedMetadata,
|
Error, HasMetadata, HasNamedMetadata,
|
||||||
};
|
};
|
||||||
@ -44,35 +42,6 @@ use crate::{
|
|||||||
/// The maximum size of a testcase
|
/// The maximum size of a testcase
|
||||||
pub const DEFAULT_MAX_SIZE: usize = 1_048_576;
|
pub const DEFAULT_MAX_SIZE: usize = 1_048_576;
|
||||||
|
|
||||||
/// The [`State`] of the fuzzer.
|
|
||||||
/// Contains all important information about the current run.
|
|
||||||
/// Will be used to restart the fuzzing process at any time.
|
|
||||||
pub trait State:
|
|
||||||
UsesInput
|
|
||||||
+ Serialize
|
|
||||||
+ DeserializeOwned
|
|
||||||
+ MaybeHasClientPerfMonitor
|
|
||||||
+ MaybeHasScalabilityMonitor
|
|
||||||
+ HasCurrentCorpusId
|
|
||||||
+ HasCurrentStageId
|
|
||||||
+ Stoppable
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Structs which implement this trait are aware of the state. This is used for type enforcement.
|
|
||||||
pub trait UsesState: UsesInput<Input = <Self::State as UsesInput>::Input> {
|
|
||||||
/// The state known by this type.
|
|
||||||
type State: State;
|
|
||||||
}
|
|
||||||
|
|
||||||
// blanket impl which automatically defines UsesInput for anything that implements UsesState
|
|
||||||
impl<KS> UsesInput for KS
|
|
||||||
where
|
|
||||||
KS: UsesState,
|
|
||||||
{
|
|
||||||
type Input = <KS::State as UsesInput>::Input;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Trait for elements offering a corpus
|
/// Trait for elements offering a corpus
|
||||||
pub trait HasCorpus {
|
pub trait HasCorpus {
|
||||||
/// The associated type implementing [`Corpus`].
|
/// The associated type implementing [`Corpus`].
|
||||||
@ -84,6 +53,32 @@ pub trait HasCorpus {
|
|||||||
fn corpus_mut(&mut self) -> &mut Self::Corpus;
|
fn corpus_mut(&mut self) -> &mut Self::Corpus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The trait that implements the very standard capability of a state.
|
||||||
|
/// This state contains important information about the current run
|
||||||
|
/// and can be used to restart the fuzzing process at any time.
|
||||||
|
///
|
||||||
|
/// This [`State`] is here for documentation purpose.
|
||||||
|
/// You should *NOT* implement this trait for any of your struct,
|
||||||
|
/// but when you implement your customized state, you can look at this trait to see what would be needed.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
trait State:
|
||||||
|
Serialize
|
||||||
|
+ DeserializeOwned
|
||||||
|
+ MaybeHasClientPerfMonitor
|
||||||
|
+ HasCurrentCorpusId
|
||||||
|
+ HasCurrentStageId
|
||||||
|
+ Stoppable
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I, C, R, SC> State for StdState<I, C, R, SC>
|
||||||
|
where
|
||||||
|
C: Serialize + DeserializeOwned,
|
||||||
|
R: Rand,
|
||||||
|
SC: Serialize + DeserializeOwned,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// Reflexivity
|
// Reflexivity
|
||||||
impl<C> HasCorpus for C
|
impl<C> HasCorpus for C
|
||||||
where
|
where
|
||||||
@ -153,29 +148,6 @@ impl<T> MaybeHasClientPerfMonitor for T {}
|
|||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
impl<T> MaybeHasClientPerfMonitor for T where T: HasClientPerfMonitor {}
|
impl<T> MaybeHasClientPerfMonitor for T where T: HasClientPerfMonitor {}
|
||||||
|
|
||||||
/// Intermediate trait for `HasScalabilityMonitor`
|
|
||||||
#[cfg(feature = "scalability_introspection")]
|
|
||||||
pub trait MaybeHasScalabilityMonitor: HasScalabilityMonitor {}
|
|
||||||
/// Intermediate trait for `HasScalabilityMonitor`
|
|
||||||
#[cfg(not(feature = "scalability_introspection"))]
|
|
||||||
pub trait MaybeHasScalabilityMonitor {}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "scalability_introspection"))]
|
|
||||||
impl<T> MaybeHasScalabilityMonitor for T {}
|
|
||||||
|
|
||||||
#[cfg(feature = "scalability_introspection")]
|
|
||||||
impl<T> MaybeHasScalabilityMonitor for T where T: HasScalabilityMonitor {}
|
|
||||||
|
|
||||||
/// Trait for offering a [`ScalabilityMonitor`]
|
|
||||||
#[cfg(feature = "scalability_introspection")]
|
|
||||||
pub trait HasScalabilityMonitor {
|
|
||||||
/// Ref to [`ScalabilityMonitor`]
|
|
||||||
fn scalability_monitor(&self) -> &ScalabilityMonitor;
|
|
||||||
|
|
||||||
/// Mutable ref to [`ScalabilityMonitor`]
|
|
||||||
fn scalability_monitor_mut(&mut self) -> &mut ScalabilityMonitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Trait for the execution counter
|
/// Trait for the execution counter
|
||||||
pub trait HasExecutions {
|
pub trait HasExecutions {
|
||||||
/// The executions counter
|
/// The executions counter
|
||||||
@ -270,8 +242,6 @@ pub struct StdState<I, C, R, SC> {
|
|||||||
/// Performance statistics for this fuzzer
|
/// Performance statistics for this fuzzer
|
||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
introspection_monitor: ClientPerfMonitor,
|
introspection_monitor: ClientPerfMonitor,
|
||||||
#[cfg(feature = "scalability_introspection")]
|
|
||||||
scalability_monitor: ScalabilityMonitor,
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
/// Remaining initial inputs to load, if any
|
/// Remaining initial inputs to load, if any
|
||||||
remaining_initial_files: Option<Vec<PathBuf>>,
|
remaining_initial_files: Option<Vec<PathBuf>>,
|
||||||
@ -296,22 +266,6 @@ pub struct StdState<I, C, R, SC> {
|
|||||||
phantom: PhantomData<I>,
|
phantom: PhantomData<I>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, C, R, SC> UsesInput for StdState<I, C, R, SC>
|
|
||||||
where
|
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
type Input = I;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I, C, R, SC> State for StdState<I, C, R, SC>
|
|
||||||
where
|
|
||||||
C: Corpus<Input = Self::Input> + Serialize + DeserializeOwned,
|
|
||||||
R: Rand,
|
|
||||||
SC: Corpus<Input = Self::Input> + Serialize + DeserializeOwned,
|
|
||||||
Self: UsesInput,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I, C, R, SC> HasRand for StdState<I, C, R, SC>
|
impl<I, C, R, SC> HasRand for StdState<I, C, R, SC>
|
||||||
where
|
where
|
||||||
R: Rand,
|
R: Rand,
|
||||||
@ -368,7 +322,8 @@ where
|
|||||||
impl<I, C, R, SC> HasSolutions for StdState<I, C, R, SC>
|
impl<I, C, R, SC> HasSolutions for StdState<I, C, R, SC>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
SC: Corpus<Input = <Self as UsesInput>::Input>,
|
C: Corpus,
|
||||||
|
SC: Corpus<Input = C::Input>,
|
||||||
{
|
{
|
||||||
type Solutions = SC;
|
type Solutions = SC;
|
||||||
|
|
||||||
@ -629,9 +584,9 @@ impl<I, C, R, SC> HasNestedStageStatus for StdState<I, C, R, SC> {
|
|||||||
impl<C, I, R, SC> StdState<I, C, R, SC>
|
impl<C, I, R, SC> StdState<I, C, R, SC>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<Input = <Self as UsesInput>::Input>,
|
|
||||||
R: Rand,
|
R: Rand,
|
||||||
SC: Corpus<Input = <Self as UsesInput>::Input>,
|
C: Corpus,
|
||||||
|
SC: Corpus<Input = C::Input>,
|
||||||
{
|
{
|
||||||
/// Decide if the state must load the inputs
|
/// Decide if the state must load the inputs
|
||||||
pub fn must_load_initial_inputs(&self) -> bool {
|
pub fn must_load_initial_inputs(&self) -> bool {
|
||||||
@ -723,7 +678,7 @@ where
|
|||||||
load_config: LoadConfig<I, Self, Z>,
|
load_config: LoadConfig<I, Self, Z>,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = Self>,
|
EM: EventFirer<I, Self>,
|
||||||
Z: Evaluator<E, EM, I, Self>,
|
Z: Evaluator<E, EM, I, Self>,
|
||||||
{
|
{
|
||||||
if let Some(remaining) = self.remaining_initial_files.as_ref() {
|
if let Some(remaining) = self.remaining_initial_files.as_ref() {
|
||||||
@ -747,7 +702,7 @@ where
|
|||||||
config: &mut LoadConfig<I, Self, Z>,
|
config: &mut LoadConfig<I, Self, Z>,
|
||||||
) -> Result<ExecuteInputResult, Error>
|
) -> Result<ExecuteInputResult, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = Self>,
|
EM: EventFirer<I, Self>,
|
||||||
Z: Evaluator<E, EM, I, Self>,
|
Z: Evaluator<E, EM, I, Self>,
|
||||||
{
|
{
|
||||||
log::info!("Loading file {path:?} ...");
|
log::info!("Loading file {path:?} ...");
|
||||||
@ -781,7 +736,7 @@ where
|
|||||||
mut config: LoadConfig<I, Self, Z>,
|
mut config: LoadConfig<I, Self, Z>,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = Self>,
|
EM: EventFirer<I, Self>,
|
||||||
Z: Evaluator<E, EM, I, Self>,
|
Z: Evaluator<E, EM, I, Self>,
|
||||||
{
|
{
|
||||||
loop {
|
loop {
|
||||||
@ -845,7 +800,7 @@ where
|
|||||||
file_list: &[PathBuf],
|
file_list: &[PathBuf],
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = Self>,
|
EM: EventFirer<I, Self>,
|
||||||
Z: Evaluator<E, EM, I, Self>,
|
Z: Evaluator<E, EM, I, Self>,
|
||||||
{
|
{
|
||||||
self.load_initial_inputs_custom_by_filenames(
|
self.load_initial_inputs_custom_by_filenames(
|
||||||
@ -872,7 +827,7 @@ where
|
|||||||
in_dirs: &[PathBuf],
|
in_dirs: &[PathBuf],
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = Self>,
|
EM: EventFirer<I, Self>,
|
||||||
Z: Evaluator<E, EM, I, Self>,
|
Z: Evaluator<E, EM, I, Self>,
|
||||||
{
|
{
|
||||||
self.canonicalize_input_dirs(in_dirs)?;
|
self.canonicalize_input_dirs(in_dirs)?;
|
||||||
@ -898,7 +853,7 @@ where
|
|||||||
file_list: &[PathBuf],
|
file_list: &[PathBuf],
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = Self>,
|
EM: EventFirer<I, Self>,
|
||||||
Z: Evaluator<E, EM, I, Self>,
|
Z: Evaluator<E, EM, I, Self>,
|
||||||
{
|
{
|
||||||
self.load_initial_inputs_custom_by_filenames(
|
self.load_initial_inputs_custom_by_filenames(
|
||||||
@ -923,7 +878,7 @@ where
|
|||||||
in_dirs: &[PathBuf],
|
in_dirs: &[PathBuf],
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = Self>,
|
EM: EventFirer<I, Self>,
|
||||||
Z: Evaluator<E, EM, I, Self>,
|
Z: Evaluator<E, EM, I, Self>,
|
||||||
{
|
{
|
||||||
self.canonicalize_input_dirs(in_dirs)?;
|
self.canonicalize_input_dirs(in_dirs)?;
|
||||||
@ -949,7 +904,7 @@ where
|
|||||||
in_dirs: &[PathBuf],
|
in_dirs: &[PathBuf],
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = Self>,
|
EM: EventFirer<I, Self>,
|
||||||
Z: Evaluator<E, EM, I, Self>,
|
Z: Evaluator<E, EM, I, Self>,
|
||||||
{
|
{
|
||||||
self.canonicalize_input_dirs(in_dirs)?;
|
self.canonicalize_input_dirs(in_dirs)?;
|
||||||
@ -990,7 +945,7 @@ where
|
|||||||
cores: &Cores,
|
cores: &Cores,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = Self>,
|
EM: EventFirer<I, Self>,
|
||||||
Z: Evaluator<E, EM, I, Self>,
|
Z: Evaluator<E, EM, I, Self>,
|
||||||
{
|
{
|
||||||
if self.multicore_inputs_processed.unwrap_or(false) {
|
if self.multicore_inputs_processed.unwrap_or(false) {
|
||||||
@ -1070,9 +1025,9 @@ where
|
|||||||
impl<C, I, R, SC> StdState<I, C, R, SC>
|
impl<C, I, R, SC> StdState<I, C, R, SC>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<Input = <Self as UsesInput>::Input>,
|
C: Corpus<Input = I>,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
SC: Corpus<Input = <Self as UsesInput>::Input>,
|
SC: Corpus<Input = I>,
|
||||||
{
|
{
|
||||||
fn generate_initial_internal<G, E, EM, Z>(
|
fn generate_initial_internal<G, E, EM, Z>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -1084,8 +1039,8 @@ where
|
|||||||
forced: bool,
|
forced: bool,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = Self>,
|
EM: EventFirer<I, Self>,
|
||||||
G: Generator<<Self as UsesInput>::Input, Self>,
|
G: Generator<C::Input, Self>,
|
||||||
Z: Evaluator<E, EM, I, Self>,
|
Z: Evaluator<E, EM, I, Self>,
|
||||||
{
|
{
|
||||||
let mut added = 0;
|
let mut added = 0;
|
||||||
@ -1122,8 +1077,8 @@ where
|
|||||||
num: usize,
|
num: usize,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = Self>,
|
EM: EventFirer<I, Self>,
|
||||||
G: Generator<<Self as UsesInput>::Input, Self>,
|
G: Generator<C::Input, Self>,
|
||||||
Z: Evaluator<E, EM, I, Self>,
|
Z: Evaluator<E, EM, I, Self>,
|
||||||
{
|
{
|
||||||
self.generate_initial_internal(fuzzer, executor, generator, manager, num, true)
|
self.generate_initial_internal(fuzzer, executor, generator, manager, num, true)
|
||||||
@ -1139,8 +1094,8 @@ where
|
|||||||
num: usize,
|
num: usize,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = Self>,
|
EM: EventFirer<I, Self>,
|
||||||
G: Generator<<Self as UsesInput>::Input, Self>,
|
G: Generator<C::Input, Self>,
|
||||||
Z: Evaluator<E, EM, I, Self>,
|
Z: Evaluator<E, EM, I, Self>,
|
||||||
{
|
{
|
||||||
self.generate_initial_internal(fuzzer, executor, generator, manager, num, false)
|
self.generate_initial_internal(fuzzer, executor, generator, manager, num, false)
|
||||||
@ -1173,8 +1128,6 @@ where
|
|||||||
stop_requested: false,
|
stop_requested: false,
|
||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
introspection_monitor: ClientPerfMonitor::new(),
|
introspection_monitor: ClientPerfMonitor::new(),
|
||||||
#[cfg(feature = "scalability_introspection")]
|
|
||||||
scalability_monitor: ScalabilityMonitor::new(),
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
remaining_initial_files: None,
|
remaining_initial_files: None,
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -1221,17 +1174,6 @@ impl<I, C, R, SC> HasClientPerfMonitor for StdState<I, C, R, SC> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "scalability_introspection")]
|
|
||||||
impl<I, C, R, SC> HasScalabilityMonitor for StdState<I, C, R, SC> {
|
|
||||||
fn scalability_monitor(&self) -> &ScalabilityMonitor {
|
|
||||||
&self.scalability_monitor
|
|
||||||
}
|
|
||||||
|
|
||||||
fn scalability_monitor_mut(&mut self) -> &mut ScalabilityMonitor {
|
|
||||||
&mut self.scalability_monitor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A very simple state without any bells or whistles, for testing.
|
/// A very simple state without any bells or whistles, for testing.
|
||||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
pub struct NopState<I> {
|
pub struct NopState<I> {
|
||||||
@ -1280,13 +1222,6 @@ impl<I> HasCorpus for NopState<I> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I> UsesInput for NopState<I>
|
|
||||||
where
|
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
type Input = I;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I> HasExecutions for NopState<I> {
|
impl<I> HasExecutions for NopState<I> {
|
||||||
fn executions(&self) -> &u64 {
|
fn executions(&self) -> &u64 {
|
||||||
&self.execution
|
&self.execution
|
||||||
@ -1353,8 +1288,6 @@ impl<I> HasRand for NopState<I> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I> State for NopState<I> where I: Input {}
|
|
||||||
|
|
||||||
impl<I> HasCurrentCorpusId for NopState<I> {
|
impl<I> HasCurrentCorpusId for NopState<I> {
|
||||||
fn set_corpus_id(&mut self, _id: CorpusId) -> Result<(), Error> {
|
fn set_corpus_id(&mut self, _id: CorpusId) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -1394,17 +1327,6 @@ impl<I> HasClientPerfMonitor for NopState<I> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "scalability_introspection")]
|
|
||||||
impl<I> HasScalabilityMonitor for NopState<I> {
|
|
||||||
fn scalability_monitor(&self) -> &ScalabilityMonitor {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn scalability_monitor_mut(&mut self) -> &mut ScalabilityMonitor {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::{inputs::BytesInput, state::StdState};
|
use crate::{inputs::BytesInput, state::StdState};
|
||||||
|
@ -13,11 +13,11 @@ use color_backtrace::{default_output_stream, BacktracePrinter, Verbosity};
|
|||||||
use frida_gum::interceptor::Interceptor;
|
use frida_gum::interceptor::Interceptor;
|
||||||
use frida_gum::ModuleDetails;
|
use frida_gum::ModuleDetails;
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::Testcase,
|
corpus::{Corpus, Testcase},
|
||||||
executors::ExitKind,
|
executors::ExitKind,
|
||||||
feedbacks::{Feedback, StateInitializer},
|
feedbacks::{Feedback, StateInitializer},
|
||||||
observers::Observer,
|
observers::Observer,
|
||||||
state::State,
|
state::HasCorpus,
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
@ -648,16 +648,16 @@ pub struct AsanErrorsFeedback<S> {
|
|||||||
|
|
||||||
impl<S> StateInitializer<S> for AsanErrorsFeedback<S> {}
|
impl<S> StateInitializer<S> for AsanErrorsFeedback<S> {}
|
||||||
|
|
||||||
impl<EM, OT, S> Feedback<EM, S::Input, OT, S> for AsanErrorsFeedback<S>
|
impl<EM, OT, S> Feedback<EM, <S::Corpus as Corpus>::Input, OT, S> for AsanErrorsFeedback<S>
|
||||||
where
|
where
|
||||||
S: State + Debug,
|
S: HasCorpus + Debug,
|
||||||
OT: MatchNameRef,
|
OT: MatchNameRef,
|
||||||
{
|
{
|
||||||
fn is_interesting(
|
fn is_interesting(
|
||||||
&mut self,
|
&mut self,
|
||||||
_state: &mut S,
|
_state: &mut S,
|
||||||
_manager: &mut EM,
|
_manager: &mut EM,
|
||||||
_input: &S::Input,
|
_input: &<S::Corpus as Corpus>::Input,
|
||||||
observers: &OT,
|
observers: &OT,
|
||||||
_exit_kind: &ExitKind,
|
_exit_kind: &ExitKind,
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
@ -678,7 +678,7 @@ where
|
|||||||
_state: &mut S,
|
_state: &mut S,
|
||||||
_manager: &mut EM,
|
_manager: &mut EM,
|
||||||
_observers: &OT,
|
_observers: &OT,
|
||||||
testcase: &mut Testcase<S::Input>,
|
testcase: &mut Testcase<<S::Corpus as Corpus>::Input>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
if let Some(errors) = &self.errors {
|
if let Some(errors) = &self.errors {
|
||||||
testcase.add_metadata(errors.clone());
|
testcase.add_metadata(errors.clone());
|
||||||
@ -687,7 +687,11 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn discard_metadata(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
|
fn discard_metadata(
|
||||||
|
&mut self,
|
||||||
|
_state: &mut S,
|
||||||
|
_input: &<S::Corpus as Corpus>::Input,
|
||||||
|
) -> Result<(), Error> {
|
||||||
self.errors = None;
|
self.errors = None;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,9 @@ use libafl::{
|
|||||||
};
|
};
|
||||||
use libafl::{
|
use libafl::{
|
||||||
executors::{Executor, ExitKind, HasObservers, InProcessExecutor},
|
executors::{Executor, ExitKind, HasObservers, InProcessExecutor},
|
||||||
inputs::{NopTargetBytesConverter, TargetBytesConverter, UsesInput},
|
inputs::{NopTargetBytesConverter, TargetBytesConverter},
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
state::{HasCorpus, HasExecutions, UsesState},
|
state::{HasCorpus, HasExecutions},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{tuples::RefIndexable, AsSlice};
|
use libafl_bolts::{tuples::RefIndexable, AsSlice};
|
||||||
@ -59,9 +59,8 @@ where
|
|||||||
impl<EM, H, I, OT, RT, S, TC, Z> Executor<EM, I, S, Z>
|
impl<EM, H, I, OT, RT, S, TC, Z> Executor<EM, I, S, Z>
|
||||||
for FridaInProcessExecutor<'_, '_, '_, H, I, OT, RT, S, TC>
|
for FridaInProcessExecutor<'_, '_, '_, H, I, OT, RT, S, TC>
|
||||||
where
|
where
|
||||||
EM: UsesState<State = S>,
|
|
||||||
H: FnMut(&I) -> ExitKind,
|
H: FnMut(&I) -> ExitKind,
|
||||||
S: HasCorpus + HasExecutions + UsesInput<Input = I>,
|
S: HasCorpus + HasExecutions,
|
||||||
TC: TargetBytesConverter<Input = I>,
|
TC: TargetBytesConverter<Input = I>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
RT: FridaRuntimeTuple,
|
RT: FridaRuntimeTuple,
|
||||||
@ -226,7 +225,7 @@ impl<'a, 'b, 'c, H, I, OT, RT, S, TC> HasInProcessHooks<I, S>
|
|||||||
for FridaInProcessExecutor<'a, 'b, 'c, H, I, OT, RT, S, TC>
|
for FridaInProcessExecutor<'a, 'b, 'c, H, I, OT, RT, S, TC>
|
||||||
where
|
where
|
||||||
H: FnMut(&I) -> ExitKind,
|
H: FnMut(&I) -> ExitKind,
|
||||||
S: HasSolutions + HasCorpus + HasCurrentTestcase + HasExecutions + UsesInput<Input = I>,
|
S: HasSolutions + HasCorpus + HasCurrentTestcase + HasExecutions,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
TC: TargetBytesConverter<Input = I>,
|
TC: TargetBytesConverter<Input = I>,
|
||||||
|
@ -161,7 +161,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
.arg(&archive_path)
|
.arg(&archive_path)
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("llvm-nm works (are you using nightly?)");
|
.expect("llvm-nm does not work (are you using nightly? or did you install by rustup component add llvm-tools?)");
|
||||||
|
|
||||||
let mut redefinitions_file = BufWriter::new(File::create(&redefined_symbols).unwrap());
|
let mut redefinitions_file = BufWriter::new(File::create(&redefined_symbols).unwrap());
|
||||||
|
|
||||||
|
@ -4,11 +4,11 @@ use std::borrow::Cow;
|
|||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
alloc,
|
alloc,
|
||||||
corpus::Testcase,
|
corpus::{Corpus, Testcase},
|
||||||
executors::ExitKind,
|
executors::ExitKind,
|
||||||
feedbacks::{Feedback, MinMapFeedback, StateInitializer},
|
feedbacks::{Feedback, MinMapFeedback, StateInitializer},
|
||||||
inputs::{BytesInput, Input},
|
inputs::{BytesInput, Input},
|
||||||
state::State,
|
state::HasCorpus,
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{impl_serdeany, tuples::MatchNameRef, Named};
|
use libafl_bolts::{impl_serdeany, tuples::MatchNameRef, Named};
|
||||||
@ -43,15 +43,15 @@ impl Named for LibfuzzerKeepFeedback {
|
|||||||
|
|
||||||
impl<S> StateInitializer<S> for LibfuzzerKeepFeedback {}
|
impl<S> StateInitializer<S> for LibfuzzerKeepFeedback {}
|
||||||
|
|
||||||
impl<EM, OT, S> Feedback<EM, S::Input, OT, S> for LibfuzzerKeepFeedback
|
impl<EM, OT, S> Feedback<EM, <S::Corpus as Corpus>::Input, OT, S> for LibfuzzerKeepFeedback
|
||||||
where
|
where
|
||||||
S: State,
|
S: HasCorpus,
|
||||||
{
|
{
|
||||||
fn is_interesting(
|
fn is_interesting(
|
||||||
&mut self,
|
&mut self,
|
||||||
_state: &mut S,
|
_state: &mut S,
|
||||||
_manager: &mut EM,
|
_manager: &mut EM,
|
||||||
_input: &S::Input,
|
_input: &<S::Corpus as Corpus>::Input,
|
||||||
_observers: &OT,
|
_observers: &OT,
|
||||||
_exit_kind: &ExitKind,
|
_exit_kind: &ExitKind,
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
@ -119,7 +119,6 @@ impl<S> StateInitializer<S> for LibfuzzerCrashCauseFeedback {}
|
|||||||
|
|
||||||
impl<EM, OT, S> Feedback<EM, BytesInput, OT, S> for LibfuzzerCrashCauseFeedback
|
impl<EM, OT, S> Feedback<EM, BytesInput, OT, S> for LibfuzzerCrashCauseFeedback
|
||||||
where
|
where
|
||||||
S: State<Input = BytesInput>,
|
|
||||||
OT: MatchNameRef,
|
OT: MatchNameRef,
|
||||||
{
|
{
|
||||||
fn is_interesting(
|
fn is_interesting(
|
||||||
|
@ -17,10 +17,9 @@ use libafl::{
|
|||||||
SimpleRestartingEventManager,
|
SimpleRestartingEventManager,
|
||||||
},
|
},
|
||||||
executors::ExitKind,
|
executors::ExitKind,
|
||||||
inputs::UsesInput,
|
|
||||||
monitors::{tui::TuiMonitor, Monitor, MultiMonitor},
|
monitors::{tui::TuiMonitor, Monitor, MultiMonitor},
|
||||||
stages::{HasCurrentStageId, StagesTuple},
|
stages::{HasCurrentStageId, StagesTuple},
|
||||||
state::{HasExecutions, HasLastReportTime, HasSolutions, Stoppable, UsesState},
|
state::{HasExecutions, HasLastReportTime, HasSolutions, Stoppable},
|
||||||
Error, Fuzzer, HasMetadata,
|
Error, Fuzzer, HasMetadata,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
@ -65,12 +64,11 @@ where
|
|||||||
F: Fuzzer<E, EM, S, ST>,
|
F: Fuzzer<E, EM, S, ST>,
|
||||||
S: HasMetadata
|
S: HasMetadata
|
||||||
+ HasExecutions
|
+ HasExecutions
|
||||||
+ UsesInput
|
|
||||||
+ HasSolutions
|
+ HasSolutions
|
||||||
+ HasLastReportTime
|
+ HasLastReportTime
|
||||||
+ HasCurrentStageId
|
+ HasCurrentStageId
|
||||||
+ Stoppable,
|
+ Stoppable,
|
||||||
EM: ProgressReporter<State = S> + EventProcessor<E, F>,
|
EM: ProgressReporter<S> + EventProcessor<E, S, F>,
|
||||||
ST: StagesTuple<E, EM, S, F>,
|
ST: StagesTuple<E, EM, S, F>,
|
||||||
{
|
{
|
||||||
if let Some(solution) = state.solutions().last() {
|
if let Some(solution) = state.solutions().last() {
|
||||||
@ -113,7 +111,7 @@ where
|
|||||||
fuzz_with!(options, harness, do_fuzz, |fuzz_single| {
|
fuzz_with!(options, harness, do_fuzz, |fuzz_single| {
|
||||||
let (state, mgr): (
|
let (state, mgr): (
|
||||||
Option<StdState<_, _, _, _>>,
|
Option<StdState<_, _, _, _>>,
|
||||||
SimpleRestartingEventManager<_, StdState<_, _, _, _>, _>,
|
SimpleRestartingEventManager<_, _, StdState<_, _, _, _>, _>,
|
||||||
) = match SimpleRestartingEventManager::launch(monitor, &mut shmem_provider) {
|
) = match SimpleRestartingEventManager::launch(monitor, &mut shmem_provider) {
|
||||||
// The restarting state will spawn the same process again as child, then restarted it each time it crashes.
|
// The restarting state will spawn the same process again as child, then restarted it each time it crashes.
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
|
@ -9,7 +9,7 @@ use std::{
|
|||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
events::{EventRestarter, SimpleRestartingEventManager},
|
events::{EventRestarter, ManagerExit, SimpleRestartingEventManager},
|
||||||
executors::{ExitKind, InProcessExecutor},
|
executors::{ExitKind, InProcessExecutor},
|
||||||
feedback_and_fast, feedback_or_fast,
|
feedback_and_fast, feedback_or_fast,
|
||||||
feedbacks::{CrashFeedback, MinMapFeedback, TimeoutFeedback},
|
feedbacks::{CrashFeedback, MinMapFeedback, TimeoutFeedback},
|
||||||
@ -69,7 +69,7 @@ pub fn merge(
|
|||||||
|
|
||||||
let (state, mut mgr): (
|
let (state, mut mgr): (
|
||||||
Option<StdState<_, _, _, _>>,
|
Option<StdState<_, _, _, _>>,
|
||||||
SimpleRestartingEventManager<_, StdState<_, _, _, _>, _>,
|
SimpleRestartingEventManager<_, _, StdState<_, _, _, _>, _>,
|
||||||
) = match SimpleRestartingEventManager::launch(monitor, &mut shmem_provider) {
|
) = match SimpleRestartingEventManager::launch(monitor, &mut shmem_provider) {
|
||||||
// The restarting state will spawn the same process again as child, then restarted it each time it crashes.
|
// The restarting state will spawn the same process again as child, then restarted it each time it crashes.
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
|
@ -7,10 +7,10 @@ use std::{
|
|||||||
|
|
||||||
use ahash::AHasher;
|
use ahash::AHasher;
|
||||||
use libafl::{
|
use libafl::{
|
||||||
|
corpus::Corpus,
|
||||||
executors::ExitKind,
|
executors::ExitKind,
|
||||||
inputs::UsesInput,
|
|
||||||
observers::{MapObserver, Observer, TimeObserver},
|
observers::{MapObserver, Observer, TimeObserver},
|
||||||
state::UsesState,
|
state::HasCorpus,
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{AsIter, HasLen, Named};
|
use libafl_bolts::{AsIter, HasLen, Named};
|
||||||
@ -158,13 +158,17 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M, O, S> Observer<S::Input, S> for MappedEdgeMapObserver<M, O>
|
impl<M, O, S> Observer<<S::Corpus as Corpus>::Input, S> for MappedEdgeMapObserver<M, O>
|
||||||
where
|
where
|
||||||
M: Observer<S::Input, S> + Debug,
|
S: HasCorpus,
|
||||||
O: Observer<S::Input, S> + Debug,
|
M: Observer<<S::Corpus as Corpus>::Input, S> + Debug,
|
||||||
S: UsesInput,
|
O: Observer<<S::Corpus as Corpus>::Input, S> + Debug,
|
||||||
{
|
{
|
||||||
fn pre_exec(&mut self, state: &mut S, input: &S::Input) -> Result<(), Error> {
|
fn pre_exec(
|
||||||
|
&mut self,
|
||||||
|
state: &mut S,
|
||||||
|
input: &<S::Corpus as Corpus>::Input,
|
||||||
|
) -> Result<(), Error> {
|
||||||
self.inner.pre_exec(state, input)?;
|
self.inner.pre_exec(state, input)?;
|
||||||
self.value_observer.pre_exec(state, input)
|
self.value_observer.pre_exec(state, input)
|
||||||
}
|
}
|
||||||
@ -172,7 +176,7 @@ where
|
|||||||
fn post_exec(
|
fn post_exec(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &S::Input,
|
input: &<S::Corpus as Corpus>::Input,
|
||||||
exit_kind: &ExitKind,
|
exit_kind: &ExitKind,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
self.inner.post_exec(state, input, exit_kind)?;
|
self.inner.post_exec(state, input, exit_kind)?;
|
||||||
@ -255,12 +259,16 @@ impl Named for SizeValueObserver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Observer<S::Input, S> for SizeValueObserver
|
impl<S> Observer<<S::Corpus as Corpus>::Input, S> for SizeValueObserver
|
||||||
where
|
where
|
||||||
S: UsesInput,
|
S: HasCorpus,
|
||||||
S::Input: HasLen,
|
<S::Corpus as Corpus>::Input: HasLen,
|
||||||
{
|
{
|
||||||
fn pre_exec(&mut self, _state: &mut S, input: &S::Input) -> Result<(), Error> {
|
fn pre_exec(
|
||||||
|
&mut self,
|
||||||
|
_state: &mut S,
|
||||||
|
input: &<S::Corpus as Corpus>::Input,
|
||||||
|
) -> Result<(), Error> {
|
||||||
self.size = input.len();
|
self.size = input.len();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -299,18 +307,22 @@ impl Named for TimeValueObserver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Observer<S::Input, S> for TimeValueObserver
|
impl<S> Observer<<S::Corpus as Corpus>::Input, S> for TimeValueObserver
|
||||||
where
|
where
|
||||||
S: UsesInput,
|
S: HasCorpus,
|
||||||
{
|
{
|
||||||
fn pre_exec(&mut self, state: &mut S, input: &S::Input) -> Result<(), Error> {
|
fn pre_exec(
|
||||||
|
&mut self,
|
||||||
|
state: &mut S,
|
||||||
|
input: &<S::Corpus as Corpus>::Input,
|
||||||
|
) -> Result<(), Error> {
|
||||||
self.time_obs.pre_exec(state, input)
|
self.time_obs.pre_exec(state, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post_exec(
|
fn post_exec(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &S::Input,
|
input: &<S::Corpus as Corpus>::Input,
|
||||||
exit_kind: &ExitKind,
|
exit_kind: &ExitKind,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
self.time_obs.post_exec(state, input, exit_kind)?;
|
self.time_obs.post_exec(state, input, exit_kind)?;
|
||||||
@ -361,12 +373,16 @@ impl Named for SizeTimeValueObserver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Observer<S::Input, S> for SizeTimeValueObserver
|
impl<S> Observer<<S::Corpus as Corpus>::Input, S> for SizeTimeValueObserver
|
||||||
where
|
where
|
||||||
S: UsesInput,
|
S: HasCorpus,
|
||||||
S::Input: HasLen,
|
<S::Corpus as Corpus>::Input: HasLen,
|
||||||
{
|
{
|
||||||
fn pre_exec(&mut self, state: &mut S, input: &S::Input) -> Result<(), Error> {
|
fn pre_exec(
|
||||||
|
&mut self,
|
||||||
|
state: &mut S,
|
||||||
|
input: &<S::Corpus as Corpus>::Input,
|
||||||
|
) -> Result<(), Error> {
|
||||||
self.size_obs.pre_exec(state, input)?;
|
self.size_obs.pre_exec(state, input)?;
|
||||||
self.time_obs.pre_exec(state, input)
|
self.time_obs.pre_exec(state, input)
|
||||||
}
|
}
|
||||||
@ -374,7 +390,7 @@ where
|
|||||||
fn post_exec(
|
fn post_exec(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &S::Input,
|
input: &<S::Corpus as Corpus>::Input,
|
||||||
exit_kind: &ExitKind,
|
exit_kind: &ExitKind,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
self.time_obs.post_exec(state, input, exit_kind)?;
|
self.time_obs.post_exec(state, input, exit_kind)?;
|
||||||
|
@ -4,10 +4,9 @@ use libafl::{
|
|||||||
events::{EventProcessor, ProgressReporter, SimpleEventManager},
|
events::{EventProcessor, ProgressReporter, SimpleEventManager},
|
||||||
executors::HasObservers,
|
executors::HasObservers,
|
||||||
feedbacks::MapFeedbackMetadata,
|
feedbacks::MapFeedbackMetadata,
|
||||||
inputs::UsesInput,
|
|
||||||
monitors::SimpleMonitor,
|
monitors::SimpleMonitor,
|
||||||
stages::{HasCurrentStageId, StagesTuple},
|
stages::{HasCurrentStageId, StagesTuple},
|
||||||
state::{HasExecutions, HasLastReportTime, Stoppable, UsesState},
|
state::{HasExecutions, HasLastReportTime, Stoppable},
|
||||||
Error, Fuzzer, HasMetadata, HasNamedMetadata,
|
Error, Fuzzer, HasMetadata, HasNamedMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -27,12 +26,11 @@ where
|
|||||||
S: HasMetadata
|
S: HasMetadata
|
||||||
+ HasNamedMetadata
|
+ HasNamedMetadata
|
||||||
+ HasExecutions
|
+ HasExecutions
|
||||||
+ UsesInput
|
|
||||||
+ HasLastReportTime
|
+ HasLastReportTime
|
||||||
+ HasCurrentStageId
|
+ HasCurrentStageId
|
||||||
+ Stoppable,
|
+ Stoppable,
|
||||||
E: HasObservers,
|
E: HasObservers,
|
||||||
EM: ProgressReporter<State = S> + EventProcessor<E, F>,
|
EM: ProgressReporter<S> + EventProcessor<E, S, F>,
|
||||||
ST: StagesTuple<E, EM, S, F>,
|
ST: StagesTuple<E, EM, S, F>,
|
||||||
{
|
{
|
||||||
let meta = state
|
let meta = state
|
||||||
|
@ -6,7 +6,7 @@ use libafl::{
|
|||||||
feedbacks::MapNoveltiesMetadata,
|
feedbacks::MapNoveltiesMetadata,
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
schedulers::{RemovableScheduler, Scheduler},
|
schedulers::{RemovableScheduler, Scheduler},
|
||||||
state::{HasCorpus, State},
|
state::HasCorpus,
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ pub struct MergeScheduler<I, S> {
|
|||||||
impl<I, S> RemovableScheduler<I, S> for MergeScheduler<I, S>
|
impl<I, S> RemovableScheduler<I, S> for MergeScheduler<I, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
S: State + HasCorpus,
|
S: HasCorpus,
|
||||||
{
|
{
|
||||||
fn on_remove(
|
fn on_remove(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -35,7 +35,7 @@ where
|
|||||||
|
|
||||||
impl<I, S> Scheduler<I, S> for MergeScheduler<I, S>
|
impl<I, S> Scheduler<I, S> for MergeScheduler<I, S>
|
||||||
where
|
where
|
||||||
S: State + HasCorpus,
|
S: HasCorpus,
|
||||||
{
|
{
|
||||||
fn on_add(&mut self, state: &mut S, id: CorpusId) -> Result<(), Error> {
|
fn on_add(&mut self, state: &mut S, id: CorpusId) -> Result<(), Error> {
|
||||||
self.all.insert(id);
|
self.all.insert(id);
|
||||||
|
@ -7,9 +7,9 @@ use std::{
|
|||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
executors::{Executor, ExitKind, HasObservers, HasTimeout},
|
executors::{Executor, ExitKind, HasObservers, HasTimeout},
|
||||||
inputs::{HasTargetBytes, UsesInput},
|
inputs::HasTargetBytes,
|
||||||
observers::{ObserversTuple, StdOutObserver},
|
observers::{ObserversTuple, StdOutObserver},
|
||||||
state::{HasCorpus, HasExecutions, UsesState},
|
state::{HasCorpus, HasExecutions},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{tuples::RefIndexable, AsSlice};
|
use libafl_bolts::{tuples::RefIndexable, AsSlice};
|
||||||
@ -41,8 +41,7 @@ impl NyxExecutor<(), ()> {
|
|||||||
|
|
||||||
impl<EM, S, Z, OT> Executor<EM, <S::Corpus as Corpus>::Input, S, Z> for NyxExecutor<S, OT>
|
impl<EM, S, Z, OT> Executor<EM, <S::Corpus as Corpus>::Input, S, Z> for NyxExecutor<S, OT>
|
||||||
where
|
where
|
||||||
EM: UsesState<State = S>,
|
S: HasCorpus + HasExecutions,
|
||||||
S: HasCorpus + HasExecutions + UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
<S::Corpus as Corpus>::Input: HasTargetBytes,
|
<S::Corpus as Corpus>::Input: HasTargetBytes,
|
||||||
OT: ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
OT: ObserversTuple<<S::Corpus as Corpus>::Input, S>,
|
||||||
{
|
{
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{inputs::HasTargetBytes, state::HasExecutions};
|
||||||
inputs::HasTargetBytes,
|
|
||||||
state::{HasExecutions, State},
|
|
||||||
};
|
|
||||||
use libafl_bolts::tuples::{tuple_list, Append, Prepend};
|
use libafl_bolts::tuples::{tuple_list, Append, Prepend};
|
||||||
|
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
@ -74,7 +71,7 @@ impl<C, I, S>
|
|||||||
StdSnapshotManager,
|
StdSnapshotManager,
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
S: State + HasExecutions + Unpin,
|
S: HasExecutions + Unpin,
|
||||||
I: HasTargetBytes,
|
I: HasTargetBytes,
|
||||||
{
|
{
|
||||||
#[must_use]
|
#[must_use]
|
||||||
@ -104,7 +101,7 @@ impl<C, I, S>
|
|||||||
StdSnapshotManager,
|
StdSnapshotManager,
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
S: State + HasExecutions + Unpin,
|
S: HasExecutions + Unpin,
|
||||||
I: HasTargetBytes,
|
I: HasTargetBytes,
|
||||||
{
|
{
|
||||||
#[expect(clippy::should_implement_trait)]
|
#[expect(clippy::should_implement_trait)]
|
||||||
|
@ -7,10 +7,7 @@ use std::{cell::RefCell, ops::Add, pin::Pin};
|
|||||||
|
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use libafl::{
|
use libafl::{
|
||||||
executors::ExitKind,
|
executors::ExitKind, inputs::HasTargetBytes, observers::ObserversTuple, state::HasExecutions,
|
||||||
inputs::HasTargetBytes,
|
|
||||||
observers::ObserversTuple,
|
|
||||||
state::{HasExecutions, State},
|
|
||||||
};
|
};
|
||||||
use libafl_qemu_sys::{GuestAddr, GuestPhysAddr, GuestUsize, GuestVirtAddr};
|
use libafl_qemu_sys::{GuestAddr, GuestPhysAddr, GuestUsize, GuestVirtAddr};
|
||||||
|
|
||||||
@ -253,7 +250,7 @@ impl<C, I, S> Emulator<C, NopCommandManager, NopEmulatorDriver, (), I, S, NopSna
|
|||||||
|
|
||||||
impl<C, I, S> Emulator<C, StdCommandManager<S>, StdEmulatorDriver, (), I, S, StdSnapshotManager>
|
impl<C, I, S> Emulator<C, StdCommandManager<S>, StdEmulatorDriver, (), I, S, StdSnapshotManager>
|
||||||
where
|
where
|
||||||
S: State + HasExecutions + Unpin,
|
S: HasExecutions + Unpin,
|
||||||
I: HasTargetBytes,
|
I: HasTargetBytes,
|
||||||
{
|
{
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -20,9 +20,9 @@ use libafl::{
|
|||||||
},
|
},
|
||||||
feedbacks::Feedback,
|
feedbacks::Feedback,
|
||||||
fuzzer::HasObjective,
|
fuzzer::HasObjective,
|
||||||
inputs::{Input, UsesInput},
|
inputs::Input,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions, State, UsesState},
|
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions},
|
||||||
Error, ExecutionProcessor, HasScheduler,
|
Error, ExecutionProcessor, HasScheduler,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "fork")]
|
#[cfg(feature = "fork")]
|
||||||
@ -92,11 +92,11 @@ pub unsafe fn inproc_qemu_timeout_handler<E, EM, ET, I, OF, S, Z>(
|
|||||||
) where
|
) where
|
||||||
E: HasObservers + HasInProcessHooks<I, S> + Executor<EM, I, S, Z>,
|
E: HasObservers + HasInProcessHooks<I, S> + Executor<EM, I, S, Z>,
|
||||||
E::Observers: ObserversTuple<I, S>,
|
E::Observers: ObserversTuple<I, S>,
|
||||||
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
ET: EmulatorModuleTuple<I, S>,
|
ET: EmulatorModuleTuple<I, S>,
|
||||||
I: Unpin,
|
I: Unpin,
|
||||||
OF: Feedback<EM, I, E::Observers, S>,
|
OF: Feedback<EM, I, E::Observers, S>,
|
||||||
S: HasExecutions + HasSolutions + HasCorpus + Unpin + HasCurrentTestcase + UsesInput<Input = I>,
|
S: HasExecutions + HasSolutions + HasCorpus + Unpin + HasCurrentTestcase,
|
||||||
I: Input,
|
I: Input,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
@ -152,7 +152,7 @@ where
|
|||||||
H: FnMut(&mut Emulator<C, CM, ED, ET, I, S, SM>, &mut S, &I) -> ExitKind,
|
H: FnMut(&mut Emulator<C, CM, ED, ET, I, S, SM>, &mut S, &I) -> ExitKind,
|
||||||
I: Input + Unpin,
|
I: Input + Unpin,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasCorpus + Unpin + HasExecutions + HasSolutions + State<Input = I>,
|
S: HasCorpus + Unpin + HasExecutions + HasSolutions + HasCurrentTestcase,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
{
|
{
|
||||||
pub fn new<EM, OF, Z>(
|
pub fn new<EM, OF, Z>(
|
||||||
@ -168,7 +168,7 @@ where
|
|||||||
C: Clone,
|
C: Clone,
|
||||||
CM: CommandManager<C, ED, ET, I, S, SM, Commands = C>,
|
CM: CommandManager<C, ED, ET, I, S, SM, Commands = C>,
|
||||||
ED: EmulatorDriver<C, CM, ET, I, S, SM>,
|
ED: EmulatorDriver<C, CM, ET, I, S, SM>,
|
||||||
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, OT, S>,
|
OF: Feedback<EM, I, OT, S>,
|
||||||
Z: HasObjective<Objective = OF> + HasScheduler<I, S> + ExecutionProcessor<EM, I, OT, S>,
|
Z: HasObjective<Objective = OF> + HasScheduler<I, S> + ExecutionProcessor<EM, I, OT, S>,
|
||||||
<S as HasCorpus>::Corpus: Corpus<Input = I>,
|
<S as HasCorpus>::Corpus: Corpus<Input = I>,
|
||||||
@ -248,12 +248,11 @@ where
|
|||||||
C: Clone,
|
C: Clone,
|
||||||
CM: CommandManager<C, ED, ET, I, S, SM, Commands = C>,
|
CM: CommandManager<C, ED, ET, I, S, SM, Commands = C>,
|
||||||
ED: EmulatorDriver<C, CM, ET, I, S, SM>,
|
ED: EmulatorDriver<C, CM, ET, I, S, SM>,
|
||||||
EM: UsesState<State = S>,
|
|
||||||
ET: EmulatorModuleTuple<I, S>,
|
ET: EmulatorModuleTuple<I, S>,
|
||||||
H: FnMut(&mut Emulator<C, CM, ED, ET, I, S, SM>, &mut S, &I) -> ExitKind,
|
H: FnMut(&mut Emulator<C, CM, ED, ET, I, S, SM>, &mut S, &I) -> ExitKind,
|
||||||
I: Unpin,
|
I: Unpin,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: State + HasExecutions + Unpin + HasCorpus,
|
S: HasExecutions + Unpin + HasCorpus,
|
||||||
{
|
{
|
||||||
fn run_target(
|
fn run_target(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -290,7 +289,7 @@ where
|
|||||||
ET: EmulatorModuleTuple<I, S>,
|
ET: EmulatorModuleTuple<I, S>,
|
||||||
H: FnMut(&mut Emulator<C, CM, ED, ET, I, S, SM>, &mut S, &I) -> ExitKind,
|
H: FnMut(&mut Emulator<C, CM, ED, ET, I, S, SM>, &mut S, &I) -> ExitKind,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: State + HasCorpus,
|
S: HasCorpus,
|
||||||
{
|
{
|
||||||
type Observers = OT;
|
type Observers = OT;
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -318,12 +317,11 @@ impl<C, CM, ED, EM, ET, H, I, OT, S, SM, SP, Z> Debug
|
|||||||
where
|
where
|
||||||
C: Debug,
|
C: Debug,
|
||||||
CM: Debug,
|
CM: Debug,
|
||||||
EM: UsesState<State = S>,
|
|
||||||
ED: Debug,
|
ED: Debug,
|
||||||
ET: EmulatorModuleTuple<I, S> + Debug,
|
ET: EmulatorModuleTuple<I, S> + Debug,
|
||||||
OT: ObserversTuple<I, S> + Debug,
|
OT: ObserversTuple<I, S> + Debug,
|
||||||
I: Debug,
|
I: Debug,
|
||||||
S: UsesInput<Input = I> + Debug,
|
S: Debug,
|
||||||
SM: Debug,
|
SM: Debug,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
@ -339,10 +337,10 @@ where
|
|||||||
impl<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, SP, Z>
|
impl<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, SP, Z>
|
||||||
QemuForkExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, SP, Z>
|
QemuForkExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, SP, Z>
|
||||||
where
|
where
|
||||||
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
ET: EmulatorModuleTuple<I, S>,
|
ET: EmulatorModuleTuple<I, S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: State + HasSolutions + HasCorpus,
|
S: HasSolutions + HasCorpus,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
Z: HasObjective,
|
Z: HasObjective,
|
||||||
Z::Objective: Feedback<EM, I, OT, S>,
|
Z::Objective: Feedback<EM, I, OT, S>,
|
||||||
@ -404,13 +402,13 @@ where
|
|||||||
C: Clone,
|
C: Clone,
|
||||||
CM: CommandManager<C, ED, ET, I, S, SM, Commands = C>,
|
CM: CommandManager<C, ED, ET, I, S, SM, Commands = C>,
|
||||||
ED: EmulatorDriver<C, CM, ET, I, S, SM>,
|
ED: EmulatorDriver<C, CM, ET, I, S, SM>,
|
||||||
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
ET: EmulatorModuleTuple<I, S>,
|
ET: EmulatorModuleTuple<I, S>,
|
||||||
H: FnMut(&mut Emulator<C, CM, ED, ET, I, S, SM>, &I) -> ExitKind,
|
H: FnMut(&mut Emulator<C, CM, ED, ET, I, S, SM>, &I) -> ExitKind,
|
||||||
OF: Feedback<EM, I, OT, S>,
|
OF: Feedback<EM, I, OT, S>,
|
||||||
OT: ObserversTuple<I, S> + Debug,
|
OT: ObserversTuple<I, S> + Debug,
|
||||||
I: Input + Unpin,
|
I: Input + Unpin,
|
||||||
S: State + HasExecutions + Unpin + HasCorpus,
|
S: HasExecutions + Unpin + HasCorpus,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
{
|
{
|
||||||
@ -438,26 +436,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "fork")]
|
|
||||||
impl<C, CM, ED, EM, ET, H, I, OT, S, SM, SP, Z> UsesState
|
|
||||||
for QemuForkExecutor<'_, C, CM, ED, EM, ET, H, I, OT, S, SM, SP, Z>
|
|
||||||
where
|
|
||||||
ET: EmulatorModuleTuple<I, S>,
|
|
||||||
OT: ObserversTuple<I, S>,
|
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
|
||||||
{
|
|
||||||
type State = S;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "fork")]
|
#[cfg(feature = "fork")]
|
||||||
impl<C, CM, ED, EM, ET, H, I, OT, S, SM, SP, Z> HasObservers
|
impl<C, CM, ED, EM, ET, H, I, OT, S, SM, SP, Z> HasObservers
|
||||||
for QemuForkExecutor<'_, C, CM, ED, EM, ET, H, I, OT, S, SM, SP, Z>
|
for QemuForkExecutor<'_, C, CM, ED, EM, ET, H, I, OT, S, SM, SP, Z>
|
||||||
where
|
where
|
||||||
EM: UsesState<State = S>,
|
|
||||||
ET: EmulatorModuleTuple<I, S>,
|
ET: EmulatorModuleTuple<I, S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: State,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
type Observers = OT;
|
type Observers = OT;
|
||||||
|
@ -4,10 +4,10 @@ use core::marker::PhantomData;
|
|||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{Corpus, HasCurrentCorpusId},
|
corpus::{Corpus, HasCurrentCorpusId},
|
||||||
executors::{Executor, HasObservers},
|
executors::{Executor, HasObservers},
|
||||||
inputs::{BytesInput, UsesInput},
|
inputs::BytesInput,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
stages::{colorization::TaintMetadata, RetryCountRestartHelper, Stage},
|
stages::{colorization::TaintMetadata, RetryCountRestartHelper, Stage},
|
||||||
state::{HasCorpus, HasCurrentTestcase, UsesState},
|
state::{HasCorpus, HasCurrentTestcase},
|
||||||
Error, HasMetadata, HasNamedMetadata,
|
Error, HasMetadata, HasNamedMetadata,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
@ -36,15 +36,9 @@ impl<EM, TE, S, Z> Named for AFLppCmplogTracingStage<'_, EM, TE, S, Z> {
|
|||||||
|
|
||||||
impl<E, EM, TE, S, Z> Stage<E, EM, S, Z> for AFLppCmplogTracingStage<'_, EM, TE, S, Z>
|
impl<E, EM, TE, S, Z> Stage<E, EM, S, Z> for AFLppCmplogTracingStage<'_, EM, TE, S, Z>
|
||||||
where
|
where
|
||||||
EM: UsesState<State = S>,
|
|
||||||
TE: HasObservers + Executor<EM, BytesInput, S, Z>,
|
TE: HasObservers + Executor<EM, BytesInput, S, Z>,
|
||||||
TE::Observers: MatchNameRef + ObserversTuple<BytesInput, S>,
|
TE::Observers: MatchNameRef + ObserversTuple<BytesInput, S>,
|
||||||
S: HasCorpus
|
S: HasCorpus + HasCurrentTestcase + HasMetadata + HasNamedMetadata + HasCurrentCorpusId,
|
||||||
+ HasCurrentTestcase
|
|
||||||
+ UsesInput<Input = BytesInput>
|
|
||||||
+ HasMetadata
|
|
||||||
+ HasNamedMetadata
|
|
||||||
+ HasCurrentCorpusId,
|
|
||||||
S::Corpus: Corpus<Input = BytesInput>,
|
S::Corpus: Corpus<Input = BytesInput>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -11,7 +11,7 @@ use std::{
|
|||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
inputs::{BytesInput, HasMutatorBytes, UsesInput},
|
inputs::{BytesInput, HasMutatorBytes},
|
||||||
mutators::{
|
mutators::{
|
||||||
ComposedByMutations, MutationId, MutationResult, Mutator, MutatorsTuple, ScheduledMutator,
|
ComposedByMutations, MutationId, MutationResult, Mutator, MutatorsTuple, ScheduledMutator,
|
||||||
},
|
},
|
||||||
@ -152,7 +152,7 @@ where
|
|||||||
F: Fn(&mut dyn for<'b> FnMut(&'b mut S)) -> bool,
|
F: Fn(&mut dyn for<'b> FnMut(&'b mut S)) -> bool,
|
||||||
M: ScheduledMutator<BytesInput, S>,
|
M: ScheduledMutator<BytesInput, S>,
|
||||||
M::Mutations: MutatorsTuple<BytesInput, S>,
|
M::Mutations: MutatorsTuple<BytesInput, S>,
|
||||||
S: HasMaxSize + UsesInput<Input = BytesInput>,
|
S: HasMaxSize,
|
||||||
{
|
{
|
||||||
fn mutate(&self, data: *mut u8, size: usize, max_size: usize) -> usize {
|
fn mutate(&self, data: *mut u8, size: usize, max_size: usize) -> usize {
|
||||||
let mut new_size = 0; // if access fails, the new len is zero
|
let mut new_size = 0; // if access fails, the new len is zero
|
||||||
@ -290,12 +290,12 @@ impl<S, SM> Named for LLVMCustomMutator<S, SM, false> {
|
|||||||
|
|
||||||
impl<S, SM> Mutator<BytesInput, S> for LLVMCustomMutator<S, SM, false>
|
impl<S, SM> Mutator<BytesInput, S> for LLVMCustomMutator<S, SM, false>
|
||||||
where
|
where
|
||||||
S: UsesInput<Input = BytesInput> + HasRand + HasMaxSize + 'static,
|
S: HasRand + HasMaxSize + 'static,
|
||||||
SM: ScheduledMutator<BytesInput, S> + 'static,
|
SM: ScheduledMutator<BytesInput, S> + 'static,
|
||||||
SM::Mutations: MutatorsTuple<BytesInput, S>,
|
SM::Mutations: MutatorsTuple<BytesInput, S>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mutate(&mut self, state: &mut S, input: &mut S::Input) -> Result<MutationResult, Error> {
|
fn mutate(&mut self, state: &mut S, input: &mut BytesInput) -> Result<MutationResult, Error> {
|
||||||
self.scheduled_mutate(state, input)
|
self.scheduled_mutate(state, input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -303,15 +303,15 @@ where
|
|||||||
impl<S, SM> ScheduledMutator<BytesInput, S> for LLVMCustomMutator<S, SM, false>
|
impl<S, SM> ScheduledMutator<BytesInput, S> for LLVMCustomMutator<S, SM, false>
|
||||||
where
|
where
|
||||||
SM: ScheduledMutator<BytesInput, S> + 'static,
|
SM: ScheduledMutator<BytesInput, S> + 'static,
|
||||||
S: UsesInput<Input = BytesInput> + HasRand + HasMaxSize + 'static,
|
S: HasRand + HasMaxSize + 'static,
|
||||||
SM::Mutations: MutatorsTuple<BytesInput, S>,
|
SM::Mutations: MutatorsTuple<BytesInput, S>,
|
||||||
{
|
{
|
||||||
fn iterations(&self, state: &mut S, input: &S::Input) -> u64 {
|
fn iterations(&self, state: &mut S, input: &BytesInput) -> u64 {
|
||||||
let mutator = self.mutator.deref().borrow();
|
let mutator = self.mutator.deref().borrow();
|
||||||
mutator.iterations(state, input)
|
mutator.iterations(state, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn schedule(&self, state: &mut S, input: &S::Input) -> MutationId {
|
fn schedule(&self, state: &mut S, input: &BytesInput) -> MutationId {
|
||||||
let mutator = self.mutator.deref().borrow();
|
let mutator = self.mutator.deref().borrow();
|
||||||
mutator.schedule(state, input)
|
mutator.schedule(state, input)
|
||||||
}
|
}
|
||||||
@ -319,7 +319,7 @@ where
|
|||||||
fn scheduled_mutate(
|
fn scheduled_mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut S::Input,
|
input: &mut BytesInput,
|
||||||
) -> Result<MutationResult, Error> {
|
) -> Result<MutationResult, Error> {
|
||||||
let seed = state.rand_mut().next();
|
let seed = state.rand_mut().next();
|
||||||
let len_orig = input.bytes().len();
|
let len_orig = input.bytes().len();
|
||||||
@ -367,13 +367,13 @@ impl<S, SM> Named for LLVMCustomMutator<S, SM, true> {
|
|||||||
|
|
||||||
impl<S, SM> Mutator<BytesInput, S> for LLVMCustomMutator<S, SM, true>
|
impl<S, SM> Mutator<BytesInput, S> for LLVMCustomMutator<S, SM, true>
|
||||||
where
|
where
|
||||||
S: UsesInput<Input = BytesInput> + HasRand + HasMaxSize + HasCorpus + 'static,
|
S: HasRand + HasMaxSize + HasCorpus + 'static,
|
||||||
SM: ScheduledMutator<BytesInput, S> + 'static,
|
SM: ScheduledMutator<BytesInput, S> + 'static,
|
||||||
S::Corpus: Corpus<Input = BytesInput>,
|
S::Corpus: Corpus<Input = BytesInput>,
|
||||||
SM::Mutations: MutatorsTuple<BytesInput, S>,
|
SM::Mutations: MutatorsTuple<BytesInput, S>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mutate(&mut self, state: &mut S, input: &mut S::Input) -> Result<MutationResult, Error> {
|
fn mutate(&mut self, state: &mut S, input: &mut BytesInput) -> Result<MutationResult, Error> {
|
||||||
self.scheduled_mutate(state, input)
|
self.scheduled_mutate(state, input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -381,16 +381,16 @@ where
|
|||||||
impl<S, SM> ScheduledMutator<BytesInput, S> for LLVMCustomMutator<S, SM, true>
|
impl<S, SM> ScheduledMutator<BytesInput, S> for LLVMCustomMutator<S, SM, true>
|
||||||
where
|
where
|
||||||
SM: ScheduledMutator<BytesInput, S> + 'static,
|
SM: ScheduledMutator<BytesInput, S> + 'static,
|
||||||
S: UsesInput<Input = BytesInput> + HasRand + HasMaxSize + HasCorpus + 'static,
|
S: HasRand + HasMaxSize + HasCorpus + 'static,
|
||||||
S::Corpus: Corpus<Input = BytesInput>,
|
S::Corpus: Corpus<Input = BytesInput>,
|
||||||
SM::Mutations: MutatorsTuple<BytesInput, S>,
|
SM::Mutations: MutatorsTuple<BytesInput, S>,
|
||||||
{
|
{
|
||||||
fn iterations(&self, state: &mut S, input: &S::Input) -> u64 {
|
fn iterations(&self, state: &mut S, input: &BytesInput) -> u64 {
|
||||||
let mutator = self.mutator.deref().borrow();
|
let mutator = self.mutator.deref().borrow();
|
||||||
mutator.iterations(state, input)
|
mutator.iterations(state, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn schedule(&self, state: &mut S, input: &S::Input) -> MutationId {
|
fn schedule(&self, state: &mut S, input: &BytesInput) -> MutationId {
|
||||||
let mutator = self.mutator.deref().borrow();
|
let mutator = self.mutator.deref().borrow();
|
||||||
mutator.schedule(state, input)
|
mutator.schedule(state, input)
|
||||||
}
|
}
|
||||||
@ -398,7 +398,7 @@ where
|
|||||||
fn scheduled_mutate(
|
fn scheduled_mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
input: &mut S::Input,
|
input: &mut BytesInput,
|
||||||
) -> Result<MutationResult, Error> {
|
) -> Result<MutationResult, Error> {
|
||||||
let id = random_corpus_id_with_disabled!(state.corpus(), state.rand_mut());
|
let id = random_corpus_id_with_disabled!(state.corpus(), state.rand_mut());
|
||||||
// We don't want to use the testcase we're already using for splicing
|
// We don't want to use the testcase we're already using for splicing
|
||||||
|
@ -5,7 +5,7 @@ use libafl::{
|
|||||||
events::{EventFirer, EventRestarter},
|
events::{EventFirer, EventRestarter},
|
||||||
executors::{hooks::windows::windows_asan_handler::asan_death_handler, Executor, HasObservers},
|
executors::{hooks::windows::windows_asan_handler::asan_death_handler, Executor, HasObservers},
|
||||||
feedbacks::Feedback,
|
feedbacks::Feedback,
|
||||||
inputs::{Input, UsesInput},
|
inputs::Input,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions},
|
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions},
|
||||||
HasObjective,
|
HasObjective,
|
||||||
@ -34,9 +34,9 @@ pub unsafe fn setup_asan_callback<E, EM, I, OF, S, Z>(_executor: &E, _event_mgr:
|
|||||||
where
|
where
|
||||||
E: Executor<EM, I, S, Z> + HasObservers,
|
E: Executor<EM, I, S, Z> + HasObservers,
|
||||||
E::Observers: ObserversTuple<I, S>,
|
E::Observers: ObserversTuple<I, S>,
|
||||||
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
EM: EventFirer<I, S> + EventRestarter<S>,
|
||||||
OF: Feedback<EM, I, E::Observers, S>,
|
OF: Feedback<EM, I, E::Observers, S>,
|
||||||
S: HasExecutions + HasSolutions + HasCurrentTestcase + HasCorpus + UsesInput<Input = I>,
|
S: HasExecutions + HasSolutions + HasCurrentTestcase + HasCorpus,
|
||||||
S::Solutions: Corpus<Input = I>,
|
S::Solutions: Corpus<Input = I>,
|
||||||
Z: HasObjective<Objective = OF>,
|
Z: HasObjective<Objective = OF>,
|
||||||
I: Input + Clone,
|
I: Input + Clone,
|
||||||
|
@ -3,8 +3,8 @@ use core::{marker::PhantomData, ptr, time::Duration};
|
|||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
executors::{Executor, ExitKind, HasObservers},
|
executors::{Executor, ExitKind, HasObservers},
|
||||||
inputs::{HasTargetBytes, UsesInput},
|
inputs::HasTargetBytes,
|
||||||
state::{HasCorpus, HasExecutions, UsesState},
|
state::{HasCorpus, HasExecutions},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
@ -51,8 +51,7 @@ where
|
|||||||
impl<EM, S, SP, OT, Z> Executor<EM, <S::Corpus as Corpus>::Input, S, Z>
|
impl<EM, S, SP, OT, Z> Executor<EM, <S::Corpus as Corpus>::Input, S, Z>
|
||||||
for TinyInstExecutor<S, SP, OT>
|
for TinyInstExecutor<S, SP, OT>
|
||||||
where
|
where
|
||||||
EM: UsesState<State = S>,
|
S: HasCorpus + HasExecutions,
|
||||||
S: HasCorpus + HasExecutions + UsesInput<Input = <S::Corpus as Corpus>::Input>,
|
|
||||||
<S::Corpus as Corpus>::Input: HasTargetBytes,
|
<S::Corpus as Corpus>::Input: HasTargetBytes,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user