fix qemu launcher bug (#3206)
* no more shellscript * metadatas * clp * clippo * fix bug * taplo * Merge branch 'qemu_launcher_insane' of github.com:AFLplusplus/LibAFL into qemu_launcher_insane * fix wrong code
This commit is contained in:
parent
60c05396da
commit
390008e1d5
@ -2,9 +2,10 @@ use std::env;
|
|||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{InMemoryOnDiskCorpus, OnDiskCorpus},
|
corpus::{InMemoryOnDiskCorpus, OnDiskCorpus},
|
||||||
events::ClientDescription,
|
events::{
|
||||||
|
ClientDescription, EventFirer, EventReceiver, EventRestarter, ProgressReporter, SendExiting,
|
||||||
|
},
|
||||||
inputs::BytesInput,
|
inputs::BytesInput,
|
||||||
monitors::Monitor,
|
|
||||||
state::StdState,
|
state::StdState,
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
@ -14,11 +15,7 @@ use libafl_qemu::modules::{
|
|||||||
utils::filters::StdAddressFilter, DrCovModule, InjectionModule,
|
utils::filters::StdAddressFilter, DrCovModule, InjectionModule,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{harness::Harness, instance::Instance, options::FuzzerOptions};
|
||||||
harness::Harness,
|
|
||||||
instance::{ClientMgr, Instance},
|
|
||||||
options::FuzzerOptions,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[expect(clippy::module_name_repetitions)]
|
#[expect(clippy::module_name_repetitions)]
|
||||||
pub type ClientState =
|
pub type ClientState =
|
||||||
@ -51,12 +48,19 @@ impl Client<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[expect(clippy::too_many_lines)]
|
#[expect(clippy::too_many_lines)]
|
||||||
pub fn run<M: Monitor>(
|
pub fn run<EM>(
|
||||||
&self,
|
&self,
|
||||||
state: Option<ClientState>,
|
state: Option<ClientState>,
|
||||||
mgr: ClientMgr<M>,
|
mgr: EM,
|
||||||
client_description: ClientDescription,
|
client_description: ClientDescription,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error>
|
||||||
|
where
|
||||||
|
EM: EventFirer<BytesInput, ClientState>
|
||||||
|
+ EventRestarter<ClientState>
|
||||||
|
+ ProgressReporter<ClientState>
|
||||||
|
+ SendExiting
|
||||||
|
+ EventReceiver<BytesInput, ClientState>,
|
||||||
|
{
|
||||||
let core_id = client_description.core_id();
|
let core_id = client_description.core_id();
|
||||||
let mut args = self.args()?;
|
let mut args = self.args()?;
|
||||||
Harness::edit_args(&mut args);
|
Harness::edit_args(&mut args);
|
||||||
|
@ -5,20 +5,16 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
#[cfg(feature = "simplemgr")]
|
|
||||||
use libafl::events::SimpleEventManager;
|
|
||||||
#[cfg(not(feature = "simplemgr"))]
|
#[cfg(not(feature = "simplemgr"))]
|
||||||
use libafl::events::{EventConfig, Launcher, LlmpEventManagerBuilder, MonitorTypedEventManager};
|
use libafl::events::{EventConfig, Launcher};
|
||||||
use libafl::{
|
use libafl::{
|
||||||
events::ClientDescription,
|
events::{ClientDescription, SimpleEventManager},
|
||||||
monitors::{tui::TuiMonitor, Monitor, MultiMonitor},
|
monitors::{tui::TuiMonitor, Monitor, MultiMonitor},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
#[cfg(not(feature = "simplemgr"))]
|
#[cfg(not(feature = "simplemgr"))]
|
||||||
use libafl_bolts::shmem::{ShMemProvider, StdShMemProvider};
|
use libafl_bolts::shmem::{ShMemProvider, StdShMemProvider};
|
||||||
use libafl_bolts::{core_affinity::CoreId, current_time};
|
use libafl_bolts::{core_affinity::CoreId, current_time};
|
||||||
#[cfg(not(feature = "simplemgr"))]
|
|
||||||
use libafl_bolts::{llmp::LlmpBroker, staterestore::StateRestorer, tuples::tuple_list};
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use {
|
use {
|
||||||
nix::unistd::dup,
|
nix::unistd::dup,
|
||||||
@ -84,7 +80,8 @@ impl Fuzzer {
|
|||||||
{
|
{
|
||||||
// The shared memory allocator
|
// The shared memory allocator
|
||||||
#[cfg(not(feature = "simplemgr"))]
|
#[cfg(not(feature = "simplemgr"))]
|
||||||
let mut shmem_provider = StdShMemProvider::new()?;
|
let shmem_provider = StdShMemProvider::new()?;
|
||||||
|
|
||||||
/* If we are running in verbose, don't provide a replacement stdout, otherwise, use /dev/null */
|
/* If we are running in verbose, don't provide a replacement stdout, otherwise, use /dev/null */
|
||||||
#[cfg(not(feature = "simplemgr"))]
|
#[cfg(not(feature = "simplemgr"))]
|
||||||
let stdout = if self.options.verbose {
|
let stdout = if self.options.verbose {
|
||||||
@ -95,45 +92,10 @@ impl Fuzzer {
|
|||||||
|
|
||||||
let client = Client::new(&self.options);
|
let client = Client::new(&self.options);
|
||||||
|
|
||||||
#[cfg(not(feature = "simplemgr"))]
|
|
||||||
if self.options.rerun_input.is_some() {
|
|
||||||
// If we want to rerun a single input but we use a restarting mgr, we'll have to create a fake restarting mgr that doesn't actually restart.
|
|
||||||
// It's not pretty but better than recompiling with simplemgr.
|
|
||||||
|
|
||||||
// Just a random number, let's hope it's free :)
|
|
||||||
let broker_port = 13120;
|
|
||||||
let _fake_broker = LlmpBroker::create_attach_to_tcp(
|
|
||||||
shmem_provider.clone(),
|
|
||||||
tuple_list!(),
|
|
||||||
broker_port,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// To rerun an input, instead of using a launcher, we create dummy parameters and run the client directly.
|
|
||||||
// NOTE: This is a hack for debugging that that will only work for non-crashing inputs.
|
|
||||||
return client.run(
|
|
||||||
None,
|
|
||||||
MonitorTypedEventManager::<_, M>::new(
|
|
||||||
LlmpEventManagerBuilder::builder()
|
|
||||||
.build_on_port(
|
|
||||||
shmem_provider.clone(),
|
|
||||||
broker_port,
|
|
||||||
EventConfig::AlwaysUnique,
|
|
||||||
Some(StateRestorer::new(
|
|
||||||
shmem_provider.new_shmem(0x1000).unwrap(),
|
|
||||||
)),
|
|
||||||
)
|
|
||||||
.unwrap(),
|
|
||||||
),
|
|
||||||
ClientDescription::new(0, 0, CoreId(0)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "simplemgr")]
|
|
||||||
if self.options.rerun_input.is_some() {
|
if self.options.rerun_input.is_some() {
|
||||||
return client.run(
|
return client.run(
|
||||||
None,
|
None,
|
||||||
SimpleEventManager::new(monitor),
|
SimpleEventManager::new(monitor.clone()),
|
||||||
ClientDescription::new(0, 0, CoreId(0)),
|
ClientDescription::new(0, 0, CoreId(0)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -141,7 +103,7 @@ impl Fuzzer {
|
|||||||
#[cfg(feature = "simplemgr")]
|
#[cfg(feature = "simplemgr")]
|
||||||
return client.run(
|
return client.run(
|
||||||
None,
|
None,
|
||||||
SimpleEventManager::new(monitor),
|
SimpleEventManager::new(monitor.clone()),
|
||||||
ClientDescription::new(0, 0, CoreId(0)),
|
ClientDescription::new(0, 0, CoreId(0)),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -152,7 +114,7 @@ impl Fuzzer {
|
|||||||
.broker_port(self.options.port)
|
.broker_port(self.options.port)
|
||||||
.configuration(EventConfig::from_build_id())
|
.configuration(EventConfig::from_build_id())
|
||||||
.monitor(monitor)
|
.monitor(monitor)
|
||||||
.run_client(|s, m, c| client.run(s, MonitorTypedEventManager::<_, M>::new(m), c))
|
.run_client(|s, m, c| client.run(s, m, c))
|
||||||
.cores(&self.options.cores)
|
.cores(&self.options.cores)
|
||||||
.stdout_file(stdout)
|
.stdout_file(stdout)
|
||||||
.stderr_file(stdout)
|
.stderr_file(stdout)
|
||||||
|
@ -1,19 +1,16 @@
|
|||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
use std::{fs, marker::PhantomData, ops::Range, process};
|
use std::{fs, ops::Range, process};
|
||||||
|
|
||||||
#[cfg(feature = "simplemgr")]
|
|
||||||
use libafl::events::SimpleEventManager;
|
|
||||||
#[cfg(not(feature = "simplemgr"))]
|
|
||||||
use libafl::events::{LlmpRestartingEventManager, MonitorTypedEventManager};
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{Corpus, HasCurrentCorpusId, InMemoryOnDiskCorpus, OnDiskCorpus},
|
corpus::{Corpus, HasCurrentCorpusId, InMemoryOnDiskCorpus, OnDiskCorpus},
|
||||||
events::{ClientDescription, EventRestarter},
|
events::{
|
||||||
|
ClientDescription, EventFirer, EventReceiver, EventRestarter, ProgressReporter, SendExiting,
|
||||||
|
},
|
||||||
executors::{Executor, ExitKind, ShadowExecutor},
|
executors::{Executor, ExitKind, ShadowExecutor},
|
||||||
feedback_and_fast, feedback_or, feedback_or_fast,
|
feedback_and_fast, feedback_or, feedback_or_fast,
|
||||||
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
||||||
fuzzer::{Evaluator, Fuzzer, StdFuzzer},
|
fuzzer::{Evaluator, Fuzzer, StdFuzzer},
|
||||||
inputs::{BytesInput, Input},
|
inputs::{BytesInput, Input},
|
||||||
monitors::Monitor,
|
|
||||||
mutators::{
|
mutators::{
|
||||||
havoc_mutations, token_mutations::I2SRandReplace, tokens_mutations, HavocScheduledMutator,
|
havoc_mutations, token_mutations::I2SRandReplace, tokens_mutations, HavocScheduledMutator,
|
||||||
StdMOptMutator, Tokens,
|
StdMOptMutator, Tokens,
|
||||||
@ -31,8 +28,6 @@ use libafl::{
|
|||||||
state::{HasCorpus, HasExecutions, HasSolutions, StdState},
|
state::{HasCorpus, HasExecutions, HasSolutions, StdState},
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
};
|
};
|
||||||
#[cfg(not(feature = "simplemgr"))]
|
|
||||||
use libafl_bolts::shmem::{StdShMem, StdShMemProvider};
|
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
ownedref::OwnedMutSlice,
|
ownedref::OwnedMutSlice,
|
||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
@ -57,14 +52,6 @@ use crate::{harness::Harness, options::FuzzerOptions};
|
|||||||
pub type ClientState =
|
pub type ClientState =
|
||||||
StdState<InMemoryOnDiskCorpus<BytesInput>, BytesInput, StdRand, OnDiskCorpus<BytesInput>>;
|
StdState<InMemoryOnDiskCorpus<BytesInput>, BytesInput, StdRand, OnDiskCorpus<BytesInput>>;
|
||||||
|
|
||||||
#[cfg(feature = "simplemgr")]
|
|
||||||
pub type ClientMgr<M> = SimpleEventManager<BytesInput, M, ClientState>;
|
|
||||||
#[cfg(not(feature = "simplemgr"))]
|
|
||||||
pub type ClientMgr<M> = MonitorTypedEventManager<
|
|
||||||
LlmpRestartingEventManager<(), BytesInput, ClientState, StdShMem, StdShMemProvider>,
|
|
||||||
M,
|
|
||||||
>;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The snapshot and iterations options interact as follows:
|
* The snapshot and iterations options interact as follows:
|
||||||
*
|
*
|
||||||
@ -87,17 +74,22 @@ pub type ClientMgr<M> = MonitorTypedEventManager<
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#[derive(TypedBuilder)]
|
#[derive(TypedBuilder)]
|
||||||
pub struct Instance<'a, M: Monitor> {
|
pub struct Instance<'a, EM> {
|
||||||
options: &'a FuzzerOptions,
|
options: &'a FuzzerOptions,
|
||||||
mgr: ClientMgr<M>,
|
mgr: EM,
|
||||||
client_description: ClientDescription,
|
client_description: ClientDescription,
|
||||||
#[builder(default)]
|
#[builder(default)]
|
||||||
extra_tokens: Vec<String>,
|
extra_tokens: Vec<String>,
|
||||||
#[builder(default=PhantomData)]
|
|
||||||
phantom: PhantomData<M>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Monitor> Instance<'_, M> {
|
impl<MTEM> Instance<'_, MTEM>
|
||||||
|
where
|
||||||
|
MTEM: EventFirer<BytesInput, ClientState>
|
||||||
|
+ EventRestarter<ClientState>
|
||||||
|
+ ProgressReporter<ClientState>
|
||||||
|
+ SendExiting
|
||||||
|
+ EventReceiver<BytesInput, ClientState>,
|
||||||
|
{
|
||||||
fn coverage_filter(&self, qemu: Qemu) -> Result<StdAddressFilter, Error> {
|
fn coverage_filter(&self, qemu: Qemu) -> Result<StdAddressFilter, Error> {
|
||||||
/* Conversion is required on 32-bit targets, but not on 64-bit ones */
|
/* Conversion is required on 32-bit targets, but not on 64-bit ones */
|
||||||
if let Some(includes) = &self.options.include {
|
if let Some(includes) = &self.options.include {
|
||||||
@ -438,10 +430,10 @@ impl<M: Monitor> Instance<'_, M> {
|
|||||||
stages: &mut ST,
|
stages: &mut ST,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
ST: StagesTuple<E, ClientMgr<M>, ClientState, Z>,
|
ST: StagesTuple<E, MTEM, ClientState, Z>,
|
||||||
RSM: Fn(&mut E, Qemu),
|
RSM: Fn(&mut E, Qemu),
|
||||||
Z: Fuzzer<E, ClientMgr<M>, BytesInput, ClientState, ST>
|
Z: Fuzzer<E, MTEM, BytesInput, ClientState, ST>
|
||||||
+ Evaluator<E, ClientMgr<M>, BytesInput, ClientState>,
|
+ Evaluator<E, MTEM, BytesInput, ClientState>,
|
||||||
{
|
{
|
||||||
if state.must_load_initial_inputs() {
|
if state.must_load_initial_inputs() {
|
||||||
let corpus_dirs = [self.options.input_dir()];
|
let corpus_dirs = [self.options.input_dir()];
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{InMemoryOnDiskCorpus, OnDiskCorpus},
|
corpus::{InMemoryOnDiskCorpus, OnDiskCorpus},
|
||||||
events::ClientDescription,
|
events::{
|
||||||
|
ClientDescription, EventFirer, EventReceiver, EventRestarter, ProgressReporter, SendExiting,
|
||||||
|
},
|
||||||
inputs::BytesInput,
|
inputs::BytesInput,
|
||||||
monitors::Monitor,
|
monitors::Monitor,
|
||||||
state::StdState,
|
state::StdState,
|
||||||
@ -8,11 +12,7 @@ use libafl::{
|
|||||||
};
|
};
|
||||||
use libafl_bolts::rands::StdRand;
|
use libafl_bolts::rands::StdRand;
|
||||||
|
|
||||||
use crate::{
|
use crate::{instance::Instance, options::FuzzerOptions};
|
||||||
instance::{ClientMgr, Instance},
|
|
||||||
options::FuzzerOptions,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[allow(clippy::module_name_repetitions)]
|
#[allow(clippy::module_name_repetitions)]
|
||||||
pub type ClientState =
|
pub type ClientState =
|
||||||
StdState<InMemoryOnDiskCorpus<BytesInput>, BytesInput, StdRand, OnDiskCorpus<BytesInput>>;
|
StdState<InMemoryOnDiskCorpus<BytesInput>, BytesInput, StdRand, OnDiskCorpus<BytesInput>>;
|
||||||
@ -26,12 +26,19 @@ impl Client<'_> {
|
|||||||
Client { options }
|
Client { options }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run<M: Monitor>(
|
pub fn run<EM>(
|
||||||
&self,
|
&self,
|
||||||
state: Option<ClientState>,
|
state: Option<ClientState>,
|
||||||
mgr: ClientMgr<M>,
|
mgr: EM,
|
||||||
client_description: ClientDescription,
|
client_description: ClientDescription,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error>
|
||||||
|
where
|
||||||
|
EM: EventFirer<BytesInput, ClientState>
|
||||||
|
+ EventRestarter<ClientState>
|
||||||
|
+ ProgressReporter<ClientState>
|
||||||
|
+ SendExiting
|
||||||
|
+ EventReceiver<BytesInput, ClientState>,
|
||||||
|
{
|
||||||
let instance = Instance::builder()
|
let instance = Instance::builder()
|
||||||
.options(self.options)
|
.options(self.options)
|
||||||
.mgr(mgr)
|
.mgr(mgr)
|
||||||
|
@ -7,7 +7,7 @@ use std::{
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use libafl::{
|
use libafl::{
|
||||||
events::{
|
events::{
|
||||||
ClientDescription, EventConfig, Launcher, LlmpEventManagerBuilder, MonitorTypedEventManager,
|
ClientDescription, EventConfig, Launcher, LlmpEventManagerBuilder, SimpleEventManager,
|
||||||
},
|
},
|
||||||
monitors::{tui::TuiMonitor, Monitor, MultiMonitor},
|
monitors::{tui::TuiMonitor, Monitor, MultiMonitor},
|
||||||
Error,
|
Error,
|
||||||
@ -83,7 +83,7 @@ impl Fuzzer {
|
|||||||
M: Monitor + Clone,
|
M: Monitor + Clone,
|
||||||
{
|
{
|
||||||
// The shared memory allocator
|
// The shared memory allocator
|
||||||
let mut shmem_provider = StdShMemProvider::new()?;
|
let shmem_provider = StdShMemProvider::new()?;
|
||||||
|
|
||||||
/* If we are running in verbose, don't provide a replacement stdout, otherwise, use /dev/null */
|
/* If we are running in verbose, don't provide a replacement stdout, otherwise, use /dev/null */
|
||||||
let stdout = if self.options.verbose {
|
let stdout = if self.options.verbose {
|
||||||
@ -95,45 +95,28 @@ impl Fuzzer {
|
|||||||
let client = Client::new(&self.options);
|
let client = Client::new(&self.options);
|
||||||
|
|
||||||
if self.options.rerun_input.is_some() {
|
if self.options.rerun_input.is_some() {
|
||||||
// If we want to rerun a single input but we use a restarting mgr, we'll have to create a fake restarting mgr that doesn't actually restart.
|
|
||||||
// It's not pretty but better than recompiling with simplemgr.
|
|
||||||
|
|
||||||
// Just a random number, let's hope it's free :)
|
|
||||||
let broker_port = 13120;
|
|
||||||
let _fake_broker = LlmpBroker::create_attach_to_tcp(
|
|
||||||
shmem_provider.clone(),
|
|
||||||
tuple_list!(),
|
|
||||||
broker_port,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// To rerun an input, instead of using a launcher, we create dummy parameters and run the client directly.
|
|
||||||
return client.run(
|
return client.run(
|
||||||
None,
|
None,
|
||||||
MonitorTypedEventManager::<_, M>::new(
|
SimpleEventManager::new(monitor.clone()),
|
||||||
LlmpEventManagerBuilder::builder().build_on_port(
|
|
||||||
shmem_provider.clone(),
|
|
||||||
broker_port,
|
|
||||||
EventConfig::AlwaysUnique,
|
|
||||||
Some(StateRestorer::new(
|
|
||||||
shmem_provider.new_shmem(0x1000).unwrap(),
|
|
||||||
)),
|
|
||||||
)?,
|
|
||||||
),
|
|
||||||
ClientDescription::new(0, 0, CoreId(0)),
|
ClientDescription::new(0, 0, CoreId(0)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "simplemgr")]
|
#[cfg(feature = "simplemgr")]
|
||||||
return client.run(None, SimpleEventManager::new(monitor), CoreId(0));
|
return client.run(
|
||||||
|
None,
|
||||||
|
SimpleEventManager::new(monitor.clone()),
|
||||||
|
ClientDescription::new(0, 0, CoreId(0)),
|
||||||
|
);
|
||||||
|
|
||||||
// Build and run a Launcher
|
// Build and run a Launcher
|
||||||
|
#[cfg(not(feature = "simplemgr"))]
|
||||||
match Launcher::builder()
|
match Launcher::builder()
|
||||||
.shmem_provider(shmem_provider)
|
.shmem_provider(shmem_provider)
|
||||||
.broker_port(self.options.port)
|
.broker_port(self.options.port)
|
||||||
.configuration(EventConfig::from_build_id())
|
.configuration(EventConfig::from_build_id())
|
||||||
.monitor(monitor)
|
.monitor(monitor)
|
||||||
.run_client(|s, m, c| client.run(s, MonitorTypedEventManager::<_, M>::new(m), c))
|
.run_client(|s, m, c| client.run(s, m, c))
|
||||||
.cores(&self.options.cores)
|
.cores(&self.options.cores)
|
||||||
.stdout_file(stdout)
|
.stdout_file(stdout)
|
||||||
.stderr_file(stdout)
|
.stderr_file(stdout)
|
||||||
|
@ -3,15 +3,14 @@ use std::{marker::PhantomData, process};
|
|||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
|
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
|
||||||
events::{
|
events::{
|
||||||
ClientDescription, EventRestarter, LlmpRestartingEventManager, MonitorTypedEventManager,
|
ClientDescription, EventFirer, EventReceiver, EventRestarter, LlmpRestartingEventManager,
|
||||||
NopEventManager,
|
NopEventManager, ProgressReporter, SendExiting,
|
||||||
},
|
},
|
||||||
executors::{Executor, ShadowExecutor},
|
executors::{Executor, ShadowExecutor},
|
||||||
feedback_and_fast, feedback_or, feedback_or_fast,
|
feedback_and_fast, feedback_or, feedback_or_fast,
|
||||||
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
||||||
fuzzer::{Evaluator, Fuzzer, StdFuzzer},
|
fuzzer::{Evaluator, Fuzzer, StdFuzzer},
|
||||||
inputs::BytesInput,
|
inputs::BytesInput,
|
||||||
monitors::Monitor,
|
|
||||||
mutators::{
|
mutators::{
|
||||||
havoc_mutations, tokens_mutations, HavocScheduledMutator, I2SRandReplace, StdMOptMutator,
|
havoc_mutations, tokens_mutations, HavocScheduledMutator, I2SRandReplace, StdMOptMutator,
|
||||||
Tokens,
|
Tokens,
|
||||||
@ -43,22 +42,22 @@ use crate::options::FuzzerOptions;
|
|||||||
pub type ClientState =
|
pub type ClientState =
|
||||||
StdState<InMemoryOnDiskCorpus<BytesInput>, BytesInput, StdRand, OnDiskCorpus<BytesInput>>;
|
StdState<InMemoryOnDiskCorpus<BytesInput>, BytesInput, StdRand, OnDiskCorpus<BytesInput>>;
|
||||||
|
|
||||||
pub type ClientMgr<M> = MonitorTypedEventManager<
|
|
||||||
LlmpRestartingEventManager<(), BytesInput, ClientState, StdShMem, StdShMemProvider>,
|
|
||||||
M,
|
|
||||||
>;
|
|
||||||
|
|
||||||
#[derive(TypedBuilder)]
|
#[derive(TypedBuilder)]
|
||||||
pub struct Instance<'a, M: Monitor> {
|
pub struct Instance<'a, EM> {
|
||||||
options: &'a FuzzerOptions,
|
options: &'a FuzzerOptions,
|
||||||
/// The harness. We create it before forking, then `take()` it inside the client.
|
/// The harness. We create it before forking, then `take()` it inside the client.
|
||||||
mgr: ClientMgr<M>,
|
mgr: EM,
|
||||||
client_description: ClientDescription,
|
client_description: ClientDescription,
|
||||||
#[builder(default=PhantomData)]
|
|
||||||
phantom: PhantomData<M>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Monitor> Instance<'_, M> {
|
impl<EM> Instance<'_, EM>
|
||||||
|
where
|
||||||
|
EM: EventFirer<BytesInput, ClientState>
|
||||||
|
+ EventRestarter<ClientState>
|
||||||
|
+ ProgressReporter<ClientState>
|
||||||
|
+ SendExiting
|
||||||
|
+ EventReceiver<BytesInput, ClientState>,
|
||||||
|
{
|
||||||
pub fn run(mut self, state: Option<ClientState>) -> Result<(), Error> {
|
pub fn run(mut self, state: Option<ClientState>) -> Result<(), Error> {
|
||||||
let parent_cpu_id = self
|
let parent_cpu_id = self
|
||||||
.options
|
.options
|
||||||
@ -229,9 +228,8 @@ impl<M: Monitor> Instance<'_, M> {
|
|||||||
stages: &mut ST,
|
stages: &mut ST,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
Z: Fuzzer<E, ClientMgr<M>, BytesInput, ClientState, ST>
|
Z: Fuzzer<E, EM, BytesInput, ClientState, ST> + Evaluator<E, EM, BytesInput, ClientState>,
|
||||||
+ Evaluator<E, ClientMgr<M>, BytesInput, ClientState>,
|
ST: StagesTuple<E, EM, ClientState, Z>,
|
||||||
ST: StagesTuple<E, ClientMgr<M>, ClientState, Z>,
|
|
||||||
{
|
{
|
||||||
let corpus_dirs = [self.options.input_dir()];
|
let corpus_dirs = [self.options.input_dir()];
|
||||||
|
|
||||||
|
@ -697,137 +697,6 @@ impl HasEventManagerId for NopEventManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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`.
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
pub struct MonitorTypedEventManager<EM, M> {
|
|
||||||
inner: EM,
|
|
||||||
phantom: PhantomData<M>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<EM, M> MonitorTypedEventManager<EM, M> {
|
|
||||||
/// Creates a new `EventManager` that wraps another manager, but captures a `monitor` type as well.
|
|
||||||
#[must_use]
|
|
||||||
pub fn new(inner: EM) -> Self {
|
|
||||||
MonitorTypedEventManager {
|
|
||||||
inner,
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<EM, I, M, S> EventFirer<I, S> for MonitorTypedEventManager<EM, M>
|
|
||||||
where
|
|
||||||
EM: EventFirer<I, S>,
|
|
||||||
{
|
|
||||||
fn should_send(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn fire(&mut self, state: &mut S, event: EventWithStats<I>) -> Result<(), Error> {
|
|
||||||
self.inner.fire(state, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn log(
|
|
||||||
&mut self,
|
|
||||||
state: &mut S,
|
|
||||||
severity_level: LogSeverity,
|
|
||||||
message: String,
|
|
||||||
) -> Result<(), Error>
|
|
||||||
where
|
|
||||||
S: HasExecutions,
|
|
||||||
{
|
|
||||||
self.inner.log(state, severity_level, message)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn configuration(&self) -> EventConfig {
|
|
||||||
self.inner.configuration()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<EM, M, S> EventRestarter<S> for MonitorTypedEventManager<EM, M>
|
|
||||||
where
|
|
||||||
EM: EventRestarter<S>,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn on_restart(&mut self, state: &mut S) -> Result<(), Error> {
|
|
||||||
self.inner.on_restart(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<EM, M> SendExiting for MonitorTypedEventManager<EM, M>
|
|
||||||
where
|
|
||||||
EM: SendExiting,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn send_exiting(&mut self) -> Result<(), Error> {
|
|
||||||
self.inner.send_exiting()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_shutdown(&mut self) -> Result<(), Error> {
|
|
||||||
self.inner.on_shutdown()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<EM, M> AwaitRestartSafe for MonitorTypedEventManager<EM, M>
|
|
||||||
where
|
|
||||||
EM: AwaitRestartSafe,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn await_restart_safe(&mut self) {
|
|
||||||
self.inner.await_restart_safe();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<EM, I, M, S> EventReceiver<I, S> for MonitorTypedEventManager<EM, M>
|
|
||||||
where
|
|
||||||
EM: EventReceiver<I, S>,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn try_receive(&mut self, state: &mut S) -> Result<Option<(EventWithStats<I>, bool)>, Error> {
|
|
||||||
self.inner.try_receive(state)
|
|
||||||
}
|
|
||||||
fn on_interesting(
|
|
||||||
&mut self,
|
|
||||||
_state: &mut S,
|
|
||||||
_event_vec: EventWithStats<I>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<EM, M, S> ProgressReporter<S> for MonitorTypedEventManager<EM, M>
|
|
||||||
where
|
|
||||||
EM: ProgressReporter<S>,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn maybe_report_progress(
|
|
||||||
&mut self,
|
|
||||||
state: &mut S,
|
|
||||||
monitor_timeout: Duration,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
self.inner.maybe_report_progress(state, monitor_timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn report_progress(&mut self, state: &mut S) -> Result<(), Error> {
|
|
||||||
self.inner.report_progress(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<EM, M> HasEventManagerId for MonitorTypedEventManager<EM, M>
|
|
||||||
where
|
|
||||||
EM: HasEventManagerId,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn mgr_id(&self) -> EventManagerId {
|
|
||||||
self.inner.mgr_id()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user