Fix usage of TracingStage (#3062)
* real fix * more * debug * fix * fixer * mmmm * mm * mm * mm * fix * fix atheris * ?
This commit is contained in:
parent
f4cb9a827d
commit
226a20e6cf
@ -370,7 +370,7 @@ unsafe fn fuzz(
|
|||||||
|
|
||||||
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||||
|
|
||||||
let tracing = ShadowTracingStage::new(&mut executor);
|
let tracing = ShadowTracingStage::new();
|
||||||
|
|
||||||
// Setup a randomic Input2State stage
|
// Setup a randomic Input2State stage
|
||||||
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(
|
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(
|
||||||
|
@ -218,7 +218,7 @@ fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
|
|||||||
|
|
||||||
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||||
|
|
||||||
let tracing = ShadowTracingStage::new(&mut executor);
|
let tracing = ShadowTracingStage::new();
|
||||||
|
|
||||||
// Setup a randomic Input2State stage
|
// Setup a randomic Input2State stage
|
||||||
let i2s =
|
let i2s =
|
||||||
|
@ -344,7 +344,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
|
|||||||
|
|
||||||
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||||
|
|
||||||
let tracing = ShadowTracingStage::new(&mut executor);
|
let tracing = ShadowTracingStage::new();
|
||||||
|
|
||||||
// Setup a randomic Input2State stage
|
// Setup a randomic Input2State stage
|
||||||
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(
|
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(
|
||||||
|
@ -391,7 +391,7 @@ fn fuzz(
|
|||||||
println!("We imported {} inputs from disk.", state.corpus().count());
|
println!("We imported {} inputs from disk.", state.corpus().count());
|
||||||
}
|
}
|
||||||
|
|
||||||
let tracing = ShadowTracingStage::new(&mut executor);
|
let tracing = ShadowTracingStage::new();
|
||||||
|
|
||||||
// The order of the stages matter!
|
// The order of the stages matter!
|
||||||
let mut stages = tuple_list!(calibration, tracing, i2s, power);
|
let mut stages = tuple_list!(calibration, tracing, i2s, power);
|
||||||
|
@ -403,7 +403,7 @@ fn fuzz(
|
|||||||
println!("We imported {} input(s) from disk.", state.corpus().count());
|
println!("We imported {} input(s) from disk.", state.corpus().count());
|
||||||
}
|
}
|
||||||
|
|
||||||
let tracing = ShadowTracingStage::new(&mut executor);
|
let tracing = ShadowTracingStage::new();
|
||||||
|
|
||||||
// The order of the stages matter!
|
// The order of the stages matter!
|
||||||
let mut stages = tuple_list!(calibration, tracing, i2s, power);
|
let mut stages = tuple_list!(calibration, tracing, i2s, power);
|
||||||
|
@ -316,7 +316,7 @@ impl<M: Monitor> Instance<'_, M> {
|
|||||||
|
|
||||||
let mut shadow_executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
let mut shadow_executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||||
|
|
||||||
let tracing = ShadowTracingStage::new(&mut shadow_executor);
|
let tracing = ShadowTracingStage::new();
|
||||||
|
|
||||||
// Setup a randomic Input2State stage
|
// Setup a randomic Input2State stage
|
||||||
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(
|
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(
|
||||||
|
@ -192,7 +192,7 @@ impl<M: Monitor> Instance<'_, M> {
|
|||||||
I2SRandReplace::new()
|
I2SRandReplace::new()
|
||||||
)));
|
)));
|
||||||
|
|
||||||
let tracing = ShadowTracingStage::new(&mut executor);
|
let tracing = ShadowTracingStage::new();
|
||||||
|
|
||||||
// Setup a MOPT mutator
|
// Setup a MOPT mutator
|
||||||
let mutator = StdMOptMutator::new(
|
let mutator = StdMOptMutator::new(
|
||||||
|
@ -232,7 +232,7 @@ pub fn fuzz() {
|
|||||||
)));
|
)));
|
||||||
|
|
||||||
// Setup an havoc mutator with a mutational stage
|
// Setup an havoc mutator with a mutational stage
|
||||||
let tracing = ShadowTracingStage::new(&mut executor);
|
let tracing = ShadowTracingStage::new();
|
||||||
let mutator = StdScheduledMutator::new(havoc_mutations());
|
let mutator = StdScheduledMutator::new(havoc_mutations());
|
||||||
let mut stages = tuple_list!(tracing, i2s, StdMutationalStage::new(mutator),);
|
let mut stages = tuple_list!(tracing, i2s, StdMutationalStage::new(mutator),);
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ pub fn fuzz() {
|
|||||||
)));
|
)));
|
||||||
|
|
||||||
// Setup an havoc mutator with a mutational stage
|
// Setup an havoc mutator with a mutational stage
|
||||||
let tracing = ShadowTracingStage::new(&mut executor);
|
let tracing = ShadowTracingStage::new();
|
||||||
let mutator = StdScheduledMutator::new(havoc_mutations());
|
let mutator = StdScheduledMutator::new(havoc_mutations());
|
||||||
let mut stages = tuple_list!(tracing, i2s, StdMutationalStage::new(mutator),);
|
let mut stages = tuple_list!(tracing, i2s, StdMutationalStage::new(mutator),);
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ use clap::{Arg, ArgAction, Command};
|
|||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{Corpus, InMemoryCorpus, OnDiskCorpus},
|
corpus::{Corpus, InMemoryCorpus, OnDiskCorpus},
|
||||||
events::{launcher::Launcher, EventConfig},
|
events::{launcher::Launcher, EventConfig},
|
||||||
executors::{inprocess::InProcessExecutor, ExitKind},
|
executors::{inprocess::InProcessExecutor, ExitKind, ShadowExecutor},
|
||||||
feedback_or,
|
feedback_or,
|
||||||
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
||||||
fuzzer::{Fuzzer, StdFuzzer},
|
fuzzer::{Fuzzer, StdFuzzer},
|
||||||
@ -28,7 +28,7 @@ use libafl::{
|
|||||||
},
|
},
|
||||||
observers::{CanTrack, HitcountsMapObserver, StdMapObserver, TimeObserver},
|
observers::{CanTrack, HitcountsMapObserver, StdMapObserver, TimeObserver},
|
||||||
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
|
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
|
||||||
stages::{StdMutationalStage, TracingStage},
|
stages::{ShadowTracingStage, StdMutationalStage, TracingStage},
|
||||||
state::{HasCorpus, StdState},
|
state::{HasCorpus, StdState},
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
};
|
};
|
||||||
@ -216,14 +216,9 @@ pub extern "C" fn LLVMFuzzerRunDriver(
|
|||||||
ExitKind::Ok
|
ExitKind::Ok
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||||
// Setup a tracing stage in which we log comparisons
|
// Setup a tracing stage in which we log comparisons
|
||||||
let tracing = TracingStage::new(InProcessExecutor::new(
|
let tracing = ShadowTracingStage::new();
|
||||||
&mut harness,
|
|
||||||
tuple_list!(cmplog_observer),
|
|
||||||
&mut fuzzer,
|
|
||||||
&mut state,
|
|
||||||
&mut mgr,
|
|
||||||
)?);
|
|
||||||
|
|
||||||
// Setup a randomic Input2State stage
|
// Setup a randomic Input2State stage
|
||||||
let i2s =
|
let i2s =
|
||||||
|
@ -19,7 +19,7 @@ use libafl::{
|
|||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
|
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
|
||||||
events::SimpleRestartingEventManager,
|
events::SimpleRestartingEventManager,
|
||||||
executors::{ExitKind, inprocess::InProcessExecutor},
|
executors::{ExitKind, ShadowExecutor, inprocess::InProcessExecutor},
|
||||||
feedback_or,
|
feedback_or,
|
||||||
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback},
|
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback},
|
||||||
fuzzer::{Fuzzer, StdFuzzer},
|
fuzzer::{Fuzzer, StdFuzzer},
|
||||||
@ -34,7 +34,7 @@ use libafl::{
|
|||||||
IndexesLenTimeMinimizerScheduler, StdWeightedScheduler, powersched::PowerSchedule,
|
IndexesLenTimeMinimizerScheduler, StdWeightedScheduler, powersched::PowerSchedule,
|
||||||
},
|
},
|
||||||
stages::{
|
stages::{
|
||||||
StdMutationalStage, TracingStage, calibrate::CalibrationStage,
|
ShadowTracingStage, StdMutationalStage, calibrate::CalibrationStage,
|
||||||
power::StdPowerMutationalStage,
|
power::StdPowerMutationalStage,
|
||||||
},
|
},
|
||||||
state::{HasCorpus, StdState},
|
state::{HasCorpus, StdState},
|
||||||
@ -331,8 +331,6 @@ fn fuzz(
|
|||||||
ExitKind::Ok
|
ExitKind::Ok
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut tracing_harness = harness;
|
|
||||||
|
|
||||||
// Create the executor for an in-process function with one observer for edge coverage and one for the execution time
|
// Create the executor for an in-process function with one observer for edge coverage and one for the execution time
|
||||||
let mut executor = InProcessExecutor::with_timeout(
|
let mut executor = InProcessExecutor::with_timeout(
|
||||||
&mut harness,
|
&mut harness,
|
||||||
@ -343,18 +341,10 @@ fn fuzz(
|
|||||||
timeout,
|
timeout,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||||
|
|
||||||
// Setup a tracing stage in which we log comparisons
|
// Setup a tracing stage in which we log comparisons
|
||||||
let tracing = TracingStage::new(
|
let tracing = ShadowTracingStage::new();
|
||||||
InProcessExecutor::with_timeout(
|
|
||||||
&mut tracing_harness,
|
|
||||||
tuple_list!(cmplog_observer),
|
|
||||||
&mut fuzzer,
|
|
||||||
&mut state,
|
|
||||||
&mut mgr,
|
|
||||||
timeout * 10,
|
|
||||||
)?,
|
|
||||||
// Give it more time!
|
|
||||||
);
|
|
||||||
|
|
||||||
// The order of the stages matter!
|
// The order of the stages matter!
|
||||||
let mut stages = tuple_list!(calibration, tracing, i2s, power);
|
let mut stages = tuple_list!(calibration, tracing, i2s, power);
|
||||||
|
@ -18,10 +18,7 @@ use clap::{Arg, Command};
|
|||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
|
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
|
||||||
events::SimpleRestartingEventManager,
|
events::SimpleRestartingEventManager,
|
||||||
executors::{
|
executors::{inprocess::HookableInProcessExecutor, ExitKind, ShadowExecutor},
|
||||||
inprocess::{HookableInProcessExecutor, InProcessExecutor},
|
|
||||||
ExitKind,
|
|
||||||
},
|
|
||||||
feedback_or,
|
feedback_or,
|
||||||
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback},
|
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback},
|
||||||
fuzzer::{Fuzzer, StdFuzzer},
|
fuzzer::{Fuzzer, StdFuzzer},
|
||||||
@ -36,8 +33,8 @@ use libafl::{
|
|||||||
powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler,
|
powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler,
|
||||||
},
|
},
|
||||||
stages::{
|
stages::{
|
||||||
calibrate::CalibrationStage, power::StdPowerMutationalStage, StdMutationalStage,
|
calibrate::CalibrationStage, power::StdPowerMutationalStage, ShadowTracingStage,
|
||||||
TracingStage,
|
StdMutationalStage,
|
||||||
},
|
},
|
||||||
state::{HasCorpus, StdState},
|
state::{HasCorpus, StdState},
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
@ -343,24 +340,10 @@ fn fuzz(
|
|||||||
ExitKind::Ok
|
ExitKind::Ok
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut tracing_harness = harness;
|
|
||||||
let ctx_hook = CtxHook::new();
|
let ctx_hook = CtxHook::new();
|
||||||
|
|
||||||
// Setup a tracing stage in which we log comparisons
|
|
||||||
let tracing = TracingStage::new(
|
|
||||||
InProcessExecutor::with_timeout(
|
|
||||||
&mut tracing_harness,
|
|
||||||
tuple_list!(cmplog_observer),
|
|
||||||
&mut fuzzer,
|
|
||||||
&mut state,
|
|
||||||
&mut mgr,
|
|
||||||
timeout * 10,
|
|
||||||
)?,
|
|
||||||
// Give it more time!
|
|
||||||
);
|
|
||||||
|
|
||||||
// Create the executor for an in-process function with one observer for edge coverage and one for the execution time
|
// Create the executor for an in-process function with one observer for edge coverage and one for the execution time
|
||||||
let mut executor = HookableInProcessExecutor::with_timeout_generic(
|
let executor = HookableInProcessExecutor::with_timeout_generic(
|
||||||
tuple_list!(ctx_hook),
|
tuple_list!(ctx_hook),
|
||||||
&mut harness,
|
&mut harness,
|
||||||
tuple_list!(edges_observer, time_observer),
|
tuple_list!(edges_observer, time_observer),
|
||||||
@ -370,6 +353,10 @@ fn fuzz(
|
|||||||
timeout,
|
timeout,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||||
|
// Setup a tracing stage in which we log comparisons
|
||||||
|
let tracing = ShadowTracingStage::new();
|
||||||
|
|
||||||
// The order of the stages matter!
|
// The order of the stages matter!
|
||||||
let mut stages = tuple_list!(calibration, tracing, i2s, power);
|
let mut stages = tuple_list!(calibration, tracing, i2s, power);
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ use content_inspector::inspect;
|
|||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
|
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
|
||||||
events::SimpleRestartingEventManager,
|
events::SimpleRestartingEventManager,
|
||||||
executors::{inprocess::InProcessExecutor, ExitKind},
|
executors::{inprocess::InProcessExecutor, ExitKind, ShadowExecutor},
|
||||||
feedback_or,
|
feedback_or,
|
||||||
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback},
|
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback},
|
||||||
fuzzer::{Fuzzer, StdFuzzer},
|
fuzzer::{Fuzzer, StdFuzzer},
|
||||||
@ -40,7 +40,7 @@ use libafl::{
|
|||||||
},
|
},
|
||||||
stages::{
|
stages::{
|
||||||
calibrate::CalibrationStage, power::StdPowerMutationalStage, GeneralizationStage,
|
calibrate::CalibrationStage, power::StdPowerMutationalStage, GeneralizationStage,
|
||||||
StdMutationalStage, TracingStage,
|
ShadowTracingStage, StdMutationalStage,
|
||||||
},
|
},
|
||||||
state::{HasCorpus, StdState},
|
state::{HasCorpus, StdState},
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
@ -400,8 +400,6 @@ fn fuzz_binary(
|
|||||||
ExitKind::Ok
|
ExitKind::Ok
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut tracing_harness = harness;
|
|
||||||
|
|
||||||
// Create the executor for an in-process function with one observer for edge coverage and one for the execution time
|
// Create the executor for an in-process function with one observer for edge coverage and one for the execution time
|
||||||
let mut executor = InProcessExecutor::with_timeout(
|
let mut executor = InProcessExecutor::with_timeout(
|
||||||
&mut harness,
|
&mut harness,
|
||||||
@ -413,14 +411,9 @@ fn fuzz_binary(
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Setup a tracing stage in which we log comparisons
|
// Setup a tracing stage in which we log comparisons
|
||||||
let tracing = TracingStage::new(InProcessExecutor::with_timeout(
|
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||||
&mut tracing_harness,
|
|
||||||
tuple_list!(cmplog_observer),
|
let tracing = ShadowTracingStage::new();
|
||||||
&mut fuzzer,
|
|
||||||
&mut state,
|
|
||||||
&mut mgr,
|
|
||||||
timeout * 10,
|
|
||||||
)?);
|
|
||||||
|
|
||||||
// The order of the stages matter!
|
// The order of the stages matter!
|
||||||
let mut stages = tuple_list!(calibration, tracing, i2s, power);
|
let mut stages = tuple_list!(calibration, tracing, i2s, power);
|
||||||
@ -632,8 +625,6 @@ fn fuzz_text(
|
|||||||
ExitKind::Ok
|
ExitKind::Ok
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut tracing_harness = harness;
|
|
||||||
|
|
||||||
let generalization = GeneralizationStage::new(&edges_observer);
|
let generalization = GeneralizationStage::new(&edges_observer);
|
||||||
|
|
||||||
// Create the executor for an in-process function with one observer for edge coverage and one for the execution time
|
// Create the executor for an in-process function with one observer for edge coverage and one for the execution time
|
||||||
@ -646,15 +637,8 @@ fn fuzz_text(
|
|||||||
timeout,
|
timeout,
|
||||||
)?;
|
)?;
|
||||||
// Setup a tracing stage in which we log comparisons
|
// Setup a tracing stage in which we log comparisons
|
||||||
let tracing = TracingStage::new(InProcessExecutor::with_timeout(
|
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||||
&mut tracing_harness,
|
let tracing = ShadowTracingStage::new();
|
||||||
tuple_list!(cmplog_observer),
|
|
||||||
&mut fuzzer,
|
|
||||||
&mut state,
|
|
||||||
&mut mgr,
|
|
||||||
// Give it more time!
|
|
||||||
timeout * 10,
|
|
||||||
)?);
|
|
||||||
|
|
||||||
// The order of the stages matter!
|
// The order of the stages matter!
|
||||||
let mut stages = tuple_list!(generalization, calibration, tracing, i2s, power, grimoire);
|
let mut stages = tuple_list!(generalization, calibration, tracing, i2s, power, grimoire);
|
||||||
|
@ -152,7 +152,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup a tracing stage in which we log comparisons
|
// Setup a tracing stage in which we log comparisons
|
||||||
let tracing = ShadowTracingStage::new(&mut executor);
|
let tracing = ShadowTracingStage::new();
|
||||||
|
|
||||||
// Setup a randomic Input2State stage
|
// Setup a randomic Input2State stage
|
||||||
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(I2SRandReplace::new())));
|
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(I2SRandReplace::new())));
|
||||||
|
@ -190,7 +190,7 @@ fn fuzz(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup a tracing stage in which we log comparisons
|
// Setup a tracing stage in which we log comparisons
|
||||||
let tracing = ShadowTracingStage::new(&mut executor);
|
let tracing = ShadowTracingStage::new();
|
||||||
|
|
||||||
// Setup a randomic Input2State stage
|
// Setup a randomic Input2State stage
|
||||||
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(I2SRandReplace::new())));
|
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(I2SRandReplace::new())));
|
||||||
|
@ -37,7 +37,7 @@ pub use sync::*;
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use time_tracker::TimeTrackingStageWrapper;
|
pub use time_tracker::TimeTrackingStageWrapper;
|
||||||
pub use tmin::{ObserverEqualityFactory, ObserverEqualityFeedback, StdTMinMutationalStage};
|
pub use tmin::{ObserverEqualityFactory, ObserverEqualityFeedback, StdTMinMutationalStage};
|
||||||
pub use tracing::{ShadowTracingStage, TracingStage};
|
pub use tracing::TracingStage;
|
||||||
pub use tuneable::*;
|
pub use tuneable::*;
|
||||||
use tuple_list::NonEmptyTuple;
|
use tuple_list::NonEmptyTuple;
|
||||||
#[cfg(feature = "unicode")]
|
#[cfg(feature = "unicode")]
|
||||||
@ -57,6 +57,9 @@ pub mod mutational;
|
|||||||
pub mod push;
|
pub mod push;
|
||||||
pub mod tmin;
|
pub mod tmin;
|
||||||
|
|
||||||
|
pub mod shadow;
|
||||||
|
pub use shadow::*;
|
||||||
|
|
||||||
pub mod replay;
|
pub mod replay;
|
||||||
pub use replay::*;
|
pub use replay::*;
|
||||||
|
|
||||||
|
139
libafl/src/stages/shadow.rs
Normal file
139
libafl/src/stages/shadow.rs
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
//! A stage that runs the shadow executor using also the shadow observers. Unlike tracing stage, this
|
||||||
|
//! stage *CAN* be used with inprocess executor.
|
||||||
|
|
||||||
|
use alloc::{
|
||||||
|
borrow::{Cow, ToOwned},
|
||||||
|
string::ToString,
|
||||||
|
};
|
||||||
|
use core::{fmt::Debug, marker::PhantomData};
|
||||||
|
|
||||||
|
use libafl_bolts::Named;
|
||||||
|
|
||||||
|
#[cfg(feature = "introspection")]
|
||||||
|
use crate::monitors::stats::PerfFeature;
|
||||||
|
use crate::{
|
||||||
|
Error, HasNamedMetadata,
|
||||||
|
corpus::HasCurrentCorpusId,
|
||||||
|
executors::{Executor, HasObservers, ShadowExecutor},
|
||||||
|
mark_feature_time,
|
||||||
|
observers::ObserversTuple,
|
||||||
|
stages::{Restartable, RetryCountRestartHelper, Stage},
|
||||||
|
start_timer,
|
||||||
|
state::{HasCorpus, HasCurrentTestcase, HasExecutions, MaybeHasClientPerfMonitor},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A stage that runs the shadow executor using also the shadow observers
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct ShadowTracingStage<E, EM, I, SOT, S, Z> {
|
||||||
|
name: Cow<'static, str>,
|
||||||
|
phantom: PhantomData<(E, EM, I, SOT, S, Z)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E, EM, I, SOT, S, Z> Default for ShadowTracingStage<E, EM, I, SOT, S, Z>
|
||||||
|
where
|
||||||
|
E: Executor<EM, I, S, Z> + HasObservers,
|
||||||
|
S: HasExecutions + HasCorpus<I>,
|
||||||
|
SOT: ObserversTuple<I, S>,
|
||||||
|
{
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The counter for giving this stage unique id
|
||||||
|
static mut SHADOW_TRACING_STAGE_ID: usize = 0;
|
||||||
|
/// Name for shadow tracing stage
|
||||||
|
pub static SHADOW_TRACING_STAGE_NAME: &str = "shadow";
|
||||||
|
|
||||||
|
impl<E, EM, I, SOT, S, Z> Named for ShadowTracingStage<E, EM, I, SOT, S, Z> {
|
||||||
|
fn name(&self) -> &Cow<'static, str> {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E, EM, I, SOT, S, Z> Stage<ShadowExecutor<E, I, S, SOT>, EM, S, Z>
|
||||||
|
for ShadowTracingStage<E, EM, I, SOT, S, Z>
|
||||||
|
where
|
||||||
|
E: Executor<EM, I, S, Z> + HasObservers,
|
||||||
|
E::Observers: ObserversTuple<I, S>,
|
||||||
|
SOT: ObserversTuple<I, S>,
|
||||||
|
S: HasExecutions
|
||||||
|
+ HasCorpus<I>
|
||||||
|
+ HasNamedMetadata
|
||||||
|
+ Debug
|
||||||
|
+ HasCurrentTestcase<I>
|
||||||
|
+ HasCurrentCorpusId
|
||||||
|
+ MaybeHasClientPerfMonitor,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn perform(
|
||||||
|
&mut self,
|
||||||
|
fuzzer: &mut Z,
|
||||||
|
executor: &mut ShadowExecutor<E, I, S, SOT>,
|
||||||
|
state: &mut S,
|
||||||
|
manager: &mut EM,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
start_timer!(state);
|
||||||
|
let input = state.current_input_cloned()?;
|
||||||
|
|
||||||
|
mark_feature_time!(state, PerfFeature::GetInputFromCorpus);
|
||||||
|
|
||||||
|
start_timer!(state);
|
||||||
|
executor
|
||||||
|
.shadow_observers_mut()
|
||||||
|
.pre_exec_all(state, &input)?;
|
||||||
|
executor.observers_mut().pre_exec_all(state, &input)?;
|
||||||
|
mark_feature_time!(state, PerfFeature::PreExecObservers);
|
||||||
|
|
||||||
|
start_timer!(state);
|
||||||
|
let exit_kind = executor.run_target(fuzzer, state, manager, &input)?;
|
||||||
|
mark_feature_time!(state, PerfFeature::TargetExecution);
|
||||||
|
|
||||||
|
start_timer!(state);
|
||||||
|
executor
|
||||||
|
.shadow_observers_mut()
|
||||||
|
.post_exec_all(state, &input, &exit_kind)?;
|
||||||
|
executor
|
||||||
|
.observers_mut()
|
||||||
|
.post_exec_all(state, &input, &exit_kind)?;
|
||||||
|
mark_feature_time!(state, PerfFeature::PostExecObservers);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E, EM, I, SOT, S, Z> Restartable<S> for ShadowTracingStage<E, EM, I, SOT, S, Z>
|
||||||
|
where
|
||||||
|
S: HasNamedMetadata + HasCurrentCorpusId,
|
||||||
|
{
|
||||||
|
fn should_restart(&mut self, state: &mut S) -> Result<bool, Error> {
|
||||||
|
RetryCountRestartHelper::no_retry(state, &self.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_progress(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
|
RetryCountRestartHelper::clear_progress(state, &self.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E, EM, I, SOT, S, Z> ShadowTracingStage<E, EM, I, SOT, S, Z>
|
||||||
|
where
|
||||||
|
E: Executor<EM, I, S, Z> + HasObservers,
|
||||||
|
S: HasExecutions + HasCorpus<I>,
|
||||||
|
SOT: ObserversTuple<I, S>,
|
||||||
|
{
|
||||||
|
/// Creates a new default stage
|
||||||
|
pub fn new() -> Self {
|
||||||
|
// unsafe but impossible that you create two threads both instantiating this instance
|
||||||
|
let stage_id = unsafe {
|
||||||
|
let ret = SHADOW_TRACING_STAGE_ID;
|
||||||
|
SHADOW_TRACING_STAGE_ID += 1;
|
||||||
|
ret
|
||||||
|
};
|
||||||
|
Self {
|
||||||
|
name: Cow::Owned(
|
||||||
|
SHADOW_TRACING_STAGE_NAME.to_owned() + ":" + stage_id.to_string().as_str(),
|
||||||
|
),
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,7 @@ use crate::monitors::stats::PerfFeature;
|
|||||||
use crate::{
|
use crate::{
|
||||||
Error, HasNamedMetadata,
|
Error, HasNamedMetadata,
|
||||||
corpus::HasCurrentCorpusId,
|
corpus::HasCurrentCorpusId,
|
||||||
executors::{Executor, HasObservers, ShadowExecutor},
|
executors::{Executor, HasObservers},
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
mark_feature_time,
|
mark_feature_time,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
@ -23,6 +23,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// A stage that runs a tracer executor
|
/// A stage that runs a tracer executor
|
||||||
|
/// This should *NOT* be used with inprocess executor
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct TracingStage<EM, I, TE, S, Z> {
|
pub struct TracingStage<EM, I, TE, S, Z> {
|
||||||
name: Cow<'static, str>,
|
name: Cow<'static, str>,
|
||||||
@ -146,108 +147,3 @@ impl<EM, I, TE, S, Z> TracingStage<EM, I, TE, S, Z> {
|
|||||||
&mut self.tracer_executor
|
&mut self.tracer_executor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A stage that runs the shadow executor using also the shadow observers
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct ShadowTracingStage<E, EM, I, SOT, S, Z> {
|
|
||||||
name: Cow<'static, str>,
|
|
||||||
phantom: PhantomData<(E, EM, I, SOT, S, Z)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The counter for giving this stage unique id
|
|
||||||
static mut SHADOW_TRACING_STAGE_ID: usize = 0;
|
|
||||||
/// Name for shadow tracing stage
|
|
||||||
pub static SHADOW_TRACING_STAGE_NAME: &str = "shadow";
|
|
||||||
|
|
||||||
impl<E, EM, I, SOT, S, Z> Named for ShadowTracingStage<E, EM, I, SOT, S, Z> {
|
|
||||||
fn name(&self) -> &Cow<'static, str> {
|
|
||||||
&self.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E, EM, I, SOT, S, Z> Stage<ShadowExecutor<E, I, S, SOT>, EM, S, Z>
|
|
||||||
for ShadowTracingStage<E, EM, I, SOT, S, Z>
|
|
||||||
where
|
|
||||||
E: Executor<EM, I, S, Z> + HasObservers,
|
|
||||||
E::Observers: ObserversTuple<I, S>,
|
|
||||||
SOT: ObserversTuple<I, S>,
|
|
||||||
S: HasExecutions
|
|
||||||
+ HasCorpus<I>
|
|
||||||
+ HasNamedMetadata
|
|
||||||
+ Debug
|
|
||||||
+ HasCurrentTestcase<I>
|
|
||||||
+ HasCurrentCorpusId
|
|
||||||
+ MaybeHasClientPerfMonitor,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn perform(
|
|
||||||
&mut self,
|
|
||||||
fuzzer: &mut Z,
|
|
||||||
executor: &mut ShadowExecutor<E, I, S, SOT>,
|
|
||||||
state: &mut S,
|
|
||||||
manager: &mut EM,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
start_timer!(state);
|
|
||||||
let input = state.current_input_cloned()?;
|
|
||||||
|
|
||||||
mark_feature_time!(state, PerfFeature::GetInputFromCorpus);
|
|
||||||
|
|
||||||
start_timer!(state);
|
|
||||||
executor
|
|
||||||
.shadow_observers_mut()
|
|
||||||
.pre_exec_all(state, &input)?;
|
|
||||||
executor.observers_mut().pre_exec_all(state, &input)?;
|
|
||||||
mark_feature_time!(state, PerfFeature::PreExecObservers);
|
|
||||||
|
|
||||||
start_timer!(state);
|
|
||||||
let exit_kind = executor.run_target(fuzzer, state, manager, &input)?;
|
|
||||||
mark_feature_time!(state, PerfFeature::TargetExecution);
|
|
||||||
|
|
||||||
start_timer!(state);
|
|
||||||
executor
|
|
||||||
.shadow_observers_mut()
|
|
||||||
.post_exec_all(state, &input, &exit_kind)?;
|
|
||||||
executor
|
|
||||||
.observers_mut()
|
|
||||||
.post_exec_all(state, &input, &exit_kind)?;
|
|
||||||
mark_feature_time!(state, PerfFeature::PostExecObservers);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E, EM, I, SOT, S, Z> Restartable<S> for ShadowTracingStage<E, EM, I, SOT, S, Z>
|
|
||||||
where
|
|
||||||
S: HasNamedMetadata + HasCurrentCorpusId,
|
|
||||||
{
|
|
||||||
fn should_restart(&mut self, state: &mut S) -> Result<bool, Error> {
|
|
||||||
RetryCountRestartHelper::no_retry(state, &self.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clear_progress(&mut self, state: &mut S) -> Result<(), Error> {
|
|
||||||
RetryCountRestartHelper::clear_progress(state, &self.name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E, EM, I, SOT, S, Z> ShadowTracingStage<E, EM, I, SOT, S, Z>
|
|
||||||
where
|
|
||||||
E: Executor<EM, I, S, Z> + HasObservers,
|
|
||||||
S: HasExecutions + HasCorpus<I>,
|
|
||||||
SOT: ObserversTuple<I, S>,
|
|
||||||
{
|
|
||||||
/// Creates a new default stage
|
|
||||||
pub fn new(_executor: &mut ShadowExecutor<E, I, S, SOT>) -> Self {
|
|
||||||
// unsafe but impossible that you create two threads both instantiating this instance
|
|
||||||
let stage_id = unsafe {
|
|
||||||
let ret = SHADOW_TRACING_STAGE_ID;
|
|
||||||
SHADOW_TRACING_STAGE_ID += 1;
|
|
||||||
ret
|
|
||||||
};
|
|
||||||
Self {
|
|
||||||
name: Cow::Owned(
|
|
||||||
SHADOW_TRACING_STAGE_NAME.to_owned() + ":" + stage_id.to_string().as_str(),
|
|
||||||
),
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -148,7 +148,7 @@ macro_rules! fuzz_with {
|
|||||||
};
|
};
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
executors::{ExitKind, InProcessExecutor},
|
executors::{ExitKind, InProcessExecutor, ShadowExecutor},
|
||||||
feedback_and_fast, feedback_not, feedback_or, feedback_or_fast,
|
feedback_and_fast, feedback_not, feedback_or, feedback_or_fast,
|
||||||
feedbacks::{ConstFeedback, CrashFeedback, MaxMapFeedback, NewHashFeedback, TimeFeedback, TimeoutFeedback},
|
feedbacks::{ConstFeedback, CrashFeedback, MaxMapFeedback, NewHashFeedback, TimeFeedback, TimeoutFeedback},
|
||||||
generators::RandBytesGenerator,
|
generators::RandBytesGenerator,
|
||||||
@ -166,7 +166,7 @@ macro_rules! fuzz_with {
|
|||||||
},
|
},
|
||||||
stages::{
|
stages::{
|
||||||
CalibrationStage, GeneralizationStage, IfStage, StdMutationalStage,
|
CalibrationStage, GeneralizationStage, IfStage, StdMutationalStage,
|
||||||
StdPowerMutationalStage, UnicodeIdentificationStage, TracingStage,
|
StdPowerMutationalStage, UnicodeIdentificationStage, ShadowTracingStage,
|
||||||
},
|
},
|
||||||
state::{HasCorpus, StdState},
|
state::{HasCorpus, StdState},
|
||||||
StdFuzzer,
|
StdFuzzer,
|
||||||
@ -438,8 +438,6 @@ macro_rules! fuzz_with {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut tracing_harness = harness;
|
|
||||||
|
|
||||||
let add_extra_observer = $extra_obsv;
|
let add_extra_observer = $extra_obsv;
|
||||||
let observers = add_extra_observer(
|
let observers = add_extra_observer(
|
||||||
tuple_list!(edges_observer, size_edges_observer, time_observer, backtrace_observer, oom_observer),
|
tuple_list!(edges_observer, size_edges_observer, time_observer, backtrace_observer, oom_observer),
|
||||||
@ -488,14 +486,9 @@ macro_rules! fuzz_with {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
|
||||||
// Setup a tracing stage in which we log comparisons
|
// Setup a tracing stage in which we log comparisons
|
||||||
let tracing = IfStage::new(|_, _, _, _| Ok(!$options.skip_tracing()), (TracingStage::new(InProcessExecutor::new(
|
let tracing = IfStage::new(|_, _, _, _| Ok(!$options.skip_tracing()), (ShadowTracingStage::new(), ()));
|
||||||
&mut tracing_harness,
|
|
||||||
tuple_list!(cmplog_observer),
|
|
||||||
&mut fuzzer,
|
|
||||||
&mut state,
|
|
||||||
&mut mgr,
|
|
||||||
)?), ()));
|
|
||||||
|
|
||||||
// The order of the stages matter!
|
// The order of the stages matter!
|
||||||
let mut stages = tuple_list!(
|
let mut stages = tuple_list!(
|
||||||
|
@ -261,7 +261,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup a tracing stage in which we log comparisons
|
// Setup a tracing stage in which we log comparisons
|
||||||
let tracing = ShadowTracingStage::new(&mut executor);
|
let tracing = ShadowTracingStage::new();
|
||||||
|
|
||||||
// Setup a randomic Input2State stage
|
// Setup a randomic Input2State stage
|
||||||
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(
|
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(
|
||||||
|
@ -299,7 +299,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup a tracing stage in which we log comparisons
|
// Setup a tracing stage in which we log comparisons
|
||||||
let tracing = ShadowTracingStage::new(&mut executor);
|
let tracing = ShadowTracingStage::new();
|
||||||
|
|
||||||
// Setup a randomic Input2State stage
|
// Setup a randomic Input2State stage
|
||||||
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(
|
let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user