Fix fuzz_level related thing, separate on_replace/on_remove from Scheduler & various fixes (#1119)
* delete HasFuzzedCorpusId * more * fmt clp * aa * fixing * delete * a * append parent id when Objective * add HasCorpus inprocss executor * ecofuzz, delete was_fuzzed, update fuzz_level * fix * RemovableScheduler for Tunable, Queue, Weighted * clp * no std * import * on_execution * fix * win * fmt * fix * revert to on_evaluation and propogate in the accounting scheduler * fix --------- Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
This commit is contained in:
parent
2ed6583041
commit
4d778dd64d
@ -19,7 +19,7 @@ use crate::{
|
|||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
executors::{Executor, HasObservers},
|
executors::{Executor, HasObservers},
|
||||||
observers::{MapObserver, ObserversTuple},
|
observers::{MapObserver, ObserversTuple},
|
||||||
schedulers::{LenTimeMulTestcaseScore, Scheduler, TestcaseScore},
|
schedulers::{LenTimeMulTestcaseScore, RemovableScheduler, Scheduler, TestcaseScore},
|
||||||
state::{HasCorpus, HasMetadata, UsesState},
|
state::{HasCorpus, HasMetadata, UsesState},
|
||||||
Error, HasScheduler,
|
Error, HasScheduler,
|
||||||
};
|
};
|
||||||
@ -41,7 +41,7 @@ where
|
|||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
E: Executor<EM, Z> + HasObservers,
|
E: Executor<EM, Z> + HasObservers,
|
||||||
CS: Scheduler<State = E::State>,
|
CS: Scheduler<State = E::State> + RemovableScheduler, // schedulers that has on_remove/on_replace only!
|
||||||
EM: UsesState<State = E::State>,
|
EM: UsesState<State = E::State>,
|
||||||
Z: HasScheduler<Scheduler = CS, State = E::State>;
|
Z: HasScheduler<Scheduler = CS, State = E::State>;
|
||||||
}
|
}
|
||||||
@ -100,7 +100,7 @@ where
|
|||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
E: Executor<EM, Z> + HasObservers,
|
E: Executor<EM, Z> + HasObservers,
|
||||||
CS: Scheduler<State = E::State>,
|
CS: Scheduler<State = E::State> + RemovableScheduler,
|
||||||
EM: UsesState<State = E::State>,
|
EM: UsesState<State = E::State>,
|
||||||
Z: HasScheduler<Scheduler = CS, State = E::State>,
|
Z: HasScheduler<Scheduler = CS, State = E::State>,
|
||||||
{
|
{
|
||||||
|
@ -34,9 +34,7 @@ where
|
|||||||
/// Number of executions done at discovery time
|
/// Number of executions done at discovery time
|
||||||
executions: usize,
|
executions: usize,
|
||||||
/// Number of fuzzing iterations of this particular input updated in perform_mutational
|
/// Number of fuzzing iterations of this particular input updated in perform_mutational
|
||||||
fuzz_level: usize,
|
scheduled_count: usize,
|
||||||
/// If it has been fuzzed
|
|
||||||
fuzzed: bool,
|
|
||||||
/// Parent [`CorpusId`], if known
|
/// Parent [`CorpusId`], if known
|
||||||
parent_id: Option<CorpusId>,
|
parent_id: Option<CorpusId>,
|
||||||
}
|
}
|
||||||
@ -160,28 +158,16 @@ where
|
|||||||
&mut self.executions
|
&mut self.executions
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the `fuzz_level`
|
/// Get the `scheduled_count`
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn fuzz_level(&self) -> usize {
|
pub fn scheduled_count(&self) -> usize {
|
||||||
self.fuzz_level
|
self.scheduled_count
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the `fuzz_level`
|
/// Set the `scheduled_count`
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_fuzz_level(&mut self, fuzz_level: usize) {
|
pub fn set_scheduled_count(&mut self, scheduled_count: usize) {
|
||||||
self.fuzz_level = fuzz_level;
|
self.scheduled_count = scheduled_count;
|
||||||
}
|
|
||||||
|
|
||||||
/// Get if it was fuzzed
|
|
||||||
#[inline]
|
|
||||||
pub fn fuzzed(&self) -> bool {
|
|
||||||
self.fuzzed
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set if it was fuzzed
|
|
||||||
#[inline]
|
|
||||||
pub fn set_fuzzed(&mut self, fuzzed: bool) {
|
|
||||||
self.fuzzed = fuzzed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new Testcase instance given an input
|
/// Create a new Testcase instance given an input
|
||||||
@ -257,9 +243,8 @@ where
|
|||||||
metadata: SerdeAnyMap::new(),
|
metadata: SerdeAnyMap::new(),
|
||||||
exec_time: None,
|
exec_time: None,
|
||||||
cached_len: None,
|
cached_len: None,
|
||||||
fuzz_level: 0,
|
scheduled_count: 0,
|
||||||
executions: 0,
|
executions: 0,
|
||||||
fuzzed: false,
|
|
||||||
parent_id: None,
|
parent_id: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -486,13 +471,8 @@ pub mod pybind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[getter]
|
#[getter]
|
||||||
fn fuzz_level(&self) -> usize {
|
fn scheduled_count(&self) -> usize {
|
||||||
self.inner.as_ref().fuzz_level()
|
self.inner.as_ref().scheduled_count()
|
||||||
}
|
|
||||||
|
|
||||||
#[getter]
|
|
||||||
fn fuzzed(&self) -> bool {
|
|
||||||
self.inner.as_ref().fuzzed()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn metadata(&mut self) -> PyObject {
|
fn metadata(&mut self) -> PyObject {
|
||||||
|
@ -50,7 +50,7 @@ use crate::{
|
|||||||
fuzzer::HasObjective,
|
fuzzer::HasObjective,
|
||||||
inputs::UsesInput,
|
inputs::UsesInput,
|
||||||
observers::{ObserversTuple, UsesObservers},
|
observers::{ObserversTuple, UsesObservers},
|
||||||
state::{HasClientPerfMonitor, HasFuzzedCorpusId, HasSolutions, UsesState},
|
state::{HasClientPerfMonitor, HasCorpus, HasSolutions, UsesState},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ where
|
|||||||
H: FnMut(&<S as UsesInput>::Input) -> ExitKind + ?Sized,
|
H: FnMut(&<S as UsesInput>::Input) -> ExitKind + ?Sized,
|
||||||
HB: BorrowMut<H>,
|
HB: BorrowMut<H>,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: HasSolutions + HasClientPerfMonitor + HasFuzzedCorpusId,
|
S: HasSolutions + HasClientPerfMonitor + HasCorpus,
|
||||||
{
|
{
|
||||||
/// Create a new in mem executor.
|
/// Create a new in mem executor.
|
||||||
/// 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,
|
||||||
@ -344,7 +344,7 @@ impl InProcessHandlers {
|
|||||||
E: Executor<EM, Z> + HasObservers,
|
E: Executor<EM, Z> + HasObservers,
|
||||||
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
||||||
OF: Feedback<E::State>,
|
OF: Feedback<E::State>,
|
||||||
E::State: HasSolutions + HasClientPerfMonitor + HasFuzzedCorpusId,
|
E::State: HasSolutions + HasClientPerfMonitor + HasCorpus,
|
||||||
Z: HasObjective<Objective = OF, State = E::State>,
|
Z: HasObjective<Objective = OF, State = E::State>,
|
||||||
{
|
{
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
@ -545,7 +545,7 @@ pub fn run_observers_and_save_state<E, EM, OF, Z>(
|
|||||||
E: HasObservers,
|
E: HasObservers,
|
||||||
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
||||||
OF: Feedback<E::State>,
|
OF: Feedback<E::State>,
|
||||||
E::State: HasSolutions + HasClientPerfMonitor + HasFuzzedCorpusId,
|
E::State: HasSolutions + HasClientPerfMonitor + HasCorpus,
|
||||||
Z: HasObjective<Objective = OF, State = E::State>,
|
Z: HasObjective<Objective = OF, State = E::State>,
|
||||||
{
|
{
|
||||||
let observers = executor.observers_mut();
|
let observers = executor.observers_mut();
|
||||||
@ -561,8 +561,8 @@ pub fn run_observers_and_save_state<E, EM, OF, Z>(
|
|||||||
|
|
||||||
if interesting {
|
if interesting {
|
||||||
let mut new_testcase = Testcase::new(input.clone());
|
let mut new_testcase = Testcase::new(input.clone());
|
||||||
new_testcase.set_parent_id_optional(state.fuzzed_corpus_id());
|
|
||||||
new_testcase.add_metadata(exitkind);
|
new_testcase.add_metadata(exitkind);
|
||||||
|
new_testcase.set_parent_id_optional(*state.corpus().current());
|
||||||
fuzzer
|
fuzzer
|
||||||
.objective_mut()
|
.objective_mut()
|
||||||
.append_metadata(state, observers, &mut new_testcase)
|
.append_metadata(state, observers, &mut new_testcase)
|
||||||
@ -582,8 +582,6 @@ pub fn run_observers_and_save_state<E, EM, OF, Z>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We will start mutators from scratch after restart.
|
// We will start mutators from scratch after restart.
|
||||||
state.clear_fuzzed_corpus_id();
|
|
||||||
|
|
||||||
event_mgr.on_restart(state).unwrap();
|
event_mgr.on_restart(state).unwrap();
|
||||||
|
|
||||||
log::info!("Waiting for broker...");
|
log::info!("Waiting for broker...");
|
||||||
@ -614,7 +612,7 @@ mod unix_signal_handler {
|
|||||||
feedbacks::Feedback,
|
feedbacks::Feedback,
|
||||||
fuzzer::HasObjective,
|
fuzzer::HasObjective,
|
||||||
inputs::UsesInput,
|
inputs::UsesInput,
|
||||||
state::{HasClientPerfMonitor, HasFuzzedCorpusId, HasSolutions},
|
state::{HasClientPerfMonitor, HasCorpus, HasSolutions},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) type HandlerFuncPtr =
|
pub(crate) type HandlerFuncPtr =
|
||||||
@ -673,7 +671,7 @@ mod unix_signal_handler {
|
|||||||
E: HasObservers,
|
E: HasObservers,
|
||||||
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
||||||
OF: Feedback<E::State>,
|
OF: Feedback<E::State>,
|
||||||
E::State: HasSolutions + HasClientPerfMonitor + HasFuzzedCorpusId,
|
E::State: HasSolutions + HasClientPerfMonitor + HasCorpus,
|
||||||
Z: HasObjective<Objective = OF, State = E::State>,
|
Z: HasObjective<Objective = OF, State = E::State>,
|
||||||
{
|
{
|
||||||
let old_hook = panic::take_hook();
|
let old_hook = panic::take_hook();
|
||||||
@ -714,7 +712,7 @@ mod unix_signal_handler {
|
|||||||
E: HasObservers,
|
E: HasObservers,
|
||||||
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
||||||
OF: Feedback<E::State>,
|
OF: Feedback<E::State>,
|
||||||
E::State: HasSolutions + HasClientPerfMonitor + HasFuzzedCorpusId,
|
E::State: HasSolutions + HasClientPerfMonitor + HasCorpus,
|
||||||
Z: HasObjective<Objective = OF, State = E::State>,
|
Z: HasObjective<Objective = OF, State = E::State>,
|
||||||
{
|
{
|
||||||
if !data.is_valid() {
|
if !data.is_valid() {
|
||||||
@ -757,7 +755,7 @@ mod unix_signal_handler {
|
|||||||
E: Executor<EM, Z> + HasObservers,
|
E: Executor<EM, Z> + HasObservers,
|
||||||
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
||||||
OF: Feedback<E::State>,
|
OF: Feedback<E::State>,
|
||||||
E::State: HasSolutions + HasClientPerfMonitor + HasFuzzedCorpusId,
|
E::State: HasSolutions + HasClientPerfMonitor + HasCorpus,
|
||||||
Z: HasObjective<Objective = OF, State = E::State>,
|
Z: HasObjective<Objective = OF, State = E::State>,
|
||||||
{
|
{
|
||||||
#[cfg(all(target_os = "android", target_arch = "aarch64"))]
|
#[cfg(all(target_os = "android", target_arch = "aarch64"))]
|
||||||
@ -865,7 +863,7 @@ pub mod windows_asan_handler {
|
|||||||
feedbacks::Feedback,
|
feedbacks::Feedback,
|
||||||
fuzzer::HasObjective,
|
fuzzer::HasObjective,
|
||||||
inputs::UsesInput,
|
inputs::UsesInput,
|
||||||
state::{HasClientPerfMonitor, HasFuzzedCorpusId, HasSolutions},
|
state::{HasClientPerfMonitor, HasCorpus, HasSolutions},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@ -875,7 +873,7 @@ pub mod windows_asan_handler {
|
|||||||
E: Executor<EM, Z> + HasObservers,
|
E: Executor<EM, Z> + HasObservers,
|
||||||
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
||||||
OF: Feedback<E::State>,
|
OF: Feedback<E::State>,
|
||||||
E::State: HasSolutions + HasClientPerfMonitor + HasFuzzedCorpusId,
|
E::State: HasSolutions + HasClientPerfMonitor + HasCorpus,
|
||||||
Z: HasObjective<Objective = OF, State = E::State>,
|
Z: HasObjective<Objective = OF, State = E::State>,
|
||||||
{
|
{
|
||||||
let mut data = &mut GLOBAL_STATE;
|
let mut data = &mut GLOBAL_STATE;
|
||||||
@ -974,7 +972,7 @@ mod windows_exception_handler {
|
|||||||
feedbacks::Feedback,
|
feedbacks::Feedback,
|
||||||
fuzzer::HasObjective,
|
fuzzer::HasObjective,
|
||||||
inputs::UsesInput,
|
inputs::UsesInput,
|
||||||
state::{HasClientPerfMonitor, HasFuzzedCorpusId, HasSolutions},
|
state::{HasClientPerfMonitor, HasCorpus, HasSolutions},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) type HandlerFuncPtr =
|
pub(crate) type HandlerFuncPtr =
|
||||||
@ -1013,7 +1011,7 @@ mod windows_exception_handler {
|
|||||||
E: HasObservers,
|
E: HasObservers,
|
||||||
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
||||||
OF: Feedback<E::State>,
|
OF: Feedback<E::State>,
|
||||||
E::State: HasSolutions + HasClientPerfMonitor + HasFuzzedCorpusId,
|
E::State: HasSolutions + HasClientPerfMonitor + HasCorpus,
|
||||||
Z: HasObjective<Objective = OF, State = E::State>,
|
Z: HasObjective<Objective = OF, State = E::State>,
|
||||||
{
|
{
|
||||||
let old_hook = panic::take_hook();
|
let old_hook = panic::take_hook();
|
||||||
@ -1072,7 +1070,7 @@ mod windows_exception_handler {
|
|||||||
E: HasObservers,
|
E: HasObservers,
|
||||||
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
||||||
OF: Feedback<E::State>,
|
OF: Feedback<E::State>,
|
||||||
E::State: HasSolutions + HasClientPerfMonitor + HasFuzzedCorpusId,
|
E::State: HasSolutions + HasClientPerfMonitor + HasCorpus,
|
||||||
Z: HasObjective<Objective = OF, State = E::State>,
|
Z: HasObjective<Objective = OF, State = E::State>,
|
||||||
{
|
{
|
||||||
let data: &mut InProcessExecutorHandlerData =
|
let data: &mut InProcessExecutorHandlerData =
|
||||||
@ -1133,7 +1131,7 @@ mod windows_exception_handler {
|
|||||||
E: Executor<EM, Z> + HasObservers,
|
E: Executor<EM, Z> + HasObservers,
|
||||||
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
||||||
OF: Feedback<E::State>,
|
OF: Feedback<E::State>,
|
||||||
E::State: HasSolutions + HasClientPerfMonitor + HasFuzzedCorpusId,
|
E::State: HasSolutions + HasClientPerfMonitor + HasCorpus,
|
||||||
Z: HasObjective<Objective = OF, State = E::State>,
|
Z: HasObjective<Objective = OF, State = E::State>,
|
||||||
{
|
{
|
||||||
// Have we set a timer_before?
|
// Have we set a timer_before?
|
||||||
|
@ -14,9 +14,8 @@ use crate::{
|
|||||||
executors::ExitKind,
|
executors::ExitKind,
|
||||||
feedbacks::Feedback,
|
feedbacks::Feedback,
|
||||||
generators::NautilusContext,
|
generators::NautilusContext,
|
||||||
inputs::NautilusInput,
|
inputs::{NautilusInput, UsesInput},
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
prelude::UsesInput,
|
|
||||||
state::{HasClientPerfMonitor, HasMetadata},
|
state::{HasClientPerfMonitor, HasMetadata},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
@ -23,10 +23,7 @@ use crate::{
|
|||||||
schedulers::Scheduler,
|
schedulers::Scheduler,
|
||||||
stages::StagesTuple,
|
stages::StagesTuple,
|
||||||
start_timer,
|
start_timer,
|
||||||
state::{
|
state::{HasClientPerfMonitor, HasCorpus, HasExecutions, HasMetadata, HasSolutions, UsesState},
|
||||||
HasClientPerfMonitor, HasCorpus, HasExecutions, HasFuzzedCorpusId, HasMetadata,
|
|
||||||
HasSolutions, UsesState,
|
|
||||||
},
|
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -330,7 +327,7 @@ where
|
|||||||
F: Feedback<CS::State>,
|
F: Feedback<CS::State>,
|
||||||
OF: Feedback<CS::State>,
|
OF: Feedback<CS::State>,
|
||||||
OT: ObserversTuple<CS::State> + Serialize + DeserializeOwned,
|
OT: ObserversTuple<CS::State> + Serialize + DeserializeOwned,
|
||||||
CS::State: HasCorpus + HasSolutions + HasClientPerfMonitor + HasExecutions + HasFuzzedCorpusId,
|
CS::State: HasCorpus + HasSolutions + HasClientPerfMonitor + HasExecutions,
|
||||||
{
|
{
|
||||||
/// Evaluate if a set of observation channels has an interesting state
|
/// Evaluate if a set of observation channels has an interesting state
|
||||||
fn process_execution<EM>(
|
fn process_execution<EM>(
|
||||||
@ -387,7 +384,6 @@ where
|
|||||||
|
|
||||||
// Add the input to the main corpus
|
// Add the input to the main corpus
|
||||||
let mut testcase = Testcase::with_executions(input.clone(), *state.executions());
|
let mut testcase = Testcase::with_executions(input.clone(), *state.executions());
|
||||||
testcase.set_parent_id_optional(state.fuzzed_corpus_id());
|
|
||||||
self.feedback_mut()
|
self.feedback_mut()
|
||||||
.append_metadata(state, observers, &mut testcase)?;
|
.append_metadata(state, observers, &mut testcase)?;
|
||||||
let idx = state.corpus_mut().add(testcase)?;
|
let idx = state.corpus_mut().add(testcase)?;
|
||||||
@ -421,7 +417,7 @@ where
|
|||||||
|
|
||||||
// The input is a solution, add it to the respective corpus
|
// The input is a solution, add it to the respective corpus
|
||||||
let mut testcase = Testcase::with_executions(input, *state.executions());
|
let mut testcase = Testcase::with_executions(input, *state.executions());
|
||||||
testcase.set_parent_id_optional(state.fuzzed_corpus_id());
|
testcase.set_parent_id_optional(*state.corpus().current());
|
||||||
self.objective_mut()
|
self.objective_mut()
|
||||||
.append_metadata(state, observers, &mut testcase)?;
|
.append_metadata(state, observers, &mut testcase)?;
|
||||||
state.solutions_mut().add(testcase)?;
|
state.solutions_mut().add(testcase)?;
|
||||||
@ -447,7 +443,7 @@ where
|
|||||||
OT: ObserversTuple<CS::State> + Serialize + DeserializeOwned,
|
OT: ObserversTuple<CS::State> + Serialize + DeserializeOwned,
|
||||||
F: Feedback<CS::State>,
|
F: Feedback<CS::State>,
|
||||||
OF: Feedback<CS::State>,
|
OF: Feedback<CS::State>,
|
||||||
CS::State: HasCorpus + HasSolutions + HasClientPerfMonitor + HasExecutions + HasFuzzedCorpusId,
|
CS::State: HasCorpus + HasSolutions + HasClientPerfMonitor + HasExecutions,
|
||||||
{
|
{
|
||||||
/// Process one input, adding to the respective corpora if needed and firing the right events
|
/// Process one input, adding to the respective corpora if needed and firing the right events
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -480,7 +476,7 @@ where
|
|||||||
F: Feedback<CS::State>,
|
F: Feedback<CS::State>,
|
||||||
OF: Feedback<CS::State>,
|
OF: Feedback<CS::State>,
|
||||||
OT: ObserversTuple<CS::State> + Serialize + DeserializeOwned,
|
OT: ObserversTuple<CS::State> + Serialize + DeserializeOwned,
|
||||||
CS::State: HasCorpus + HasSolutions + HasClientPerfMonitor + HasExecutions + HasFuzzedCorpusId,
|
CS::State: HasCorpus + HasSolutions + HasClientPerfMonitor + HasExecutions,
|
||||||
{
|
{
|
||||||
/// Process one input, adding to the respective corpora if needed and firing the right events
|
/// Process one input, adding to the respective corpora if needed and firing the right events
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -518,7 +514,6 @@ where
|
|||||||
|
|
||||||
// Add the input to the main corpus
|
// Add the input to the main corpus
|
||||||
let mut testcase = Testcase::with_executions(input.clone(), *state.executions());
|
let mut testcase = Testcase::with_executions(input.clone(), *state.executions());
|
||||||
testcase.set_parent_id_optional(state.fuzzed_corpus_id());
|
|
||||||
self.feedback_mut()
|
self.feedback_mut()
|
||||||
.append_metadata(state, observers, &mut testcase)?;
|
.append_metadata(state, observers, &mut testcase)?;
|
||||||
let idx = state.corpus_mut().add(testcase)?;
|
let idx = state.corpus_mut().add(testcase)?;
|
||||||
@ -552,7 +547,7 @@ where
|
|||||||
EM: ProgressReporter + EventProcessor<E, Self, State = CS::State>,
|
EM: ProgressReporter + EventProcessor<E, Self, State = CS::State>,
|
||||||
F: Feedback<CS::State>,
|
F: Feedback<CS::State>,
|
||||||
OF: Feedback<CS::State>,
|
OF: Feedback<CS::State>,
|
||||||
CS::State: HasClientPerfMonitor + HasExecutions + HasMetadata + HasFuzzedCorpusId,
|
CS::State: HasClientPerfMonitor + HasExecutions + HasMetadata,
|
||||||
ST: StagesTuple<E, EM, CS::State, Self>,
|
ST: StagesTuple<E, EM, CS::State, Self>,
|
||||||
{
|
{
|
||||||
fn fuzz_one(
|
fn fuzz_one(
|
||||||
@ -577,15 +572,9 @@ where
|
|||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
state.introspection_monitor_mut().reset_stage_index();
|
state.introspection_monitor_mut().reset_stage_index();
|
||||||
|
|
||||||
// Set the parent id - all new testcases will have this id as parent in the following stages.
|
|
||||||
state.set_fuzzed_corpus_id(idx);
|
|
||||||
|
|
||||||
// Execute all stages
|
// Execute all stages
|
||||||
stages.perform_all(self, executor, state, manager, idx)?;
|
stages.perform_all(self, executor, state, manager, idx)?;
|
||||||
|
|
||||||
// Reset the parent id
|
|
||||||
state.clear_fuzzed_corpus_id();
|
|
||||||
|
|
||||||
// Init timer for manager
|
// Init timer for manager
|
||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
state.introspection_monitor_mut().start_timer();
|
state.introspection_monitor_mut().start_timer();
|
||||||
|
@ -8,9 +8,10 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::{rands::Rand, AsMutSlice, AsSlice, HasLen, HasRefCnt},
|
bolts::{rands::Rand, AsMutSlice, AsSlice, HasLen, HasRefCnt},
|
||||||
corpus::{Corpus, CorpusId, Testcase},
|
corpus::{Corpus, CorpusId},
|
||||||
feedbacks::MapIndexesMetadata,
|
feedbacks::MapIndexesMetadata,
|
||||||
inputs::UsesInput,
|
inputs::UsesInput,
|
||||||
|
observers::ObserversTuple,
|
||||||
schedulers::{
|
schedulers::{
|
||||||
minimizer::{IsFavoredMetadata, MinimizerScheduler, DEFAULT_SKIP_NON_FAVORED_PROB},
|
minimizer::{IsFavoredMetadata, MinimizerScheduler, DEFAULT_SKIP_NON_FAVORED_PROB},
|
||||||
LenTimeMulTestcaseScore, Scheduler,
|
LenTimeMulTestcaseScore, Scheduler,
|
||||||
@ -130,22 +131,16 @@ where
|
|||||||
self.inner.on_add(state, idx)
|
self.inner.on_add(state, idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_replace(
|
fn on_evaluation<OT>(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
idx: CorpusId,
|
input: &<Self::State as UsesInput>::Input,
|
||||||
testcase: &Testcase<<Self::State as UsesInput>::Input>,
|
observers: &OT,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error>
|
||||||
self.inner.on_replace(state, idx, testcase)
|
where
|
||||||
}
|
OT: ObserversTuple<Self::State>,
|
||||||
|
{
|
||||||
fn on_remove(
|
self.inner.on_evaluation(state, input, observers)
|
||||||
&mut self,
|
|
||||||
state: &mut Self::State,
|
|
||||||
idx: CorpusId,
|
|
||||||
testcase: &Option<Testcase<<Self::State as UsesInput>::Input>>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
self.inner.on_remove(state, idx, testcase)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next(&mut self, state: &mut Self::State) -> Result<CorpusId, Error> {
|
fn next(&mut self, state: &mut Self::State) -> Result<CorpusId, Error> {
|
||||||
@ -170,8 +165,21 @@ where
|
|||||||
{
|
{
|
||||||
idx = self.inner.base_mut().next(state)?;
|
idx = self.inner.base_mut().next(state)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't add corpus.curret(). The inner scheduler will take care of it
|
||||||
|
|
||||||
Ok(idx)
|
Ok(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set current fuzzed corpus id and `scheduled_count`
|
||||||
|
fn set_current_scheduled(
|
||||||
|
&mut self,
|
||||||
|
_state: &mut Self::State,
|
||||||
|
_next_idx: Option<CorpusId>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
// We do nothing here, the inner scheduler will take care of it
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, CS> CoverageAccountingScheduler<'a, CS>
|
impl<'a, CS> CoverageAccountingScheduler<'a, CS>
|
||||||
@ -271,7 +279,7 @@ where
|
|||||||
|
|
||||||
for (_key, idx) in &top_rated.map {
|
for (_key, idx) in &top_rated.map {
|
||||||
let mut entry = state.corpus().get(*idx)?.borrow_mut();
|
let mut entry = state.corpus().get(*idx)?.borrow_mut();
|
||||||
if entry.fuzzed() {
|
if entry.scheduled_count() > 0 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,7 +290,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new [`CoverageAccountingScheduler`] that wraps a `base` [`Scheduler`]
|
/// Creates a new [`CoverageAccountingScheduler`] that wraps a `base` [`Scheduler`]
|
||||||
/// and has a default probability to skip non-faved [`Testcase`]s of [`DEFAULT_SKIP_NON_FAVORED_PROB`].
|
/// and has a default probability to skip non-faved Testcases of [`DEFAULT_SKIP_NON_FAVORED_PROB`].
|
||||||
pub fn new(state: &mut CS::State, base: CS, accounting_map: &'a [u32]) -> Self {
|
pub fn new(state: &mut CS::State, base: CS, accounting_map: &'a [u32]) -> Self {
|
||||||
match state.metadata().get::<TopAccountingMetadata>() {
|
match state.metadata().get::<TopAccountingMetadata>() {
|
||||||
Some(meta) => {
|
Some(meta) => {
|
||||||
@ -302,7 +310,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new [`CoverageAccountingScheduler`] that wraps a `base` [`Scheduler`]
|
/// Creates a new [`CoverageAccountingScheduler`] that wraps a `base` [`Scheduler`]
|
||||||
/// and has a non-default probability to skip non-faved [`Testcase`]s using (`skip_non_favored_prob`).
|
/// and has a non-default probability to skip non-faved Testcases using (`skip_non_favored_prob`).
|
||||||
pub fn with_skip_prob(
|
pub fn with_skip_prob(
|
||||||
state: &mut CS::State,
|
state: &mut CS::State,
|
||||||
base: CS,
|
base: CS,
|
||||||
|
@ -47,7 +47,6 @@ pub struct EcoTestcaseMetadata {
|
|||||||
last_energy: u64,
|
last_energy: u64,
|
||||||
state: EcoState,
|
state: EcoState,
|
||||||
serial: u64,
|
serial: u64,
|
||||||
was_fuzzed: bool,
|
|
||||||
computed_score: f64,
|
computed_score: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +116,6 @@ where
|
|||||||
.get_mut::<EcoTestcaseMetadata>()
|
.get_mut::<EcoTestcaseMetadata>()
|
||||||
.ok_or_else(|| Error::key_not_found("EcoTestcaseMetadata not found".to_string()))?;
|
.ok_or_else(|| Error::key_not_found("EcoTestcaseMetadata not found".to_string()))?;
|
||||||
// Set was_fuzzed for the old current
|
// Set was_fuzzed for the old current
|
||||||
meta.was_fuzzed = true;
|
|
||||||
meta.last_found = count - last_corpus_count;
|
meta.last_found = count - last_corpus_count;
|
||||||
meta.last_energy = meta.mutation_num - last_mutation_num;
|
meta.last_energy = meta.mutation_num - last_mutation_num;
|
||||||
meta.computed_score
|
meta.computed_score
|
||||||
@ -165,29 +163,15 @@ where
|
|||||||
fn schedule(state: &mut S) -> Result<CorpusId, Error> {
|
fn schedule(state: &mut S) -> Result<CorpusId, Error> {
|
||||||
let mut selection = None;
|
let mut selection = None;
|
||||||
for id in state.corpus().ids() {
|
for id in state.corpus().ids() {
|
||||||
let was_fuzzed = state
|
let was_fuzzed = state.corpus().get(id)?.borrow().scheduled_count() > 0;
|
||||||
.corpus()
|
if was_fuzzed {
|
||||||
.get(id)?
|
|
||||||
.borrow()
|
|
||||||
.metadata()
|
|
||||||
.get::<EcoTestcaseMetadata>()
|
|
||||||
.ok_or_else(|| Error::key_not_found("EcoTestcaseMetadata not found".to_string()))?
|
|
||||||
.was_fuzzed;
|
|
||||||
if !was_fuzzed {
|
|
||||||
selection = Some(id);
|
selection = Some(id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for id in state.corpus().ids() {
|
for id in state.corpus().ids() {
|
||||||
let was_fuzzed = state
|
let was_fuzzed = state.corpus().get(id)?.borrow().scheduled_count() > 0;
|
||||||
.corpus()
|
|
||||||
.get(id)?
|
|
||||||
.borrow()
|
|
||||||
.metadata()
|
|
||||||
.get::<EcoTestcaseMetadata>()
|
|
||||||
.ok_or_else(|| Error::key_not_found("EcoTestcaseMetadata not found".to_string()))?
|
|
||||||
.was_fuzzed;
|
|
||||||
if was_fuzzed {
|
if was_fuzzed {
|
||||||
state
|
state
|
||||||
.metadata_mut()
|
.metadata_mut()
|
||||||
@ -301,10 +285,14 @@ where
|
|||||||
|
|
||||||
// Attach a `SchedulerTestcaseMetaData` to the queue entry.
|
// Attach a `SchedulerTestcaseMetaData` to the queue entry.
|
||||||
depth += 1;
|
depth += 1;
|
||||||
state.corpus().get(idx)?.borrow_mut().add_metadata(
|
{
|
||||||
SchedulerTestcaseMetaData::with_n_fuzz_entry(depth, self.last_hash),
|
let mut testcase = state.corpus().get(idx)?.borrow_mut();
|
||||||
);
|
testcase.add_metadata(SchedulerTestcaseMetaData::with_n_fuzz_entry(
|
||||||
|
depth,
|
||||||
|
self.last_hash,
|
||||||
|
));
|
||||||
|
testcase.set_parent_id_optional(current_idx);
|
||||||
|
}
|
||||||
// Add the testcase metadata for this scheduler
|
// Add the testcase metadata for this scheduler
|
||||||
state
|
state
|
||||||
.corpus()
|
.corpus()
|
||||||
@ -324,25 +312,6 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_replace(
|
|
||||||
&mut self,
|
|
||||||
state: &mut S,
|
|
||||||
idx: CorpusId,
|
|
||||||
_testcase: &Testcase<S::Input>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
self.on_add(state, idx)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::unused_self)]
|
|
||||||
fn on_remove(
|
|
||||||
&mut self,
|
|
||||||
_state: &mut S,
|
|
||||||
_idx: CorpusId,
|
|
||||||
_testcase: &Option<Testcase<S::Input>>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_evaluation<OT>(
|
fn on_evaluation<OT>(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
@ -414,7 +383,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
let id = Self::schedule(state)?;
|
let id = Self::schedule(state)?;
|
||||||
*state.corpus_mut().current_mut() = Some(id);
|
self.set_current_scheduled(state, Some(id))?;
|
||||||
|
|
||||||
let mutation_num = state
|
let mutation_num = state
|
||||||
.corpus()
|
.corpus()
|
||||||
@ -439,6 +408,26 @@ where
|
|||||||
|
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set current fuzzed corpus id and `scheduled_count`
|
||||||
|
fn set_current_scheduled(
|
||||||
|
&mut self,
|
||||||
|
state: &mut Self::State,
|
||||||
|
next_idx: Option<CorpusId>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let current_idx = *state.corpus().current();
|
||||||
|
|
||||||
|
if let Some(idx) = current_idx {
|
||||||
|
let mut testcase = state.corpus().get(idx)?.borrow_mut();
|
||||||
|
let scheduled_count = testcase.scheduled_count();
|
||||||
|
|
||||||
|
// increase scheduled count, this was fuzz_level in afl
|
||||||
|
testcase.set_scheduled_count(scheduled_count + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
*state.corpus_mut().current_mut() = next_idx;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The weight for each corpus entry
|
/// The weight for each corpus entry
|
||||||
|
@ -13,7 +13,7 @@ use crate::{
|
|||||||
feedbacks::MapIndexesMetadata,
|
feedbacks::MapIndexesMetadata,
|
||||||
inputs::UsesInput,
|
inputs::UsesInput,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
schedulers::{LenTimeMulTestcaseScore, Scheduler, TestcaseScore},
|
schedulers::{LenTimeMulTestcaseScore, RemovableScheduler, Scheduler, TestcaseScore},
|
||||||
state::{HasCorpus, HasMetadata, HasRand, UsesState},
|
state::{HasCorpus, HasMetadata, HasRand, UsesState},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
@ -75,19 +75,13 @@ where
|
|||||||
type State = CS::State;
|
type State = CS::State;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<CS, F, M> Scheduler for MinimizerScheduler<CS, F, M>
|
impl<CS, F, M> RemovableScheduler for MinimizerScheduler<CS, F, M>
|
||||||
where
|
where
|
||||||
CS: Scheduler,
|
CS: RemovableScheduler,
|
||||||
F: TestcaseScore<CS::State>,
|
F: TestcaseScore<CS::State>,
|
||||||
M: AsSlice<Entry = usize> + SerdeAny + HasRefCnt,
|
M: AsSlice<Entry = usize> + SerdeAny + HasRefCnt,
|
||||||
CS::State: HasCorpus + HasMetadata + HasRand,
|
CS::State: HasCorpus + HasMetadata + HasRand,
|
||||||
{
|
{
|
||||||
/// Add an entry to the corpus and return its index
|
|
||||||
fn on_add(&mut self, state: &mut CS::State, idx: CorpusId) -> Result<(), Error> {
|
|
||||||
self.base.on_add(state, idx)?;
|
|
||||||
self.update_score(state, idx)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Replaces the testcase at the given idx
|
/// Replaces the testcase at the given idx
|
||||||
fn on_replace(
|
fn on_replace(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -162,6 +156,20 @@ where
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<CS, F, M> Scheduler for MinimizerScheduler<CS, F, M>
|
||||||
|
where
|
||||||
|
CS: Scheduler,
|
||||||
|
F: TestcaseScore<CS::State>,
|
||||||
|
M: AsSlice<Entry = usize> + SerdeAny + HasRefCnt,
|
||||||
|
CS::State: HasCorpus + HasMetadata + HasRand,
|
||||||
|
{
|
||||||
|
/// Add an entry to the corpus and return its index
|
||||||
|
fn on_add(&mut self, state: &mut CS::State, idx: CorpusId) -> Result<(), Error> {
|
||||||
|
self.base.on_add(state, idx)?;
|
||||||
|
self.update_score(state, idx)
|
||||||
|
}
|
||||||
|
|
||||||
/// An input has been evaluated
|
/// An input has been evaluated
|
||||||
fn on_evaluation<OT>(
|
fn on_evaluation<OT>(
|
||||||
@ -193,6 +201,16 @@ where
|
|||||||
}
|
}
|
||||||
Ok(idx)
|
Ok(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set current fuzzed corpus id and `scheduled_count`
|
||||||
|
fn set_current_scheduled(
|
||||||
|
&mut self,
|
||||||
|
_state: &mut Self::State,
|
||||||
|
_next_idx: Option<CorpusId>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
// We do nothing here, the inner scheduler will take care of it
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<CS, F, M> MinimizerScheduler<CS, F, M>
|
impl<CS, F, M> MinimizerScheduler<CS, F, M>
|
||||||
|
@ -42,11 +42,15 @@ use crate::{
|
|||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The scheduler define how the fuzzer requests a testcase from the corpus.
|
/// The scheduler also implemnts `on_remove` and `on_replace` if it implements this stage.
|
||||||
/// It has hooks to corpus add/replace/remove to allow complex scheduling algorithms to collect data.
|
pub trait RemovableScheduler: Scheduler {
|
||||||
pub trait Scheduler: UsesState {
|
/// Removed the given entry from the corpus at the given index
|
||||||
/// Added an entry to the corpus at the given index
|
fn on_remove(
|
||||||
fn on_add(&mut self, _state: &mut Self::State, _idx: CorpusId) -> Result<(), Error> {
|
&mut self,
|
||||||
|
_state: &mut Self::State,
|
||||||
|
_idx: CorpusId,
|
||||||
|
_testcase: &Option<Testcase<<Self::State as UsesInput>::Input>>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,17 +63,15 @@ pub trait Scheduler: UsesState {
|
|||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removed the given entry from the corpus at the given index
|
|
||||||
fn on_remove(
|
|
||||||
&mut self,
|
|
||||||
_state: &mut Self::State,
|
|
||||||
_idx: CorpusId,
|
|
||||||
_testcase: &Option<Testcase<<Self::State as UsesInput>::Input>>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The scheduler define how the fuzzer requests a testcase from the corpus.
|
||||||
|
/// It has hooks to corpus add/replace/remove to allow complex scheduling algorithms to collect data.
|
||||||
|
pub trait Scheduler: UsesState {
|
||||||
|
/// Added an entry to the corpus at the given index
|
||||||
|
fn on_add(&mut self, _state: &mut Self::State, _idx: CorpusId) -> Result<(), Error>;
|
||||||
|
// Add parent_id here if it has no inner
|
||||||
|
|
||||||
/// An input has been evaluated
|
/// An input has been evaluated
|
||||||
fn on_evaluation<OT>(
|
fn on_evaluation<OT>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -85,6 +87,14 @@ pub trait Scheduler: UsesState {
|
|||||||
|
|
||||||
/// Gets the next entry
|
/// Gets the next entry
|
||||||
fn next(&mut self, state: &mut Self::State) -> Result<CorpusId, Error>;
|
fn next(&mut self, state: &mut Self::State) -> Result<CorpusId, Error>;
|
||||||
|
// Increment corpus.current() here if it has no inner
|
||||||
|
|
||||||
|
/// Set current fuzzed corpus id and `scheduled_count`
|
||||||
|
fn set_current_scheduled(
|
||||||
|
&mut self,
|
||||||
|
state: &mut Self::State,
|
||||||
|
next_idx: Option<CorpusId>,
|
||||||
|
) -> Result<(), Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Feed the fuzzer simply with a random testcase on request
|
/// Feed the fuzzer simply with a random testcase on request
|
||||||
@ -104,16 +114,38 @@ impl<S> Scheduler for RandScheduler<S>
|
|||||||
where
|
where
|
||||||
S: HasCorpus + HasRand,
|
S: HasCorpus + HasRand,
|
||||||
{
|
{
|
||||||
|
fn on_add(&mut self, state: &mut Self::State, idx: CorpusId) -> Result<(), Error> {
|
||||||
|
// Set parent id
|
||||||
|
let current_idx = *state.corpus().current();
|
||||||
|
state
|
||||||
|
.corpus()
|
||||||
|
.get(idx)?
|
||||||
|
.borrow_mut()
|
||||||
|
.set_parent_id_optional(current_idx);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets the next entry at random
|
/// Gets the next entry at random
|
||||||
fn next(&mut self, state: &mut Self::State) -> Result<CorpusId, Error> {
|
fn next(&mut self, state: &mut Self::State) -> Result<CorpusId, Error> {
|
||||||
if state.corpus().count() == 0 {
|
if state.corpus().count() == 0 {
|
||||||
Err(Error::empty("No entries in corpus".to_owned()))
|
Err(Error::empty("No entries in corpus".to_owned()))
|
||||||
} else {
|
} else {
|
||||||
let id = random_corpus_id!(state.corpus(), state.rand_mut());
|
let id = random_corpus_id!(state.corpus(), state.rand_mut());
|
||||||
*state.corpus_mut().current_mut() = Some(id);
|
self.set_current_scheduled(state, Some(id))?;
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set current fuzzed corpus id and `scheduled_count`. You should call this from `next`
|
||||||
|
fn set_current_scheduled(
|
||||||
|
&mut self,
|
||||||
|
state: &mut Self::State,
|
||||||
|
next_idx: Option<CorpusId>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
*state.corpus_mut().current_mut() = next_idx;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> RandScheduler<S> {
|
impl<S> RandScheduler<S> {
|
||||||
|
@ -12,7 +12,7 @@ use crate::{
|
|||||||
corpus::{Corpus, CorpusId, SchedulerTestcaseMetaData, Testcase},
|
corpus::{Corpus, CorpusId, SchedulerTestcaseMetaData, Testcase},
|
||||||
inputs::UsesInput,
|
inputs::UsesInput,
|
||||||
observers::{MapObserver, ObserversTuple},
|
observers::{MapObserver, ObserversTuple},
|
||||||
schedulers::Scheduler,
|
schedulers::{RemovableScheduler, Scheduler},
|
||||||
state::{HasCorpus, HasMetadata, UsesState},
|
state::{HasCorpus, HasMetadata, UsesState},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
@ -178,40 +178,11 @@ where
|
|||||||
type State = S;
|
type State = S;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O, S> Scheduler for PowerQueueScheduler<O, S>
|
impl<O, S> RemovableScheduler for PowerQueueScheduler<O, S>
|
||||||
where
|
where
|
||||||
S: HasCorpus + HasMetadata,
|
S: HasCorpus + HasMetadata,
|
||||||
O: MapObserver,
|
O: MapObserver,
|
||||||
{
|
{
|
||||||
/// Add an entry to the corpus and return its index
|
|
||||||
fn on_add(&mut self, state: &mut Self::State, idx: CorpusId) -> Result<(), Error> {
|
|
||||||
let current_idx = *state.corpus().current();
|
|
||||||
|
|
||||||
let mut depth = match current_idx {
|
|
||||||
Some(parent_idx) => state
|
|
||||||
.corpus()
|
|
||||||
.get(parent_idx)?
|
|
||||||
.borrow()
|
|
||||||
.metadata()
|
|
||||||
.get::<SchedulerTestcaseMetaData>()
|
|
||||||
.ok_or_else(|| {
|
|
||||||
Error::key_not_found("SchedulerTestcaseMetaData not found".to_string())
|
|
||||||
})?
|
|
||||||
.depth(),
|
|
||||||
None => 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO increase perf_score when finding new things like in AFL
|
|
||||||
// https://github.com/google/AFL/blob/master/afl-fuzz.c#L6547
|
|
||||||
|
|
||||||
// Attach a `SchedulerTestcaseMetaData` to the queue entry.
|
|
||||||
depth += 1;
|
|
||||||
state.corpus().get(idx)?.borrow_mut().add_metadata(
|
|
||||||
SchedulerTestcaseMetaData::with_n_fuzz_entry(depth, self.last_hash),
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::cast_precision_loss)]
|
#[allow(clippy::cast_precision_loss)]
|
||||||
fn on_replace(
|
fn on_replace(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -292,6 +263,44 @@ where
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<O, S> Scheduler for PowerQueueScheduler<O, S>
|
||||||
|
where
|
||||||
|
S: HasCorpus + HasMetadata,
|
||||||
|
O: MapObserver,
|
||||||
|
{
|
||||||
|
/// Add an entry to the corpus and return its index
|
||||||
|
fn on_add(&mut self, state: &mut Self::State, idx: CorpusId) -> Result<(), Error> {
|
||||||
|
let current_idx = *state.corpus().current();
|
||||||
|
|
||||||
|
let mut depth = match current_idx {
|
||||||
|
Some(parent_idx) => state
|
||||||
|
.corpus()
|
||||||
|
.get(parent_idx)?
|
||||||
|
.borrow()
|
||||||
|
.metadata()
|
||||||
|
.get::<SchedulerTestcaseMetaData>()
|
||||||
|
.ok_or_else(|| {
|
||||||
|
Error::key_not_found("SchedulerTestcaseMetaData not found".to_string())
|
||||||
|
})?
|
||||||
|
.depth(),
|
||||||
|
None => 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO increase perf_score when finding new things like in AFL
|
||||||
|
// https://github.com/google/AFL/blob/master/afl-fuzz.c#L6547
|
||||||
|
|
||||||
|
// Attach a `SchedulerTestcaseMetaData` to the queue entry.
|
||||||
|
depth += 1;
|
||||||
|
let mut testcase = state.corpus().get(idx)?.borrow_mut();
|
||||||
|
testcase.add_metadata(SchedulerTestcaseMetaData::with_n_fuzz_entry(
|
||||||
|
depth,
|
||||||
|
self.last_hash,
|
||||||
|
));
|
||||||
|
testcase.set_parent_id_optional(current_idx);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn on_evaluation<OT>(
|
fn on_evaluation<OT>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -343,10 +352,27 @@ where
|
|||||||
}
|
}
|
||||||
None => state.corpus().first().unwrap(),
|
None => state.corpus().first().unwrap(),
|
||||||
};
|
};
|
||||||
*state.corpus_mut().current_mut() = Some(id);
|
self.set_current_scheduled(state, Some(id))?;
|
||||||
|
|
||||||
|
Ok(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set current fuzzed corpus id and `scheduled_count`
|
||||||
|
fn set_current_scheduled(
|
||||||
|
&mut self,
|
||||||
|
state: &mut Self::State,
|
||||||
|
next_idx: Option<CorpusId>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let current_idx = *state.corpus().current();
|
||||||
|
|
||||||
|
if let Some(idx) = current_idx {
|
||||||
|
let mut testcase = state.corpus().get(idx)?.borrow_mut();
|
||||||
|
let scheduled_count = testcase.scheduled_count();
|
||||||
|
|
||||||
|
// increase scheduled count, this was fuzz_level in afl
|
||||||
|
testcase.set_scheduled_count(scheduled_count + 1);
|
||||||
|
|
||||||
// Update the handicap
|
|
||||||
let mut testcase = state.corpus().get(id)?.borrow_mut();
|
|
||||||
let tcmeta = testcase
|
let tcmeta = testcase
|
||||||
.metadata_mut()
|
.metadata_mut()
|
||||||
.get_mut::<SchedulerTestcaseMetaData>()
|
.get_mut::<SchedulerTestcaseMetaData>()
|
||||||
@ -359,9 +385,10 @@ where
|
|||||||
} else if tcmeta.handicap() > 0 {
|
} else if tcmeta.handicap() > 0 {
|
||||||
tcmeta.set_handicap(tcmeta.handicap() - 1);
|
tcmeta.set_handicap(tcmeta.handicap() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*state.corpus_mut().current_mut() = next_idx;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,6 +100,13 @@ where
|
|||||||
S: HasCorpus + HasMetadata + HasRand,
|
S: HasCorpus + HasMetadata + HasRand,
|
||||||
{
|
{
|
||||||
fn on_add(&mut self, state: &mut Self::State, idx: CorpusId) -> Result<(), Error> {
|
fn on_add(&mut self, state: &mut Self::State, idx: CorpusId) -> Result<(), Error> {
|
||||||
|
let current_idx = *state.corpus().current();
|
||||||
|
state
|
||||||
|
.corpus()
|
||||||
|
.get(idx)?
|
||||||
|
.borrow_mut()
|
||||||
|
.set_parent_id_optional(current_idx);
|
||||||
|
|
||||||
if state.metadata().get::<ProbabilityMetadata>().is_none() {
|
if state.metadata().get::<ProbabilityMetadata>().is_none() {
|
||||||
state.add_metadata(ProbabilityMetadata::new());
|
state.add_metadata(ProbabilityMetadata::new());
|
||||||
}
|
}
|
||||||
@ -124,10 +131,20 @@ where
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*state.corpus_mut().current_mut() = Some(ret);
|
self.set_current_scheduled(state, Some(ret))?;
|
||||||
Ok(ret)
|
Ok(ret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set current fuzzed corpus id and `scheduled_count`
|
||||||
|
fn set_current_scheduled(
|
||||||
|
&mut self,
|
||||||
|
state: &mut Self::State,
|
||||||
|
next_idx: Option<CorpusId>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
*state.corpus_mut().current_mut() = next_idx;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, S> Default for ProbabilitySamplingScheduler<F, S>
|
impl<F, S> Default for ProbabilitySamplingScheduler<F, S>
|
||||||
|
@ -6,7 +6,7 @@ use core::marker::PhantomData;
|
|||||||
use crate::{
|
use crate::{
|
||||||
corpus::{Corpus, CorpusId},
|
corpus::{Corpus, CorpusId},
|
||||||
inputs::UsesInput,
|
inputs::UsesInput,
|
||||||
schedulers::Scheduler,
|
schedulers::{RemovableScheduler, Scheduler},
|
||||||
state::{HasCorpus, UsesState},
|
state::{HasCorpus, UsesState},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
@ -24,10 +24,24 @@ where
|
|||||||
type State = S;
|
type State = S;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S> RemovableScheduler for QueueScheduler<S> where S: HasCorpus {}
|
||||||
|
|
||||||
impl<S> Scheduler for QueueScheduler<S>
|
impl<S> Scheduler for QueueScheduler<S>
|
||||||
where
|
where
|
||||||
S: HasCorpus,
|
S: HasCorpus,
|
||||||
{
|
{
|
||||||
|
fn on_add(&mut self, state: &mut Self::State, idx: CorpusId) -> Result<(), Error> {
|
||||||
|
// Set parent id
|
||||||
|
let current_idx = *state.corpus().current();
|
||||||
|
state
|
||||||
|
.corpus()
|
||||||
|
.get(idx)?
|
||||||
|
.borrow_mut()
|
||||||
|
.set_parent_id_optional(current_idx);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets the next entry in the queue
|
/// Gets the next entry in the queue
|
||||||
fn next(&mut self, state: &mut Self::State) -> Result<CorpusId, Error> {
|
fn next(&mut self, state: &mut Self::State) -> Result<CorpusId, Error> {
|
||||||
if state.corpus().count() == 0 {
|
if state.corpus().count() == 0 {
|
||||||
@ -39,10 +53,20 @@ where
|
|||||||
.map(|id| state.corpus().next(id))
|
.map(|id| state.corpus().next(id))
|
||||||
.flatten()
|
.flatten()
|
||||||
.unwrap_or_else(|| state.corpus().first().unwrap());
|
.unwrap_or_else(|| state.corpus().first().unwrap());
|
||||||
*state.corpus_mut().current_mut() = Some(id);
|
self.set_current_scheduled(state, Some(id))?;
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set current fuzzed corpus id and `scheduled_count`
|
||||||
|
fn set_current_scheduled(
|
||||||
|
&mut self,
|
||||||
|
state: &mut Self::State,
|
||||||
|
next_idx: Option<CorpusId>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
*state.corpus_mut().current_mut() = next_idx;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> QueueScheduler<S> {
|
impl<S> QueueScheduler<S> {
|
||||||
|
@ -205,7 +205,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
PowerSchedule::FAST => {
|
PowerSchedule::FAST => {
|
||||||
if entry.fuzz_level() != 0 {
|
if entry.scheduled_count() != 0 {
|
||||||
let lg = libm::log2(f64::from(psmeta.n_fuzz()[tcmeta.n_fuzz_entry()]));
|
let lg = libm::log2(f64::from(psmeta.n_fuzz()[tcmeta.n_fuzz_entry()]));
|
||||||
|
|
||||||
match lg {
|
match lg {
|
||||||
@ -244,11 +244,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
PowerSchedule::LIN => {
|
PowerSchedule::LIN => {
|
||||||
factor = (entry.fuzz_level() as f64)
|
factor = (entry.scheduled_count() as f64)
|
||||||
/ f64::from(psmeta.n_fuzz()[tcmeta.n_fuzz_entry()] + 1);
|
/ f64::from(psmeta.n_fuzz()[tcmeta.n_fuzz_entry()] + 1);
|
||||||
}
|
}
|
||||||
PowerSchedule::QUAD => {
|
PowerSchedule::QUAD => {
|
||||||
factor = ((entry.fuzz_level() * entry.fuzz_level()) as f64)
|
factor = ((entry.scheduled_count() * entry.scheduled_count()) as f64)
|
||||||
/ f64::from(psmeta.n_fuzz()[tcmeta.n_fuzz_entry()] + 1);
|
/ f64::from(psmeta.n_fuzz()[tcmeta.n_fuzz_entry()] + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -310,7 +310,7 @@ where
|
|||||||
// This means that this testcase has never gone through the calibration stage before1,
|
// This means that this testcase has never gone through the calibration stage before1,
|
||||||
// In this case we'll just return the default weight
|
// In this case we'll just return the default weight
|
||||||
// This methoud is called in corpus's on_add() method. Fuzz_level is zero at that time.
|
// This methoud is called in corpus's on_add() method. Fuzz_level is zero at that time.
|
||||||
if entry.fuzz_level() == 0 || psmeta.cycles() == 0 {
|
if entry.scheduled_count() == 0 || psmeta.cycles() == 0 {
|
||||||
return Ok(weight);
|
return Ok(weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,7 +362,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// was it fuzzed before?
|
// was it fuzzed before?
|
||||||
if entry.fuzz_level() == 0 {
|
if entry.scheduled_count() == 0 {
|
||||||
weight *= 2.0;
|
weight *= 2.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ use core::marker::PhantomData;
|
|||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use super::RemovableScheduler;
|
||||||
use crate::{
|
use crate::{
|
||||||
corpus::{Corpus, CorpusId},
|
corpus::{Corpus, CorpusId},
|
||||||
impl_serdeany,
|
impl_serdeany,
|
||||||
@ -88,10 +89,24 @@ where
|
|||||||
type State = S;
|
type State = S;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S> RemovableScheduler for TuneableScheduler<S> where S: HasCorpus + HasMetadata {}
|
||||||
|
|
||||||
impl<S> Scheduler for TuneableScheduler<S>
|
impl<S> Scheduler for TuneableScheduler<S>
|
||||||
where
|
where
|
||||||
S: HasCorpus + HasMetadata,
|
S: HasCorpus + HasMetadata,
|
||||||
{
|
{
|
||||||
|
fn on_add(&mut self, state: &mut Self::State, idx: CorpusId) -> Result<(), Error> {
|
||||||
|
// Set parent id
|
||||||
|
let current_idx = *state.corpus().current();
|
||||||
|
state
|
||||||
|
.corpus()
|
||||||
|
.get(idx)?
|
||||||
|
.borrow_mut()
|
||||||
|
.set_parent_id_optional(current_idx);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets the next entry in the queue
|
/// Gets the next entry in the queue
|
||||||
fn next(&mut self, state: &mut Self::State) -> Result<CorpusId, Error> {
|
fn next(&mut self, state: &mut Self::State) -> Result<CorpusId, Error> {
|
||||||
if state.corpus().count() == 0 {
|
if state.corpus().count() == 0 {
|
||||||
@ -105,7 +120,17 @@ where
|
|||||||
} else {
|
} else {
|
||||||
state.corpus().first().unwrap()
|
state.corpus().first().unwrap()
|
||||||
};
|
};
|
||||||
*state.corpus_mut().current_mut() = Some(id);
|
self.set_current_scheduled(state, Some(id))?;
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set current fuzzed corpus id and `scheduled_count`
|
||||||
|
fn set_current_scheduled(
|
||||||
|
&mut self,
|
||||||
|
state: &mut Self::State,
|
||||||
|
next_idx: Option<CorpusId>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
*state.corpus_mut().current_mut() = next_idx;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,14 +9,14 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::rands::Rand,
|
bolts::rands::Rand,
|
||||||
corpus::{Corpus, CorpusId, SchedulerTestcaseMetaData, Testcase},
|
corpus::{Corpus, CorpusId, SchedulerTestcaseMetaData},
|
||||||
inputs::UsesInput,
|
inputs::UsesInput,
|
||||||
observers::{MapObserver, ObserversTuple},
|
observers::{MapObserver, ObserversTuple},
|
||||||
random_corpus_id,
|
random_corpus_id,
|
||||||
schedulers::{
|
schedulers::{
|
||||||
powersched::{PowerSchedule, SchedulerMetadata},
|
powersched::{PowerSchedule, SchedulerMetadata},
|
||||||
testcase_score::{CorpusWeightTestcaseScore, TestcaseScore},
|
testcase_score::{CorpusWeightTestcaseScore, TestcaseScore},
|
||||||
Scheduler,
|
RemovableScheduler, Scheduler,
|
||||||
},
|
},
|
||||||
state::{HasCorpus, HasMetadata, HasRand, UsesState},
|
state::{HasCorpus, HasMetadata, HasRand, UsesState},
|
||||||
Error,
|
Error,
|
||||||
@ -229,6 +229,94 @@ where
|
|||||||
type State = S;
|
type State = S;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<F, O, S> RemovableScheduler for WeightedScheduler<F, O, S>
|
||||||
|
where
|
||||||
|
F: TestcaseScore<S>,
|
||||||
|
O: MapObserver,
|
||||||
|
S: HasCorpus + HasMetadata + HasRand,
|
||||||
|
{
|
||||||
|
#[allow(clippy::cast_precision_loss)]
|
||||||
|
fn on_remove(
|
||||||
|
&mut self,
|
||||||
|
state: &mut Self::State,
|
||||||
|
_idx: CorpusId,
|
||||||
|
prev: &Option<crate::corpus::Testcase<<Self::State as UsesInput>::Input>>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let prev = prev.as_ref().ok_or_else(|| {
|
||||||
|
Error::illegal_argument(
|
||||||
|
"Power schedulers must be aware of the removed corpus entry for reweighting.",
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let prev_meta = prev
|
||||||
|
.metadata()
|
||||||
|
.get::<SchedulerTestcaseMetaData>()
|
||||||
|
.ok_or_else(|| {
|
||||||
|
Error::key_not_found("SchedulerTestcaseMetaData not found".to_string())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// Use these to adjust `SchedulerMetadata`
|
||||||
|
let (prev_total_time, prev_cycles) = prev_meta.cycle_and_time();
|
||||||
|
let prev_bitmap_size = prev_meta.bitmap_size();
|
||||||
|
let prev_bitmap_size_log = libm::log2(prev_bitmap_size as f64);
|
||||||
|
|
||||||
|
let psmeta = state
|
||||||
|
.metadata_mut()
|
||||||
|
.get_mut::<SchedulerMetadata>()
|
||||||
|
.ok_or_else(|| Error::key_not_found("SchedulerMetadata not found".to_string()))?;
|
||||||
|
|
||||||
|
psmeta.set_exec_time(psmeta.exec_time() - prev_total_time);
|
||||||
|
psmeta.set_cycles(psmeta.cycles() - (prev_cycles as u64));
|
||||||
|
psmeta.set_bitmap_size(psmeta.bitmap_size() - prev_bitmap_size);
|
||||||
|
psmeta.set_bitmap_size_log(psmeta.bitmap_size_log() - prev_bitmap_size_log);
|
||||||
|
psmeta.set_bitmap_entries(psmeta.bitmap_entries() - 1);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::cast_precision_loss)]
|
||||||
|
fn on_replace(
|
||||||
|
&mut self,
|
||||||
|
state: &mut Self::State,
|
||||||
|
idx: CorpusId,
|
||||||
|
prev: &crate::corpus::Testcase<<Self::State as UsesInput>::Input>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let prev_meta = prev
|
||||||
|
.metadata()
|
||||||
|
.get::<SchedulerTestcaseMetaData>()
|
||||||
|
.ok_or_else(|| {
|
||||||
|
Error::key_not_found("SchedulerTestcaseMetaData not found".to_string())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// Next depth is + 1
|
||||||
|
let prev_depth = prev_meta.depth() + 1;
|
||||||
|
|
||||||
|
// Use these to adjust `SchedulerMetadata`
|
||||||
|
let (prev_total_time, prev_cycles) = prev_meta.cycle_and_time();
|
||||||
|
let prev_bitmap_size = prev_meta.bitmap_size();
|
||||||
|
let prev_bitmap_size_log = libm::log2(prev_bitmap_size as f64);
|
||||||
|
|
||||||
|
let psmeta = state
|
||||||
|
.metadata_mut()
|
||||||
|
.get_mut::<SchedulerMetadata>()
|
||||||
|
.ok_or_else(|| Error::key_not_found("SchedulerMetadata not found".to_string()))?;
|
||||||
|
|
||||||
|
// We won't add new one because it'll get added when it gets executed in calirbation next time.
|
||||||
|
psmeta.set_exec_time(psmeta.exec_time() - prev_total_time);
|
||||||
|
psmeta.set_cycles(psmeta.cycles() - (prev_cycles as u64));
|
||||||
|
psmeta.set_bitmap_size(psmeta.bitmap_size() - prev_bitmap_size);
|
||||||
|
psmeta.set_bitmap_size_log(psmeta.bitmap_size_log() - prev_bitmap_size_log);
|
||||||
|
psmeta.set_bitmap_entries(psmeta.bitmap_entries() - 1);
|
||||||
|
|
||||||
|
state
|
||||||
|
.corpus()
|
||||||
|
.get(idx)?
|
||||||
|
.borrow_mut()
|
||||||
|
.add_metadata(SchedulerTestcaseMetaData::new(prev_depth));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<F, O, S> Scheduler for WeightedScheduler<F, O, S>
|
impl<F, O, S> Scheduler for WeightedScheduler<F, O, S>
|
||||||
where
|
where
|
||||||
F: TestcaseScore<S>,
|
F: TestcaseScore<S>,
|
||||||
@ -255,9 +343,14 @@ where
|
|||||||
|
|
||||||
// Attach a `SchedulerTestcaseMetaData` to the queue entry.
|
// Attach a `SchedulerTestcaseMetaData` to the queue entry.
|
||||||
depth += 1;
|
depth += 1;
|
||||||
state.corpus().get(idx)?.borrow_mut().add_metadata(
|
{
|
||||||
SchedulerTestcaseMetaData::with_n_fuzz_entry(depth, self.last_hash),
|
let mut testcase = state.corpus().get(idx)?.borrow_mut();
|
||||||
);
|
testcase.add_metadata(SchedulerTestcaseMetaData::with_n_fuzz_entry(
|
||||||
|
depth,
|
||||||
|
self.last_hash,
|
||||||
|
));
|
||||||
|
testcase.set_parent_id_optional(current_idx);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO increase perf_score when finding new things like in AFL
|
// TODO increase perf_score when finding new things like in AFL
|
||||||
// https://github.com/google/AFL/blob/master/afl-fuzz.c#L6547
|
// https://github.com/google/AFL/blob/master/afl-fuzz.c#L6547
|
||||||
@ -267,27 +360,6 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_replace(
|
|
||||||
&mut self,
|
|
||||||
state: &mut S,
|
|
||||||
idx: CorpusId,
|
|
||||||
_testcase: &Testcase<S::Input>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
// Recreate the alias table
|
|
||||||
self.on_add(state, idx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_remove(
|
|
||||||
&mut self,
|
|
||||||
state: &mut S,
|
|
||||||
_idx: CorpusId,
|
|
||||||
_testcase: &Option<Testcase<S::Input>>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
// Recreate the alias table
|
|
||||||
self.create_alias_table(state)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_evaluation<OT>(
|
fn on_evaluation<OT>(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
@ -360,10 +432,27 @@ where
|
|||||||
})?;
|
})?;
|
||||||
psmeta.set_queue_cycles(psmeta.queue_cycles() + 1);
|
psmeta.set_queue_cycles(psmeta.queue_cycles() + 1);
|
||||||
}
|
}
|
||||||
*state.corpus_mut().current_mut() = Some(idx);
|
|
||||||
|
|
||||||
// Update the handicap
|
self.set_current_scheduled(state, Some(idx))?;
|
||||||
|
Ok(idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set current fuzzed corpus id and `scheduled_count`
|
||||||
|
fn set_current_scheduled(
|
||||||
|
&mut self,
|
||||||
|
state: &mut Self::State,
|
||||||
|
next_idx: Option<CorpusId>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let current_idx = *state.corpus().current();
|
||||||
|
|
||||||
|
if let Some(idx) = current_idx {
|
||||||
let mut testcase = state.corpus().get(idx)?.borrow_mut();
|
let mut testcase = state.corpus().get(idx)?.borrow_mut();
|
||||||
|
let scheduled_count = testcase.scheduled_count();
|
||||||
|
|
||||||
|
// increase scheduled count, this was fuzz_level in afl
|
||||||
|
testcase.set_scheduled_count(scheduled_count + 1);
|
||||||
|
|
||||||
let tcmeta = testcase
|
let tcmeta = testcase
|
||||||
.metadata_mut()
|
.metadata_mut()
|
||||||
.get_mut::<SchedulerTestcaseMetaData>()
|
.get_mut::<SchedulerTestcaseMetaData>()
|
||||||
@ -376,8 +465,10 @@ where
|
|||||||
} else if tcmeta.handicap() > 0 {
|
} else if tcmeta.handicap() > 0 {
|
||||||
tcmeta.set_handicap(tcmeta.handicap() - 1);
|
tcmeta.set_handicap(tcmeta.handicap() - 1);
|
||||||
}
|
}
|
||||||
Ok(idx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*state.corpus_mut().current_mut() = next_idx;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,9 @@ where
|
|||||||
// Run this stage only once for each corpus entry and only if we haven't already inspected it
|
// Run this stage only once for each corpus entry and only if we haven't already inspected it
|
||||||
{
|
{
|
||||||
let corpus = state.corpus().get(corpus_idx)?.borrow();
|
let corpus = state.corpus().get(corpus_idx)?.borrow();
|
||||||
if corpus.fuzz_level() > 0 {
|
// println!("calibration; corpus.scheduled_count() : {}", corpus.scheduled_count());
|
||||||
|
|
||||||
|
if corpus.scheduled_count() > 0 {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -269,10 +271,10 @@ where
|
|||||||
psmeta.set_bitmap_entries(psmeta.bitmap_entries() + 1);
|
psmeta.set_bitmap_entries(psmeta.bitmap_entries() + 1);
|
||||||
|
|
||||||
let mut testcase = state.corpus().get(corpus_idx)?.borrow_mut();
|
let mut testcase = state.corpus().get(corpus_idx)?.borrow_mut();
|
||||||
let fuzz_level = testcase.fuzz_level();
|
let scheduled_count = testcase.scheduled_count();
|
||||||
|
|
||||||
testcase.set_exec_time(total_time / (iter as u32));
|
testcase.set_exec_time(total_time / (iter as u32));
|
||||||
testcase.set_fuzz_level(fuzz_level + 1);
|
testcase.set_scheduled_count(scheduled_count + 1);
|
||||||
// log::trace!("time: {:#?}", testcase.exec_time());
|
// log::trace!("time: {:#?}", testcase.exec_time());
|
||||||
|
|
||||||
let data = testcase
|
let data = testcase
|
||||||
|
@ -21,9 +21,7 @@ use crate::{
|
|||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
schedulers::Scheduler,
|
schedulers::Scheduler,
|
||||||
start_timer,
|
start_timer,
|
||||||
state::{
|
state::{HasClientPerfMonitor, HasCorpus, HasExecutions, HasMetadata, HasRand},
|
||||||
HasClientPerfMonitor, HasCorpus, HasExecutions, HasFuzzedCorpusId, HasMetadata, HasRand,
|
|
||||||
},
|
|
||||||
Error, EvaluatorObservers, ExecutionProcessor, HasScheduler,
|
Error, EvaluatorObservers, ExecutionProcessor, HasScheduler,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -90,14 +88,8 @@ where
|
|||||||
EM: EventFirer<State = CS::State> + EventRestarter + HasEventManagerId + ProgressReporter,
|
EM: EventFirer<State = CS::State> + EventRestarter + HasEventManagerId + ProgressReporter,
|
||||||
M: Mutator<CS::Input, CS::State>,
|
M: Mutator<CS::Input, CS::State>,
|
||||||
OT: ObserversTuple<CS::State>,
|
OT: ObserversTuple<CS::State>,
|
||||||
CS::State: HasFuzzedCorpusId
|
CS::State:
|
||||||
+ HasClientPerfMonitor
|
HasClientPerfMonitor + HasCorpus + HasRand + HasExecutions + HasMetadata + Clone + Debug,
|
||||||
+ HasCorpus
|
|
||||||
+ HasRand
|
|
||||||
+ HasExecutions
|
|
||||||
+ HasMetadata
|
|
||||||
+ Clone
|
|
||||||
+ Debug,
|
|
||||||
Z: ExecutionProcessor<OT, State = CS::State>
|
Z: ExecutionProcessor<OT, State = CS::State>
|
||||||
+ EvaluatorObservers<OT>
|
+ EvaluatorObservers<OT>
|
||||||
+ HasScheduler<Scheduler = CS>,
|
+ HasScheduler<Scheduler = CS>,
|
||||||
@ -144,8 +136,6 @@ where
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let idx = self.current_corpus_idx.unwrap();
|
|
||||||
state.set_fuzzed_corpus_id(idx);
|
|
||||||
start_timer!(state);
|
start_timer!(state);
|
||||||
let mut input = state
|
let mut input = state
|
||||||
.corpus()
|
.corpus()
|
||||||
@ -188,7 +178,6 @@ where
|
|||||||
.post_exec(state, self.stage_idx, self.current_corpus_idx)?;
|
.post_exec(state, self.stage_idx, self.current_corpus_idx)?;
|
||||||
mark_feature_time!(state, PerfFeature::MutatePostExec);
|
mark_feature_time!(state, PerfFeature::MutatePostExec);
|
||||||
self.testcases_done += 1;
|
self.testcases_done += 1;
|
||||||
state.clear_fuzzed_corpus_id();
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -212,14 +201,8 @@ where
|
|||||||
EM: EventFirer + EventRestarter + HasEventManagerId + ProgressReporter<State = CS::State>,
|
EM: EventFirer + EventRestarter + HasEventManagerId + ProgressReporter<State = CS::State>,
|
||||||
M: Mutator<CS::Input, CS::State>,
|
M: Mutator<CS::Input, CS::State>,
|
||||||
OT: ObserversTuple<CS::State>,
|
OT: ObserversTuple<CS::State>,
|
||||||
CS::State: HasClientPerfMonitor
|
CS::State:
|
||||||
+ HasCorpus
|
HasClientPerfMonitor + HasCorpus + HasRand + HasExecutions + HasMetadata + Clone + Debug,
|
||||||
+ HasRand
|
|
||||||
+ HasExecutions
|
|
||||||
+ HasMetadata
|
|
||||||
+ Clone
|
|
||||||
+ Debug
|
|
||||||
+ HasFuzzedCorpusId,
|
|
||||||
Z: ExecutionProcessor<OT, State = CS::State>
|
Z: ExecutionProcessor<OT, State = CS::State>
|
||||||
+ EvaluatorObservers<OT>
|
+ EvaluatorObservers<OT>
|
||||||
+ HasScheduler<Scheduler = CS>,
|
+ HasScheduler<Scheduler = CS>,
|
||||||
|
@ -21,7 +21,7 @@ use crate::{
|
|||||||
mark_feature_time,
|
mark_feature_time,
|
||||||
mutators::Mutator,
|
mutators::Mutator,
|
||||||
observers::{MapObserver, ObserversTuple},
|
observers::{MapObserver, ObserversTuple},
|
||||||
schedulers::Scheduler,
|
schedulers::{RemovableScheduler, Scheduler},
|
||||||
stages::Stage,
|
stages::Stage,
|
||||||
start_timer,
|
start_timer,
|
||||||
state::{HasClientPerfMonitor, HasCorpus, HasExecutions, HasMaxSize, HasSolutions, UsesState},
|
state::{HasClientPerfMonitor, HasCorpus, HasExecutions, HasMaxSize, HasSolutions, UsesState},
|
||||||
@ -36,7 +36,7 @@ pub trait TMinMutationalStage<CS, E, EM, F1, F2, M, OT, Z>:
|
|||||||
where
|
where
|
||||||
Self::State: HasCorpus + HasSolutions + HasExecutions + HasMaxSize + HasClientPerfMonitor,
|
Self::State: HasCorpus + HasSolutions + HasExecutions + HasMaxSize + HasClientPerfMonitor,
|
||||||
<Self::State as UsesInput>::Input: HasLen + Hash,
|
<Self::State as UsesInput>::Input: HasLen + Hash,
|
||||||
CS: Scheduler<State = Self::State>,
|
CS: Scheduler<State = Self::State> + RemovableScheduler,
|
||||||
E: Executor<EM, Z> + HasObservers<Observers = OT, State = Self::State>,
|
E: Executor<EM, Z> + HasObservers<Observers = OT, State = Self::State>,
|
||||||
EM: EventFirer<State = Self::State>,
|
EM: EventFirer<State = Self::State>,
|
||||||
F1: Feedback<Self::State>,
|
F1: Feedback<Self::State>,
|
||||||
@ -204,7 +204,7 @@ where
|
|||||||
impl<CS, E, EM, F1, F2, FF, M, OT, Z> Stage<E, EM, Z>
|
impl<CS, E, EM, F1, F2, FF, M, OT, Z> Stage<E, EM, Z>
|
||||||
for StdTMinMutationalStage<CS, E, EM, F1, F2, FF, M, OT, Z>
|
for StdTMinMutationalStage<CS, E, EM, F1, F2, FF, M, OT, Z>
|
||||||
where
|
where
|
||||||
CS: Scheduler,
|
CS: Scheduler + RemovableScheduler,
|
||||||
CS::State: HasCorpus + HasSolutions + HasExecutions + HasMaxSize + HasClientPerfMonitor,
|
CS::State: HasCorpus + HasSolutions + HasExecutions + HasMaxSize + HasClientPerfMonitor,
|
||||||
<CS::State as UsesInput>::Input: HasLen + Hash,
|
<CS::State as UsesInput>::Input: HasLen + Hash,
|
||||||
E: Executor<EM, Z> + HasObservers<Observers = OT, State = CS::State>,
|
E: Executor<EM, Z> + HasObservers<Observers = OT, State = CS::State>,
|
||||||
@ -252,7 +252,7 @@ where
|
|||||||
impl<CS, E, EM, F1, F2, FF, M, OT, Z> TMinMutationalStage<CS, E, EM, F1, F2, M, OT, Z>
|
impl<CS, E, EM, F1, F2, FF, M, OT, Z> TMinMutationalStage<CS, E, EM, F1, F2, M, OT, Z>
|
||||||
for StdTMinMutationalStage<CS, E, EM, F1, F2, FF, M, OT, Z>
|
for StdTMinMutationalStage<CS, E, EM, F1, F2, FF, M, OT, Z>
|
||||||
where
|
where
|
||||||
CS: Scheduler,
|
CS: Scheduler + RemovableScheduler,
|
||||||
E: HasObservers<Observers = OT, State = CS::State> + Executor<EM, Z>,
|
E: HasObservers<Observers = OT, State = CS::State> + Executor<EM, Z>,
|
||||||
EM: EventFirer<State = CS::State>,
|
EM: EventFirer<State = CS::State>,
|
||||||
F1: Feedback<CS::State>,
|
F1: Feedback<CS::State>,
|
||||||
|
@ -60,21 +60,6 @@ pub trait HasCorpus: UsesInput {
|
|||||||
fn corpus_mut(&mut self) -> &mut Self::Corpus;
|
fn corpus_mut(&mut self) -> &mut Self::Corpus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for a state that has information about which [`CorpusId`]
|
|
||||||
/// is currently being fuzzed.
|
|
||||||
/// When a new interesting input was found, this value becomes the `parent_id`.
|
|
||||||
pub trait HasFuzzedCorpusId {
|
|
||||||
/// The currently fuzzed [`CorpusId`], if known.
|
|
||||||
/// If a new interesting testcase was found, this should usually become the `parent_id`.
|
|
||||||
fn fuzzed_corpus_id(&self) -> Option<CorpusId>;
|
|
||||||
|
|
||||||
/// Sets the currently fuzzed [`CorpusId`].
|
|
||||||
fn set_fuzzed_corpus_id(&mut self, corpus_id: CorpusId);
|
|
||||||
|
|
||||||
/// Resets the currently fuzzed [`CorpusId`].
|
|
||||||
fn clear_fuzzed_corpus_id(&mut self);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Interact with the maximum size
|
/// Interact with the maximum size
|
||||||
pub trait HasMaxSize {
|
pub trait HasMaxSize {
|
||||||
/// The maximum size hint for items and mutations returned
|
/// The maximum size hint for items and mutations returned
|
||||||
@ -207,8 +192,6 @@ pub struct StdState<I, C, R, SC> {
|
|||||||
named_metadata: NamedSerdeAnyMap,
|
named_metadata: NamedSerdeAnyMap,
|
||||||
/// MaxSize testcase size for mutators that appreciate it
|
/// MaxSize testcase size for mutators that appreciate it
|
||||||
max_size: usize,
|
max_size: usize,
|
||||||
/// The [`CorpusId`] of the testcase we're currently fuzzing.
|
|
||||||
fuzzed_corpus_id: Option<CorpusId>,
|
|
||||||
/// Performance statistics for this fuzzer
|
/// Performance statistics for this fuzzer
|
||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
introspection_monitor: ClientPerfMonitor,
|
introspection_monitor: ClientPerfMonitor,
|
||||||
@ -274,20 +257,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, C, R, SC> HasFuzzedCorpusId for StdState<I, C, R, SC> {
|
|
||||||
fn fuzzed_corpus_id(&self) -> Option<CorpusId> {
|
|
||||||
self.fuzzed_corpus_id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_fuzzed_corpus_id(&mut self, fuzzed_corpus_id: CorpusId) {
|
|
||||||
self.fuzzed_corpus_id = Some(fuzzed_corpus_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clear_fuzzed_corpus_id(&mut self) {
|
|
||||||
self.fuzzed_corpus_id = None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I, C, R, SC> HasSolutions for StdState<I, C, R, SC>
|
impl<I, C, R, SC> HasSolutions for StdState<I, C, R, SC>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -725,7 +694,6 @@ where
|
|||||||
corpus,
|
corpus,
|
||||||
solutions,
|
solutions,
|
||||||
max_size: DEFAULT_MAX_SIZE,
|
max_size: DEFAULT_MAX_SIZE,
|
||||||
fuzzed_corpus_id: None,
|
|
||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
introspection_monitor: ClientPerfMonitor::new(),
|
introspection_monitor: ClientPerfMonitor::new(),
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
|
@ -8,7 +8,7 @@ use frida_gum::{
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use libafl::{
|
use libafl::{
|
||||||
executors::inprocess::{HasInProcessHandlers, InProcessHandlers},
|
executors::inprocess::{HasInProcessHandlers, InProcessHandlers},
|
||||||
state::{HasClientPerfMonitor, HasFuzzedCorpusId, HasSolutions},
|
state::{HasClientPerfMonitor, HasCorpus, HasSolutions},
|
||||||
};
|
};
|
||||||
use libafl::{
|
use libafl::{
|
||||||
executors::{Executor, ExitKind, HasObservers, InProcessExecutor},
|
executors::{Executor, ExitKind, HasObservers, InProcessExecutor},
|
||||||
@ -200,7 +200,7 @@ impl<'a, 'b, 'c, H, OT, RT, S> HasInProcessHandlers
|
|||||||
for FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
|
for FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&S::Input) -> ExitKind,
|
||||||
S: UsesInput + HasClientPerfMonitor + HasSolutions + HasFuzzedCorpusId,
|
S: UsesInput + HasClientPerfMonitor + HasSolutions + HasCorpus,
|
||||||
S::Input: HasTargetBytes,
|
S::Input: HasTargetBytes,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
RT: FridaRuntimeTuple,
|
RT: FridaRuntimeTuple,
|
||||||
|
@ -13,10 +13,7 @@ use libafl::{
|
|||||||
fuzzer::HasObjective,
|
fuzzer::HasObjective,
|
||||||
inputs::UsesInput,
|
inputs::UsesInput,
|
||||||
observers::{ObserversTuple, UsesObservers},
|
observers::{ObserversTuple, UsesObservers},
|
||||||
state::{
|
state::{HasClientPerfMonitor, HasCorpus, HasExecutions, HasSolutions, State, UsesState},
|
||||||
HasClientPerfMonitor, HasCorpus, HasExecutions, HasFuzzedCorpusId, HasSolutions, State,
|
|
||||||
UsesState,
|
|
||||||
},
|
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -67,12 +64,7 @@ where
|
|||||||
where
|
where
|
||||||
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
EM: EventFirer<State = S> + EventRestarter<State = S>,
|
||||||
OF: Feedback<S>,
|
OF: Feedback<S>,
|
||||||
S: State
|
S: State + HasExecutions + HasCorpus + HasSolutions + HasClientPerfMonitor,
|
||||||
+ HasExecutions
|
|
||||||
+ HasCorpus
|
|
||||||
+ HasSolutions
|
|
||||||
+ HasClientPerfMonitor
|
|
||||||
+ HasFuzzedCorpusId,
|
|
||||||
Z: HasObjective<Objective = OF, State = S>,
|
Z: HasObjective<Objective = OF, State = S>,
|
||||||
{
|
{
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
@ -4,7 +4,7 @@ use libafl::{
|
|||||||
events::{EventFirer, EventRestarter},
|
events::{EventFirer, EventRestarter},
|
||||||
executors::{inprocess::windows_asan_handler::asan_death_handler, Executor, HasObservers},
|
executors::{inprocess::windows_asan_handler::asan_death_handler, Executor, HasObservers},
|
||||||
feedbacks::Feedback,
|
feedbacks::Feedback,
|
||||||
state::{HasClientPerfMonitor, HasFuzzedCorpusId, HasSolutions},
|
state::{HasClientPerfMonitor, HasCorpus, HasSolutions},
|
||||||
HasObjective,
|
HasObjective,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ where
|
|||||||
E: Executor<EM, Z> + HasObservers,
|
E: Executor<EM, Z> + HasObservers,
|
||||||
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
||||||
OF: Feedback<E::State>,
|
OF: Feedback<E::State>,
|
||||||
E::State: HasSolutions + HasClientPerfMonitor + HasFuzzedCorpusId,
|
E::State: HasSolutions + HasClientPerfMonitor + HasCorpus,
|
||||||
Z: HasObjective<Objective = OF, State = E::State>,
|
Z: HasObjective<Objective = OF, State = E::State>,
|
||||||
{
|
{
|
||||||
__sanitizer_set_death_callback(asan_death_handler::<E, EM, OF, Z>);
|
__sanitizer_set_death_callback(asan_death_handler::<E, EM, OF, Z>);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user