Make every Builder ::builder(), so BobTheBuilder::new() becomes BobThe::builder() (#2242)
* Make every builder ::builder() * Fix no_std * More * Fix clippy, stuff * More fun * Make NopShMem do something * Alloc * more fmt * Remove UB in tinyinst executor builder * Make builder order not matter for tinyinst * More better * fix * docs * fmt * more fmt * clippy * fix fixes * tiny thing * more betterg * more more * more builder * more builder * more nyx * undo breaking clippy * clip
This commit is contained in:
parent
b97a9a1398
commit
1fafaf6454
@ -9,7 +9,7 @@ use std::{env, net::SocketAddr, path::PathBuf, time::Duration};
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{InMemoryCorpus, OnDiskCorpus},
|
corpus::{InMemoryCorpus, OnDiskCorpus},
|
||||||
events::{launcher::Launcher, EventConfig, LlmpEventConverterBuilder},
|
events::{launcher::Launcher, llmp::LlmpEventConverter, EventConfig},
|
||||||
executors::{inprocess::InProcessExecutor, ExitKind},
|
executors::{inprocess::InProcessExecutor, ExitKind},
|
||||||
feedback_or,
|
feedback_or,
|
||||||
feedbacks::{CrashFeedback, MaxMapFeedback, NautilusChunksMetadata, NautilusFeedback},
|
feedbacks::{CrashFeedback, MaxMapFeedback, NautilusChunksMetadata, NautilusFeedback},
|
||||||
@ -120,7 +120,7 @@ pub extern "C" fn libafl_main() {
|
|||||||
let context = NautilusContext::from_file(15, "grammar.json");
|
let context = NautilusContext::from_file(15, "grammar.json");
|
||||||
|
|
||||||
let mut event_converter = opt.bytes_broker_port.map(|port| {
|
let mut event_converter = opt.bytes_broker_port.map(|port| {
|
||||||
LlmpEventConverterBuilder::new()
|
LlmpEventConverter::builder()
|
||||||
.build_on_port(
|
.build_on_port(
|
||||||
shmem_provider.clone(),
|
shmem_provider.clone(),
|
||||||
port,
|
port,
|
||||||
|
@ -19,7 +19,7 @@ use libafl_bolts::{
|
|||||||
shmem::{ShMemProvider, StdShMemProvider},
|
shmem::{ShMemProvider, StdShMemProvider},
|
||||||
tuples::tuple_list,
|
tuples::tuple_list,
|
||||||
};
|
};
|
||||||
use libafl_nyx::{executor::NyxExecutorBuilder, helper::NyxHelper, settings::NyxSettings};
|
use libafl_nyx::{executor::NyxExecutor, helper::NyxHelper, settings::NyxSettings};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory");
|
let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory");
|
||||||
@ -54,7 +54,7 @@ fn main() {
|
|||||||
let mut feedback = MaxMapFeedback::new(&observer);
|
let mut feedback = MaxMapFeedback::new(&observer);
|
||||||
let mut objective = CrashFeedback::new();
|
let mut objective = CrashFeedback::new();
|
||||||
let scheduler = RandScheduler::new();
|
let scheduler = RandScheduler::new();
|
||||||
let mut executor = NyxExecutorBuilder::new().build(helper, tuple_list!(observer));
|
let mut executor = NyxExecutor::builder().build(helper, tuple_list!(observer));
|
||||||
|
|
||||||
// If not restarting, create a State from scratch
|
// If not restarting, create a State from scratch
|
||||||
let mut state = state.unwrap_or_else(|| {
|
let mut state = state.unwrap_or_else(|| {
|
||||||
|
@ -14,7 +14,7 @@ use libafl::{
|
|||||||
Fuzzer, StdFuzzer,
|
Fuzzer, StdFuzzer,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{rands::StdRand, tuples::tuple_list};
|
use libafl_bolts::{rands::StdRand, tuples::tuple_list};
|
||||||
use libafl_nyx::{executor::NyxExecutorBuilder, helper::NyxHelper, settings::NyxSettings};
|
use libafl_nyx::{executor::NyxExecutor, helper::NyxHelper, settings::NyxSettings};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// nyx stuff
|
// nyx stuff
|
||||||
@ -44,7 +44,7 @@ fn main() {
|
|||||||
let monitor = TuiMonitor::new(ui);
|
let monitor = TuiMonitor::new(ui);
|
||||||
|
|
||||||
let mut mgr = SimpleEventManager::new(monitor);
|
let mut mgr = SimpleEventManager::new(monitor);
|
||||||
let mut executor = NyxExecutorBuilder::new().build(helper, tuple_list!(observer));
|
let mut executor = NyxExecutor::builder().build(helper, tuple_list!(observer));
|
||||||
let mutator = StdScheduledMutator::new(havoc_mutations());
|
let mutator = StdScheduledMutator::new(havoc_mutations());
|
||||||
let mut stages = tuple_list!(StdMutationalStage::new(mutator));
|
let mut stages = tuple_list!(StdMutationalStage::new(mutator));
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::path::PathBuf;
|
use std::{path::PathBuf, ptr::addr_of_mut, time::Duration};
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{CachedOnDiskCorpus, Corpus, OnDiskCorpus, Testcase},
|
corpus::{CachedOnDiskCorpus, Corpus, OnDiskCorpus, Testcase},
|
||||||
@ -20,7 +20,7 @@ use libafl_bolts::shmem::Win32ShMemProvider;
|
|||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
ownedref::OwnedMutPtr, rands::StdRand, shmem::ShMemProvider, tuples::tuple_list,
|
ownedref::OwnedMutPtr, rands::StdRand, shmem::ShMemProvider, tuples::tuple_list,
|
||||||
};
|
};
|
||||||
use libafl_tinyinst::executor::TinyInstExecutorBuilder;
|
use libafl_tinyinst::executor::TinyInstExecutor;
|
||||||
static mut COVERAGE: Vec<u64> = vec![];
|
static mut COVERAGE: Vec<u64> = vec![];
|
||||||
|
|
||||||
#[cfg(not(any(target_vendor = "apple", windows, target_os = "linux")))]
|
#[cfg(not(any(target_vendor = "apple", windows, target_os = "linux")))]
|
||||||
@ -37,7 +37,7 @@ fn main() {
|
|||||||
// use file to pass testcases
|
// use file to pass testcases
|
||||||
// let args = vec!["test.exe".to_string(), "-f".to_string(), "@@".to_string()];
|
// let args = vec!["test.exe".to_string(), "-f".to_string(), "@@".to_string()];
|
||||||
|
|
||||||
let coverage = unsafe { OwnedMutPtr::Ptr(core::ptr::addr_of_mut!(COVERAGE)) };
|
let coverage = unsafe { OwnedMutPtr::Ptr(addr_of_mut!(COVERAGE)) };
|
||||||
let observer = ListObserver::new("cov", coverage);
|
let observer = ListObserver::new("cov", coverage);
|
||||||
let mut feedback = ListFeedback::new(&observer);
|
let mut feedback = ListFeedback::new(&observer);
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -59,18 +59,19 @@ fn main() {
|
|||||||
let scheduler = RandScheduler::new();
|
let scheduler = RandScheduler::new();
|
||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
let monitor = SimpleMonitor::new(|x| println!("{}", x));
|
let monitor = SimpleMonitor::new(|x| println!("{x}"));
|
||||||
|
|
||||||
let mut mgr = SimpleEventManager::new(monitor);
|
let mut mgr = SimpleEventManager::new(monitor);
|
||||||
let mut executor = unsafe {
|
let mut executor = unsafe {
|
||||||
TinyInstExecutorBuilder::new()
|
TinyInstExecutor::builder()
|
||||||
.tinyinst_args(tinyinst_args)
|
.tinyinst_args(tinyinst_args)
|
||||||
.program_args(args)
|
.program_args(args)
|
||||||
.use_shmem()
|
.use_shmem()
|
||||||
.persistent("test.exe".to_string(), "fuzz".to_string(), 1, 10000)
|
.persistent("test.exe".to_string(), "fuzz".to_string(), 1, 10000)
|
||||||
.timeout(std::time::Duration::new(5, 0))
|
.timeout(Duration::new(5, 0))
|
||||||
.shmem_provider(&mut shmem_provider)
|
.shmem_provider(&mut shmem_provider)
|
||||||
.build(&mut COVERAGE, tuple_list!(observer))
|
.coverage_ptr(addr_of_mut!(COVERAGE))
|
||||||
|
.build(tuple_list!(observer))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
};
|
};
|
||||||
let mutator = StdScheduledMutator::new(havoc_mutations());
|
let mutator = StdScheduledMutator::new(havoc_mutations());
|
||||||
|
@ -19,11 +19,12 @@ use libafl_bolts::{
|
|||||||
};
|
};
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
llmp::{self, LlmpBroker, LlmpClient, LlmpClientDescription, Tag},
|
llmp::{self, LlmpBroker, LlmpClient, LlmpClientDescription, Tag},
|
||||||
shmem::ShMemProvider,
|
shmem::{NopShMemProvider, ShMemProvider},
|
||||||
ClientId,
|
ClientId,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use super::NopEventManager;
|
||||||
#[cfg(feature = "llmp_compression")]
|
#[cfg(feature = "llmp_compression")]
|
||||||
use crate::events::llmp::COMPRESS_THRESHOLD;
|
use crate::events::llmp::COMPRESS_THRESHOLD;
|
||||||
#[cfg(feature = "adaptive_serialization")]
|
#[cfg(feature = "adaptive_serialization")]
|
||||||
@ -38,9 +39,9 @@ use crate::{
|
|||||||
},
|
},
|
||||||
executors::{Executor, HasObservers},
|
executors::{Executor, HasObservers},
|
||||||
fuzzer::{EvaluatorObservers, ExecutionProcessor},
|
fuzzer::{EvaluatorObservers, ExecutionProcessor},
|
||||||
inputs::{Input, UsesInput},
|
inputs::{Input, NopInput, UsesInput},
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
state::{HasExecutions, HasLastReportTime, UsesState},
|
state::{HasExecutions, HasLastReportTime, NopState, UsesState},
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -230,6 +231,14 @@ where
|
|||||||
is_main: bool,
|
is_main: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl CentralizedEventManager<NopEventManager<NopState<NopInput>>, NopShMemProvider> {
|
||||||
|
/// Creates a builder for [`CentralizedEventManager`]
|
||||||
|
#[must_use]
|
||||||
|
pub fn builder() -> CentralizedEventManagerBuilder {
|
||||||
|
CentralizedEventManagerBuilder::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The builder or `CentralizedEventManager`
|
/// The builder or `CentralizedEventManager`
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CentralizedEventManagerBuilder {
|
pub struct CentralizedEventManagerBuilder {
|
||||||
|
@ -48,10 +48,8 @@ use libafl_bolts::{
|
|||||||
use typed_builder::TypedBuilder;
|
use typed_builder::TypedBuilder;
|
||||||
|
|
||||||
use super::hooks::EventManagerHooksTuple;
|
use super::hooks::EventManagerHooksTuple;
|
||||||
#[cfg(all(unix, feature = "std"))]
|
|
||||||
use crate::events::centralized::CentralizedEventManagerBuilder;
|
|
||||||
#[cfg(all(unix, feature = "std", feature = "fork"))]
|
#[cfg(all(unix, feature = "std", feature = "fork"))]
|
||||||
use crate::events::{CentralizedEventManager, CentralizedLlmpEventBroker};
|
use crate::events::centralized::{CentralizedEventManager, CentralizedLlmpEventBroker};
|
||||||
#[cfg(feature = "adaptive_serialization")]
|
#[cfg(feature = "adaptive_serialization")]
|
||||||
use crate::observers::TimeObserver;
|
use crate::observers::TimeObserver;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -698,7 +696,7 @@ where
|
|||||||
let builder = builder.time_ref(self.time_obs.handle());
|
let builder = builder.time_ref(self.time_obs.handle());
|
||||||
let (state, mgr) = builder.build().launch()?;
|
let (state, mgr) = builder.build().launch()?;
|
||||||
|
|
||||||
let mut centralized_builder = CentralizedEventManagerBuilder::new();
|
let mut centralized_builder = CentralizedEventManager::builder();
|
||||||
|
|
||||||
if index == 1 {
|
if index == 1 {
|
||||||
centralized_builder = centralized_builder.is_main(true);
|
centralized_builder = centralized_builder.is_main(true);
|
||||||
|
@ -18,7 +18,7 @@ use libafl_bolts::{
|
|||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
current_time,
|
current_time,
|
||||||
llmp::{LlmpClient, LlmpClientDescription},
|
llmp::{LlmpClient, LlmpClientDescription},
|
||||||
shmem::ShMemProvider,
|
shmem::{NopShMemProvider, ShMemProvider},
|
||||||
ClientId,
|
ClientId,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -44,9 +44,9 @@ use crate::{
|
|||||||
},
|
},
|
||||||
executors::{Executor, HasObservers},
|
executors::{Executor, HasObservers},
|
||||||
fuzzer::{EvaluatorObservers, ExecutionProcessor},
|
fuzzer::{EvaluatorObservers, ExecutionProcessor},
|
||||||
inputs::UsesInput,
|
inputs::{NopInput, UsesInput},
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
state::{HasExecutions, HasLastReportTime, State, UsesState},
|
state::{HasExecutions, HasLastReportTime, NopState, State, UsesState},
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -85,6 +85,14 @@ where
|
|||||||
phantom: PhantomData<S>,
|
phantom: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl LlmpEventManager<(), NopState<NopInput>, NopShMemProvider> {
|
||||||
|
/// Creates a builder for [`LlmpEventManager`]
|
||||||
|
#[must_use]
|
||||||
|
pub fn builder() -> LlmpEventManagerBuilder<()> {
|
||||||
|
LlmpEventManagerBuilder::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Builder for `LlmpEventManager`
|
/// Builder for `LlmpEventManager`
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct LlmpEventManagerBuilder<EMH> {
|
pub struct LlmpEventManagerBuilder<EMH> {
|
||||||
|
@ -10,7 +10,7 @@ use libafl_bolts::{
|
|||||||
};
|
};
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
llmp::{LlmpClient, LlmpClientDescription, Tag},
|
llmp::{LlmpClient, LlmpClientDescription, Tag},
|
||||||
shmem::ShMemProvider,
|
shmem::{NopShMemProvider, ShMemProvider},
|
||||||
ClientId,
|
ClientId,
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
@ -19,8 +19,8 @@ use crate::{
|
|||||||
events::{CustomBufEventResult, CustomBufHandlerFn, Event, EventFirer},
|
events::{CustomBufEventResult, CustomBufHandlerFn, Event, EventFirer},
|
||||||
executors::{Executor, HasObservers},
|
executors::{Executor, HasObservers},
|
||||||
fuzzer::{EvaluatorObservers, ExecutionProcessor},
|
fuzzer::{EvaluatorObservers, ExecutionProcessor},
|
||||||
inputs::{Input, InputConverter, UsesInput},
|
inputs::{Input, InputConverter, NopInput, NopInputConverter, UsesInput},
|
||||||
state::{HasExecutions, State, UsesState},
|
state::{HasExecutions, NopState, State, UsesState},
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -108,6 +108,22 @@ where
|
|||||||
phantom: PhantomData<S>,
|
phantom: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl
|
||||||
|
LlmpEventConverter<
|
||||||
|
NopInput,
|
||||||
|
NopInputConverter<NopInput>,
|
||||||
|
NopInputConverter<NopInput>,
|
||||||
|
NopState<NopInput>,
|
||||||
|
NopShMemProvider,
|
||||||
|
>
|
||||||
|
{
|
||||||
|
/// Create a builder for [`LlmpEventConverter`]
|
||||||
|
#[must_use]
|
||||||
|
pub fn builder() -> LlmpEventConverterBuilder {
|
||||||
|
LlmpEventConverterBuilder::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Build `LlmpEventConverter`
|
/// Build `LlmpEventConverter`
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct LlmpEventConverterBuilder {
|
pub struct LlmpEventConverterBuilder {
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
//! Llmp restarting manager
|
//! The `LLMP` restarting manager will
|
||||||
|
//! forward messages over lockless shared maps.
|
||||||
|
//! When the target crashes, a watch process (the parent) will
|
||||||
|
//! restart/refork it.
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
#[cfg(all(unix, not(miri), feature = "std"))]
|
#[cfg(all(unix, not(miri), feature = "std"))]
|
||||||
@ -42,7 +45,7 @@ use crate::{
|
|||||||
events::{
|
events::{
|
||||||
hooks::EventManagerHooksTuple, Event, EventConfig, EventFirer, EventManager,
|
hooks::EventManagerHooksTuple, Event, EventConfig, EventFirer, EventManager,
|
||||||
EventManagerId, EventProcessor, EventRestarter, HasEventManagerId, LlmpEventBroker,
|
EventManagerId, EventProcessor, EventRestarter, HasEventManagerId, LlmpEventBroker,
|
||||||
LlmpEventManager, LlmpEventManagerBuilder, LlmpShouldSaveState, ProgressReporter,
|
LlmpEventManager, LlmpShouldSaveState, ProgressReporter,
|
||||||
},
|
},
|
||||||
executors::{Executor, HasObservers},
|
executors::{Executor, HasObservers},
|
||||||
fuzzer::{EvaluatorObservers, ExecutionProcessor},
|
fuzzer::{EvaluatorObservers, ExecutionProcessor},
|
||||||
@ -483,11 +486,11 @@ where
|
|||||||
}
|
}
|
||||||
LlmpConnection::IsClient { client } => {
|
LlmpConnection::IsClient { client } => {
|
||||||
#[cfg(not(feature = "adaptive_serialization"))]
|
#[cfg(not(feature = "adaptive_serialization"))]
|
||||||
let mgr: LlmpEventManager<EMH, S, SP> = LlmpEventManagerBuilder::new()
|
let mgr: LlmpEventManager<EMH, S, SP> = LlmpEventManager::builder()
|
||||||
.hooks(self.hooks)
|
.hooks(self.hooks)
|
||||||
.build_from_client(client, self.configuration)?;
|
.build_from_client(client, self.configuration)?;
|
||||||
#[cfg(feature = "adaptive_serialization")]
|
#[cfg(feature = "adaptive_serialization")]
|
||||||
let mgr: LlmpEventManager<EMH, S, SP> = LlmpEventManagerBuilder::new()
|
let mgr: LlmpEventManager<EMH, S, SP> = LlmpEventManager::builder()
|
||||||
.hooks(self.hooks)
|
.hooks(self.hooks)
|
||||||
.build_from_client(
|
.build_from_client(
|
||||||
client,
|
client,
|
||||||
@ -511,7 +514,7 @@ where
|
|||||||
ManagerKind::Client { cpu_core } => {
|
ManagerKind::Client { cpu_core } => {
|
||||||
// We are a client
|
// We are a client
|
||||||
#[cfg(not(feature = "adaptive_serialization"))]
|
#[cfg(not(feature = "adaptive_serialization"))]
|
||||||
let mgr = LlmpEventManagerBuilder::new()
|
let mgr = LlmpEventManager::builder()
|
||||||
.hooks(self.hooks)
|
.hooks(self.hooks)
|
||||||
.build_on_port(
|
.build_on_port(
|
||||||
self.shmem_provider.clone(),
|
self.shmem_provider.clone(),
|
||||||
@ -519,7 +522,7 @@ where
|
|||||||
self.configuration,
|
self.configuration,
|
||||||
)?;
|
)?;
|
||||||
#[cfg(feature = "adaptive_serialization")]
|
#[cfg(feature = "adaptive_serialization")]
|
||||||
let mgr = LlmpEventManagerBuilder::new()
|
let mgr = LlmpEventManager::builder()
|
||||||
.hooks(self.hooks)
|
.hooks(self.hooks)
|
||||||
.build_on_port(
|
.build_on_port(
|
||||||
self.shmem_provider.clone(),
|
self.shmem_provider.clone(),
|
||||||
@ -648,7 +651,7 @@ where
|
|||||||
let (state, mut mgr) =
|
let (state, mut mgr) =
|
||||||
if let Some((state_opt, mgr_description)) = staterestorer.restore()? {
|
if let Some((state_opt, mgr_description)) = staterestorer.restore()? {
|
||||||
#[cfg(not(feature = "adaptive_serialization"))]
|
#[cfg(not(feature = "adaptive_serialization"))]
|
||||||
let llmp_mgr = LlmpEventManagerBuilder::new()
|
let llmp_mgr = LlmpEventManager::builder()
|
||||||
.hooks(self.hooks)
|
.hooks(self.hooks)
|
||||||
.build_existing_client_from_description(
|
.build_existing_client_from_description(
|
||||||
new_shmem_provider,
|
new_shmem_provider,
|
||||||
@ -656,7 +659,7 @@ where
|
|||||||
self.configuration,
|
self.configuration,
|
||||||
)?;
|
)?;
|
||||||
#[cfg(feature = "adaptive_serialization")]
|
#[cfg(feature = "adaptive_serialization")]
|
||||||
let llmp_mgr = LlmpEventManagerBuilder::new()
|
let llmp_mgr = LlmpEventManager::builder()
|
||||||
.hooks(self.hooks)
|
.hooks(self.hooks)
|
||||||
.build_existing_client_from_description(
|
.build_existing_client_from_description(
|
||||||
new_shmem_provider,
|
new_shmem_provider,
|
||||||
@ -676,7 +679,7 @@ where
|
|||||||
log::info!("First run. Let's set it all up");
|
log::info!("First run. Let's set it all up");
|
||||||
// Mgr to send and receive msgs from/to all other fuzzer instances
|
// Mgr to send and receive msgs from/to all other fuzzer instances
|
||||||
#[cfg(not(feature = "adaptive_serialization"))]
|
#[cfg(not(feature = "adaptive_serialization"))]
|
||||||
let mgr = LlmpEventManagerBuilder::new()
|
let mgr = LlmpEventManager::builder()
|
||||||
.hooks(self.hooks)
|
.hooks(self.hooks)
|
||||||
.build_existing_client_from_env(
|
.build_existing_client_from_env(
|
||||||
new_shmem_provider,
|
new_shmem_provider,
|
||||||
@ -684,7 +687,7 @@ where
|
|||||||
self.configuration,
|
self.configuration,
|
||||||
)?;
|
)?;
|
||||||
#[cfg(feature = "adaptive_serialization")]
|
#[cfg(feature = "adaptive_serialization")]
|
||||||
let mgr = LlmpEventManagerBuilder::new()
|
let mgr = LlmpEventManager::builder()
|
||||||
.hooks(self.hooks)
|
.hooks(self.hooks)
|
||||||
.build_existing_client_from_env(
|
.build_existing_client_from_env(
|
||||||
new_shmem_provider,
|
new_shmem_provider,
|
||||||
@ -738,7 +741,7 @@ mod tests {
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
corpus::{Corpus, InMemoryCorpus, Testcase},
|
corpus::{Corpus, InMemoryCorpus, Testcase},
|
||||||
events::llmp::{restarting::_ENV_FUZZER_SENDER, LlmpEventManagerBuilder},
|
events::llmp::{restarting::_ENV_FUZZER_SENDER, LlmpEventManager},
|
||||||
executors::{ExitKind, InProcessExecutor},
|
executors::{ExitKind, InProcessExecutor},
|
||||||
feedbacks::ConstFeedback,
|
feedbacks::ConstFeedback,
|
||||||
fuzzer::Fuzzer,
|
fuzzer::Fuzzer,
|
||||||
@ -788,11 +791,11 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "adaptive_serialization"))]
|
#[cfg(not(feature = "adaptive_serialization"))]
|
||||||
let mut llmp_mgr = LlmpEventManagerBuilder::new()
|
let mut llmp_mgr = LlmpEventManager::builder()
|
||||||
.build_from_client(llmp_client, "fuzzer".into())
|
.build_from_client(llmp_client, "fuzzer".into())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
#[cfg(feature = "adaptive_serialization")]
|
#[cfg(feature = "adaptive_serialization")]
|
||||||
let mut llmp_mgr = LlmpEventManagerBuilder::new()
|
let mut llmp_mgr = LlmpEventManager::builder()
|
||||||
.build_from_client(llmp_client, "fuzzer".into(), time_ref.clone())
|
.build_from_client(llmp_client, "fuzzer".into(), time_ref.clone())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -837,7 +840,7 @@ mod tests {
|
|||||||
|
|
||||||
let (mut state_clone, mgr_description) = staterestorer.restore().unwrap().unwrap();
|
let (mut state_clone, mgr_description) = staterestorer.restore().unwrap().unwrap();
|
||||||
#[cfg(not(feature = "adaptive_serialization"))]
|
#[cfg(not(feature = "adaptive_serialization"))]
|
||||||
let mut llmp_clone = LlmpEventManagerBuilder::new()
|
let mut llmp_clone = LlmpEventManager::builder()
|
||||||
.build_existing_client_from_description(
|
.build_existing_client_from_description(
|
||||||
shmem_provider,
|
shmem_provider,
|
||||||
&mgr_description,
|
&mgr_description,
|
||||||
@ -845,7 +848,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
#[cfg(feature = "adaptive_serialization")]
|
#[cfg(feature = "adaptive_serialization")]
|
||||||
let mut llmp_clone = LlmpEventManagerBuilder::new()
|
let mut llmp_clone = LlmpEventManager::builder()
|
||||||
.build_existing_client_from_description(
|
.build_existing_client_from_description(
|
||||||
shmem_provider,
|
shmem_provider,
|
||||||
&mgr_description,
|
&mgr_description,
|
||||||
|
@ -440,6 +440,17 @@ where
|
|||||||
phantom: PhantomData<S>,
|
phantom: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S> TcpEventManager<(), S>
|
||||||
|
where
|
||||||
|
S: State,
|
||||||
|
{
|
||||||
|
/// Create a builder for [`TcpEventManager`]
|
||||||
|
#[must_use]
|
||||||
|
pub fn builder() -> TcpEventManagerBuilder<(), S> {
|
||||||
|
TcpEventManagerBuilder::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Builder for `TcpEventManager`
|
/// Builder for `TcpEventManager`
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct TcpEventManagerBuilder<EMH, S> {
|
pub struct TcpEventManagerBuilder<EMH, S> {
|
||||||
|
@ -182,8 +182,7 @@ impl CommandExecutor<(), (), ()> {
|
|||||||
/// By default, input is read from stdin, unless you specify a different location using
|
/// By default, input is read from stdin, unless you specify a different location using
|
||||||
/// * `arg_input_arg` for input delivered _as_ an command line argument
|
/// * `arg_input_arg` for input delivered _as_ an command line argument
|
||||||
/// * `arg_input_file` for input via a file of a specific name
|
/// * `arg_input_file` for input via a file of a specific name
|
||||||
/// * `arg_input_file_std` for a file with default name
|
/// * `arg_input_file_std` for a file with default name (at the right location in the arguments)
|
||||||
/// (at the right location in the arguments)
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn builder() -> CommandExecutorBuilder {
|
pub fn builder() -> CommandExecutorBuilder {
|
||||||
CommandExecutorBuilder::new()
|
CommandExecutorBuilder::new()
|
||||||
|
@ -1324,7 +1324,7 @@ mod tests {
|
|||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
executors::forkserver::ForkserverExecutorBuilder,
|
executors::forkserver::ForkserverExecutor,
|
||||||
observers::{ConstMapObserver, HitcountsMapObserver},
|
observers::{ConstMapObserver, HitcountsMapObserver},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
@ -1348,7 +1348,7 @@ mod tests {
|
|||||||
shmem_buf,
|
shmem_buf,
|
||||||
));
|
));
|
||||||
|
|
||||||
let executor = ForkserverExecutorBuilder::new()
|
let executor = ForkserverExecutor::builder()
|
||||||
.program(bin)
|
.program(bin)
|
||||||
.args(args)
|
.args(args)
|
||||||
.debug_child(false)
|
.debug_child(false)
|
||||||
|
@ -219,6 +219,7 @@ where
|
|||||||
/// * `user_hooks` - the hooks run before and after the harness's execution
|
/// * `user_hooks` - the hooks run before and after the harness's execution
|
||||||
/// * `harness_fn` - the harness, executing the function
|
/// * `harness_fn` - the harness, executing the function
|
||||||
/// * `observers` - the observers observing the target during execution
|
/// * `observers` - the observers observing the target during execution
|
||||||
|
///
|
||||||
/// This may return an error on unix, if signal handler setup fails
|
/// This may return an error on unix, if signal handler setup fails
|
||||||
pub fn with_timeout_generic<E, EM, OF, Z>(
|
pub fn with_timeout_generic<E, EM, OF, Z>(
|
||||||
user_hooks: HT,
|
user_hooks: HT,
|
||||||
|
@ -232,6 +232,7 @@ where
|
|||||||
/// * `user_hooks` - the hooks run before and after the harness's execution
|
/// * `user_hooks` - the hooks run before and after the harness's execution
|
||||||
/// * `harness_fn` - the harness, executing the function
|
/// * `harness_fn` - the harness, executing the function
|
||||||
/// * `observers` - the observers observing the target during execution
|
/// * `observers` - the observers observing the target during execution
|
||||||
|
///
|
||||||
/// This may return an error on unix, if signal handler setup fails
|
/// This may return an error on unix, if signal handler setup fails
|
||||||
pub fn with_timeout<EM, OF, Z>(
|
pub fn with_timeout<EM, OF, Z>(
|
||||||
harness_fn: &'a mut H,
|
harness_fn: &'a mut H,
|
||||||
@ -329,12 +330,13 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new in mem executor.
|
/// Create a new [`InProcessExecutor`].
|
||||||
/// Caution: crash and restart in one of them will lead to odd behavior if multiple are used,
|
/// Caution: crash and restart in one of them will lead to odd behavior if multiple are used,
|
||||||
/// depending on different corpus or state.
|
/// depending on different corpus or state.
|
||||||
/// * `user_hooks` - the hooks run before and after the harness's execution
|
/// * `user_hooks` - the hooks run before and after the harness's execution
|
||||||
/// * `harness_fn` - the harness, executing the function
|
/// * `harness_fn` - the harness, executing the function
|
||||||
/// * `observers` - the observers observing the target during execution
|
/// * `observers` - the observers observing the target during execution
|
||||||
|
///
|
||||||
/// This may return an error on unix, if signal handler setup fails
|
/// This may return an error on unix, if signal handler setup fails
|
||||||
pub fn with_timeout_generic<EM, OF, Z>(
|
pub fn with_timeout_generic<EM, OF, Z>(
|
||||||
user_hooks: HT,
|
user_hooks: HT,
|
||||||
|
@ -227,6 +227,7 @@ where
|
|||||||
/// * `user_hooks` - the hooks run before and after the harness's execution
|
/// * `user_hooks` - the hooks run before and after the harness's execution
|
||||||
/// * `harness_fn` - the harness, executing the function
|
/// * `harness_fn` - the harness, executing the function
|
||||||
/// * `observers` - the observers observing the target during execution
|
/// * `observers` - the observers observing the target during execution
|
||||||
|
///
|
||||||
/// This may return an error on unix, if signal handler setup fails
|
/// This may return an error on unix, if signal handler setup fails
|
||||||
pub fn with_timeout<EM, OF, Z>(
|
pub fn with_timeout<EM, OF, Z>(
|
||||||
harness_fn: &'a mut H,
|
harness_fn: &'a mut H,
|
||||||
@ -354,6 +355,7 @@ where
|
|||||||
/// * `user_hooks` - the hooks run before and after the harness's execution
|
/// * `user_hooks` - the hooks run before and after the harness's execution
|
||||||
/// * `harness_fn` - the harness, executing the function
|
/// * `harness_fn` - the harness, executing the function
|
||||||
/// * `observers` - the observers observing the target during execution
|
/// * `observers` - the observers observing the target during execution
|
||||||
|
///
|
||||||
/// This may return an error on unix, if signal handler setup fails
|
/// This may return an error on unix, if signal handler setup fails
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn with_timeout_generic<EM, OF, Z>(
|
pub fn with_timeout_generic<EM, OF, Z>(
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
//! # Concolic Tracing Serialization Format
|
//! # Concolic Tracing Serialization Format
|
||||||
|
//!
|
||||||
//! ## Design Goals
|
//! ## Design Goals
|
||||||
//! * The serialization format for concolic tracing was developed with the goal of being space and time efficient.
|
//! * The serialization format for concolic tracing was developed with the goal of being space and time efficient.
|
||||||
//! * Additionally, it should be easy to maintain and extend.
|
//! * Additionally, it should be easy to maintain and extend.
|
||||||
|
@ -22,8 +22,7 @@ static BUILD_ID: OnceLock<Uuid> = OnceLock::new();
|
|||||||
/// invocations of identically laid out binaries.
|
/// invocations of identically laid out binaries.
|
||||||
///
|
///
|
||||||
/// As such:
|
/// As such:
|
||||||
/// * It is guaranteed to be identical within multiple invocations of the same
|
/// * It is guaranteed to be identical within multiple invocations of the same binary.
|
||||||
/// binary.
|
|
||||||
/// * It is guaranteed to be different across binaries with different code or
|
/// * It is guaranteed to be different across binaries with different code or
|
||||||
/// data segments or layout.
|
/// data segments or layout.
|
||||||
/// * Equality is unspecified if the binaries have identical code and data
|
/// * Equality is unspecified if the binaries have identical code and data
|
||||||
|
@ -2,11 +2,9 @@
|
|||||||
//! too.)
|
//! too.)
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
use alloc::{rc::Rc, string::ToString};
|
use alloc::{rc::Rc, string::ToString, vec::Vec};
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
use core::fmt::Display;
|
use core::{cell::RefCell, fmt, fmt::Display, mem::ManuallyDrop};
|
||||||
#[cfg(feature = "alloc")]
|
|
||||||
use core::{cell::RefCell, fmt, mem::ManuallyDrop};
|
|
||||||
use core::{
|
use core::{
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
mem,
|
mem,
|
||||||
@ -318,6 +316,72 @@ pub trait ShMemProvider: Clone + Default + Debug {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An [`ShMemProvider`] that does not provide any [`ShMem`].
|
||||||
|
/// This is mainly for testing and type magic.
|
||||||
|
/// The resulting [`NopShMem`] is backed by a simple byte buffer to do some simple non-shared things with.
|
||||||
|
/// Calling [`NopShMemProvider::shmem_from_id_and_size`] will return new maps for the same id every time.
|
||||||
|
///
|
||||||
|
/// # Note
|
||||||
|
/// If you just want a simple shared memory implementation, use [`StdShMemProvider`] instead.
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
#[derive(Debug, Clone, Default)]
|
||||||
|
pub struct NopShMemProvider;
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
impl ShMemProvider for NopShMemProvider {
|
||||||
|
type ShMem = NopShMem;
|
||||||
|
|
||||||
|
fn new() -> Result<Self, Error> {
|
||||||
|
Ok(Self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_shmem(&mut self, map_size: usize) -> Result<Self::ShMem, Error> {
|
||||||
|
self.shmem_from_id_and_size(ShMemId::default(), map_size)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn shmem_from_id_and_size(
|
||||||
|
&mut self,
|
||||||
|
id: ShMemId,
|
||||||
|
map_size: usize,
|
||||||
|
) -> Result<Self::ShMem, Error> {
|
||||||
|
Ok(NopShMem {
|
||||||
|
id,
|
||||||
|
buf: vec![0; map_size],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An [`ShMem]`] that does not have any mem nor share anything.
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
#[derive(Debug, Clone, Default)]
|
||||||
|
pub struct NopShMem {
|
||||||
|
id: ShMemId,
|
||||||
|
buf: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
impl ShMem for NopShMem {
|
||||||
|
fn id(&self) -> ShMemId {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
impl DerefMut for NopShMem {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.buf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
impl Deref for NopShMem {
|
||||||
|
type Target = [u8];
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.buf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A Handle Counted shared map,
|
/// A Handle Counted shared map,
|
||||||
/// that can use internal mutability.
|
/// that can use internal mutability.
|
||||||
/// Useful if the `ShMemProvider` needs to keep local state.
|
/// Useful if the `ShMemProvider` needs to keep local state.
|
||||||
|
@ -189,7 +189,7 @@ impl FridaInstrumentationHelperBuilder {
|
|||||||
/// Instrument all modules in `/usr/lib` as well as `libfoo.so`:
|
/// Instrument all modules in `/usr/lib` as well as `libfoo.so`:
|
||||||
/// ```
|
/// ```
|
||||||
///# use libafl_frida::helper::FridaInstrumentationHelperBuilder;
|
///# use libafl_frida::helper::FridaInstrumentationHelperBuilder;
|
||||||
/// let builder = FridaInstrumentationHelperBuilder::new()
|
/// let builder = FridaInstrumentationHelper::builder()
|
||||||
/// .instrument_module_if(|module| module.name() == "libfoo.so")
|
/// .instrument_module_if(|module| module.name() == "libfoo.so")
|
||||||
/// .instrument_module_if(|module| module.path().starts_with("/usr/lib"));
|
/// .instrument_module_if(|module| module.path().starts_with("/usr/lib"));
|
||||||
/// ```
|
/// ```
|
||||||
@ -218,7 +218,7 @@ impl FridaInstrumentationHelperBuilder {
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
///# use libafl_frida::helper::FridaInstrumentationHelperBuilder;
|
///# use libafl_frida::helper::FridaInstrumentationHelperBuilder;
|
||||||
/// let builder = FridaInstrumentationHelperBuilder::new()
|
/// let builder = FridaInstrumentationHelper::builder()
|
||||||
/// .instrument_module_if(|module| module.path().starts_with("/usr/lib"))
|
/// .instrument_module_if(|module| module.path().starts_with("/usr/lib"))
|
||||||
/// .skip_module_if(|module| module.name() == "libfoo.so");
|
/// .skip_module_if(|module| module.name() == "libfoo.so");
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -236,6 +236,7 @@ pub fn merge(
|
|||||||
.scheduler_mut()
|
.scheduler_mut()
|
||||||
.on_remove(&mut state, idx, &Some(testcase))?;
|
.on_remove(&mut state, idx, &Some(testcase))?;
|
||||||
} else {
|
} else {
|
||||||
|
#[allow(clippy::needless_borrows_for_generic_args)] // False-positive: file_path is used just below
|
||||||
rename(&file_path, &new_file_path)?;
|
rename(&file_path, &new_file_path)?;
|
||||||
*file_path = new_file_path;
|
*file_path = new_file_path;
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,13 @@ pub struct NyxExecutor<S, OT> {
|
|||||||
phantom: PhantomData<S>,
|
phantom: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl NyxExecutor<(), ()> {
|
||||||
|
/// Create a builder for [`NyxExeuctor`]
|
||||||
|
pub fn builder() -> NyxExecutorBuilder {
|
||||||
|
NyxExecutorBuilder::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<S, OT> UsesState for NyxExecutor<S, OT>
|
impl<S, OT> UsesState for NyxExecutor<S, OT>
|
||||||
where
|
where
|
||||||
S: State,
|
S: State,
|
||||||
|
@ -5,7 +5,7 @@ use std::{fs, net::SocketAddr, path::PathBuf, time::Duration};
|
|||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{CachedOnDiskCorpus, Corpus, OnDiskCorpus},
|
corpus::{CachedOnDiskCorpus, Corpus, OnDiskCorpus},
|
||||||
events::{launcher::Launcher, EventConfig, EventRestarter, LlmpRestartingEventManager},
|
events::{launcher::Launcher, EventConfig, EventRestarter, LlmpRestartingEventManager},
|
||||||
executors::forkserver::ForkserverExecutorBuilder,
|
executors::forkserver::ForkserverExecutor,
|
||||||
feedback_or, feedback_or_fast,
|
feedback_or, feedback_or_fast,
|
||||||
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
||||||
fuzzer::{Fuzzer, StdFuzzer},
|
fuzzer::{Fuzzer, StdFuzzer},
|
||||||
@ -175,7 +175,7 @@ impl<'a> ForkserverBytesCoverageSugar<'a> {
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
let forkserver = if self.shmem_testcase {
|
let forkserver = if self.shmem_testcase {
|
||||||
ForkserverExecutorBuilder::new()
|
ForkserverExecutor::builder()
|
||||||
.program(self.program.clone())
|
.program(self.program.clone())
|
||||||
.parse_afl_cmdline(self.arguments)
|
.parse_afl_cmdline(self.arguments)
|
||||||
.is_persistent(true)
|
.is_persistent(true)
|
||||||
@ -186,7 +186,7 @@ impl<'a> ForkserverBytesCoverageSugar<'a> {
|
|||||||
.shmem_provider(&mut shmem_provider_client)
|
.shmem_provider(&mut shmem_provider_client)
|
||||||
.build_dynamic_map(edges_observer, tuple_list!(time_observer))
|
.build_dynamic_map(edges_observer, tuple_list!(time_observer))
|
||||||
} else {
|
} else {
|
||||||
ForkserverExecutorBuilder::new()
|
ForkserverExecutor::builder()
|
||||||
.program(self.program.clone())
|
.program(self.program.clone())
|
||||||
.parse_afl_cmdline(self.arguments)
|
.parse_afl_cmdline(self.arguments)
|
||||||
.is_persistent(true)
|
.is_persistent(true)
|
||||||
|
@ -200,6 +200,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "forkserver", feature = "windows_asan"))]
|
||||||
let target_family = std::env::var("CARGO_CFG_TARGET_FAMILY").unwrap();
|
let target_family = std::env::var("CARGO_CFG_TARGET_FAMILY").unwrap();
|
||||||
|
|
||||||
#[cfg(feature = "forkserver")]
|
#[cfg(feature = "forkserver")]
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use core::marker::PhantomData;
|
use core::{marker::PhantomData, ptr, time::Duration};
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
executors::{Executor, ExitKind, HasObservers},
|
executors::{Executor, ExitKind, HasObservers},
|
||||||
@ -10,19 +9,19 @@ use libafl::{
|
|||||||
};
|
};
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
fs::{InputFile, INPUTFILE_STD},
|
fs::{InputFile, INPUTFILE_STD},
|
||||||
shmem::{ShMem, ShMemProvider, StdShMemProvider},
|
shmem::{NopShMemProvider, ShMem, ShMemProvider},
|
||||||
tuples::RefIndexable,
|
tuples::RefIndexable,
|
||||||
AsSlice, AsSliceMut,
|
AsSlice, AsSliceMut,
|
||||||
};
|
};
|
||||||
use tinyinst::tinyinst::{litecov::RunResult, TinyInst};
|
use tinyinst::tinyinst::{litecov::RunResult, TinyInst};
|
||||||
|
|
||||||
/// Tinyinst executor
|
/// [`TinyInst`](https://github.com/googleprojectzero/TinyInst) executor
|
||||||
pub struct TinyInstExecutor<'a, S, SP, OT>
|
pub struct TinyInstExecutor<S, SP, OT>
|
||||||
where
|
where
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
tinyinst: TinyInst,
|
tinyinst: TinyInst,
|
||||||
coverage: &'a mut Vec<u64>,
|
coverage_ptr: *mut Vec<u64>,
|
||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
observers: OT,
|
observers: OT,
|
||||||
phantom: PhantomData<S>,
|
phantom: PhantomData<S>,
|
||||||
@ -30,7 +29,15 @@ where
|
|||||||
map: Option<<SP as ShMemProvider>::ShMem>,
|
map: Option<<SP as ShMemProvider>::ShMem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S, SP, OT> std::fmt::Debug for TinyInstExecutor<'a, S, SP, OT>
|
impl<'a> TinyInstExecutor<(), NopShMemProvider, ()> {
|
||||||
|
/// Create a builder for [`TinyInstExecutor`]
|
||||||
|
#[must_use]
|
||||||
|
pub fn builder() -> TinyInstExecutorBuilder<'a, NopShMemProvider> {
|
||||||
|
TinyInstExecutorBuilder::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, SP, OT> std::fmt::Debug for TinyInstExecutor<S, SP, OT>
|
||||||
where
|
where
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
@ -41,7 +48,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, EM, S, SP, OT, Z> Executor<EM, Z> for TinyInstExecutor<'a, S, SP, OT>
|
impl<EM, S, SP, OT, Z> Executor<EM, Z> for TinyInstExecutor<S, SP, OT>
|
||||||
where
|
where
|
||||||
EM: UsesState<State = S>,
|
EM: UsesState<State = S>,
|
||||||
S: State + HasExecutions,
|
S: State + HasExecutions,
|
||||||
@ -80,7 +87,8 @@ where
|
|||||||
let mut status = RunResult::OK;
|
let mut status = RunResult::OK;
|
||||||
unsafe {
|
unsafe {
|
||||||
status = self.tinyinst.run();
|
status = self.tinyinst.run();
|
||||||
self.tinyinst.vec_coverage(self.coverage, false);
|
self.tinyinst
|
||||||
|
.vec_coverage(self.coverage_ptr.as_mut().unwrap(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
match status {
|
match status {
|
||||||
@ -100,30 +108,52 @@ pub struct TinyInstExecutorBuilder<'a, SP> {
|
|||||||
tinyinst_args: Vec<String>,
|
tinyinst_args: Vec<String>,
|
||||||
program_args: Vec<String>,
|
program_args: Vec<String>,
|
||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
|
coverage_ptr: *mut Vec<u64>,
|
||||||
shmem_provider: Option<&'a mut SP>,
|
shmem_provider: Option<&'a mut SP>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_FILE: usize = 1024 * 1024;
|
const MAX_FILE: usize = 1024 * 1024;
|
||||||
const SHMEM_FUZZ_HDR_SIZE: usize = 4;
|
const SHMEM_FUZZ_HDR_SIZE: usize = 4;
|
||||||
|
|
||||||
impl<'a> Default for TinyInstExecutorBuilder<'a, StdShMemProvider> {
|
impl<'a> Default for TinyInstExecutorBuilder<'a, NopShMemProvider> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TinyInstExecutorBuilder<'a, StdShMemProvider> {
|
impl<'a> TinyInstExecutorBuilder<'a, NopShMemProvider> {
|
||||||
/// Constructor
|
/// Constructor
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> TinyInstExecutorBuilder<'a, StdShMemProvider> {
|
pub fn new() -> TinyInstExecutorBuilder<'a, NopShMemProvider> {
|
||||||
Self {
|
Self {
|
||||||
tinyinst_args: vec![],
|
tinyinst_args: vec![],
|
||||||
program_args: vec![],
|
program_args: vec![],
|
||||||
timeout: Duration::new(3, 0),
|
timeout: Duration::new(3, 0),
|
||||||
shmem_provider: None,
|
shmem_provider: None,
|
||||||
|
coverage_ptr: ptr::null_mut(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Use this to enable shmem testcase passing.
|
||||||
|
#[must_use]
|
||||||
|
pub fn shmem_provider<SP: ShMemProvider>(
|
||||||
|
self,
|
||||||
|
shmem_provider: &'a mut SP,
|
||||||
|
) -> TinyInstExecutorBuilder<'a, SP> {
|
||||||
|
TinyInstExecutorBuilder {
|
||||||
|
tinyinst_args: self.tinyinst_args,
|
||||||
|
program_args: self.program_args,
|
||||||
|
timeout: self.timeout,
|
||||||
|
shmem_provider: Some(shmem_provider),
|
||||||
|
coverage_ptr: ptr::null_mut(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, SP> TinyInstExecutorBuilder<'a, SP>
|
||||||
|
where
|
||||||
|
SP: ShMemProvider,
|
||||||
|
{
|
||||||
/// Argument for tinyinst instrumentation
|
/// Argument for tinyinst instrumentation
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn tinyinst_arg(mut self, arg: String) -> Self {
|
pub fn tinyinst_arg(mut self, arg: String) -> Self {
|
||||||
@ -207,31 +237,22 @@ impl<'a> TinyInstExecutorBuilder<'a, StdShMemProvider> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use this to enable shmem testcase passing.
|
/// Set the pointer to the coverage vec used to observer the execution.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// The coverage vec pointer must point to a valid vec and outlive the time the [`TinyInstExecutor`] is alive.
|
||||||
|
/// The map will be dereferenced and borrowed mutably during execution. This may not happen concurrently.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn shmem_provider<SP: ShMemProvider>(
|
pub fn coverage_ptr(mut self, coverage_ptr: *mut Vec<u64>) -> Self {
|
||||||
self,
|
self.coverage_ptr = coverage_ptr;
|
||||||
shmem_provider: &'a mut SP,
|
self
|
||||||
) -> TinyInstExecutorBuilder<'a, SP> {
|
|
||||||
TinyInstExecutorBuilder {
|
|
||||||
tinyinst_args: self.tinyinst_args,
|
|
||||||
program_args: self.program_args,
|
|
||||||
timeout: self.timeout,
|
|
||||||
shmem_provider: Some(shmem_provider),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, SP> TinyInstExecutorBuilder<'a, SP>
|
/// Build [`TinyInst`](https://github.com/googleprojectzero/TinyInst) executor
|
||||||
where
|
pub fn build<OT, S>(&mut self, observers: OT) -> Result<TinyInstExecutor<S, SP, OT>, Error> {
|
||||||
SP: ShMemProvider,
|
if self.coverage_ptr.is_null() {
|
||||||
{
|
return Err(Error::illegal_argument("Coverage pointer may not be null."));
|
||||||
/// Build tinyinst executor
|
}
|
||||||
pub fn build<OT, S>(
|
|
||||||
&mut self,
|
|
||||||
coverage: &'a mut Vec<u64>,
|
|
||||||
observers: OT,
|
|
||||||
) -> Result<TinyInstExecutor<'a, S, SP, OT>, Error> {
|
|
||||||
let (map, shmem_id) = match &mut self.shmem_provider {
|
let (map, shmem_id) = match &mut self.shmem_provider {
|
||||||
Some(provider) => {
|
Some(provider) => {
|
||||||
// setup shared memory
|
// setup shared memory
|
||||||
@ -285,7 +306,7 @@ where
|
|||||||
|
|
||||||
Ok(TinyInstExecutor {
|
Ok(TinyInstExecutor {
|
||||||
tinyinst,
|
tinyinst,
|
||||||
coverage,
|
coverage_ptr: self.coverage_ptr,
|
||||||
timeout: self.timeout,
|
timeout: self.timeout,
|
||||||
observers,
|
observers,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
@ -295,7 +316,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S, SP, OT> HasObservers for TinyInstExecutor<'a, S, SP, OT>
|
impl<S, SP, OT> HasObservers for TinyInstExecutor<S, SP, OT>
|
||||||
where
|
where
|
||||||
S: State,
|
S: State,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
@ -309,14 +330,14 @@ where
|
|||||||
RefIndexable::from(&mut self.observers)
|
RefIndexable::from(&mut self.observers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a, S, SP, OT> UsesState for TinyInstExecutor<'a, S, SP, OT>
|
impl<S, SP, OT> UsesState for TinyInstExecutor<S, SP, OT>
|
||||||
where
|
where
|
||||||
S: State,
|
S: State,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
type State = S;
|
type State = S;
|
||||||
}
|
}
|
||||||
impl<'a, S, SP, OT> UsesObservers for TinyInstExecutor<'a, S, SP, OT>
|
impl<S, SP, OT> UsesObservers for TinyInstExecutor<S, SP, OT>
|
||||||
where
|
where
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: State,
|
S: State,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user