make nopstate public so that it can be used as reproducer (#1888)
This commit is contained in:
parent
1dcfe8ef56
commit
7a4fb06d02
@ -693,7 +693,7 @@ mod tests {
|
|||||||
fuzzer::test::NopFuzzer,
|
fuzzer::test::NopFuzzer,
|
||||||
inputs::BytesInput,
|
inputs::BytesInput,
|
||||||
monitors::SimpleMonitor,
|
monitors::SimpleMonitor,
|
||||||
state::test::NopState,
|
state::NopState,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -560,7 +560,7 @@ mod tests {
|
|||||||
inprocess_fork::GenericInProcessForkExecutor, Executor,
|
inprocess_fork::GenericInProcessForkExecutor, Executor,
|
||||||
},
|
},
|
||||||
fuzzer::test::NopFuzzer,
|
fuzzer::test::NopFuzzer,
|
||||||
state::test::NopState,
|
state::NopState,
|
||||||
};
|
};
|
||||||
|
|
||||||
let provider = StdShMemProvider::new().unwrap();
|
let provider = StdShMemProvider::new().unwrap();
|
||||||
|
@ -174,7 +174,7 @@ pub mod test {
|
|||||||
executors::{Executor, ExitKind},
|
executors::{Executor, ExitKind},
|
||||||
fuzzer::test::NopFuzzer,
|
fuzzer::test::NopFuzzer,
|
||||||
inputs::{BytesInput, HasTargetBytes},
|
inputs::{BytesInput, HasTargetBytes},
|
||||||
state::{test::NopState, HasExecutions, State, UsesState},
|
state::{HasExecutions, NopState, State, UsesState},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A simple executor that does nothing.
|
/// A simple executor that does nothing.
|
||||||
|
@ -163,7 +163,7 @@ mod tests {
|
|||||||
feedbacks::{differential::DiffResult, DiffFeedback, Feedback},
|
feedbacks::{differential::DiffResult, DiffFeedback, Feedback},
|
||||||
inputs::{BytesInput, UsesInput},
|
inputs::{BytesInput, UsesInput},
|
||||||
observers::Observer,
|
observers::Observer,
|
||||||
state::{test::NopState, State, UsesState},
|
state::{NopState, State, UsesState},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -376,7 +376,7 @@ mod test {
|
|||||||
use crate::{
|
use crate::{
|
||||||
inputs::BytesInput,
|
inputs::BytesInput,
|
||||||
mutators::{ByteRandMutator, ScheduledMutator},
|
mutators::{ByteRandMutator, ScheduledMutator},
|
||||||
state::test::NopState,
|
state::NopState,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -14,7 +14,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
rands::Rand,
|
rands::{Rand, StdRand},
|
||||||
serdeany::{NamedSerdeAnyMap, SerdeAny, SerdeAnyMap},
|
serdeany::{NamedSerdeAnyMap, SerdeAny, SerdeAnyMap},
|
||||||
};
|
};
|
||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
@ -998,149 +998,139 @@ impl<I, C, R, SC> HasScalabilityMonitor for StdState<I, C, R, SC> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A very simple state without any bells or whistles, for testing.
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
|
pub struct NopState<I> {
|
||||||
|
metadata: SerdeAnyMap,
|
||||||
|
execution: usize,
|
||||||
|
rand: StdRand,
|
||||||
|
phantom: PhantomData<I>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> NopState<I> {
|
||||||
|
/// Create a new State that does nothing (for tests)
|
||||||
|
#[must_use]
|
||||||
|
pub fn new() -> Self {
|
||||||
|
NopState {
|
||||||
|
metadata: SerdeAnyMap::new(),
|
||||||
|
execution: 0,
|
||||||
|
rand: StdRand::default(),
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> UsesInput for NopState<I>
|
||||||
|
where
|
||||||
|
I: Input,
|
||||||
|
{
|
||||||
|
type Input = I;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> HasExecutions for NopState<I> {
|
||||||
|
fn executions(&self) -> &usize {
|
||||||
|
&self.execution
|
||||||
|
}
|
||||||
|
|
||||||
|
fn executions_mut(&mut self) -> &mut usize {
|
||||||
|
&mut self.execution
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> HasLastReportTime for NopState<I> {
|
||||||
|
fn last_report_time(&self) -> &Option<Duration> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn last_report_time_mut(&mut self) -> &mut Option<Duration> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> HasMetadata for NopState<I> {
|
||||||
|
fn metadata_map(&self) -> &SerdeAnyMap {
|
||||||
|
&self.metadata
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metadata_map_mut(&mut self) -> &mut SerdeAnyMap {
|
||||||
|
&mut self.metadata
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> HasRand for NopState<I> {
|
||||||
|
type Rand = StdRand;
|
||||||
|
|
||||||
|
fn rand(&self) -> &Self::Rand {
|
||||||
|
&self.rand
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rand_mut(&mut self) -> &mut Self::Rand {
|
||||||
|
&mut self.rand
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> State for NopState<I> where I: Input {}
|
||||||
|
|
||||||
|
impl<I> HasCurrentCorpusIdx for NopState<I> {
|
||||||
|
fn set_corpus_idx(&mut self, _idx: CorpusId) -> Result<(), Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_corpus_idx(&mut self) -> Result<(), Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_corpus_idx(&self) -> Result<Option<CorpusId>, Error> {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> HasCurrentStage for NopState<I> {
|
||||||
|
fn set_stage(&mut self, _idx: usize) -> Result<(), Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_stage(&mut self) -> Result<(), Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_stage(&self) -> Result<Option<usize>, Error> {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "introspection")]
|
||||||
|
impl<I> HasClientPerfMonitor for NopState<I> {
|
||||||
|
fn introspection_monitor(&self) -> &ClientPerfMonitor {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn introspection_monitor_mut(&mut self) -> &mut ClientPerfMonitor {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "scalability_introspection")]
|
||||||
|
impl<I> HasScalabilityMonitor for NopState<I> {
|
||||||
|
fn scalability_monitor(&self) -> &ScalabilityMonitor {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn scalability_monitor_mut(&mut self) -> &mut ScalabilityMonitor {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod test {
|
pub mod test {
|
||||||
use core::{marker::PhantomData, time::Duration};
|
use libafl_bolts::rands::StdRand;
|
||||||
|
|
||||||
use libafl_bolts::{rands::StdRand, serdeany::SerdeAnyMap, Error};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
|
use super::StdState;
|
||||||
use crate::{
|
use crate::{
|
||||||
corpus::{CorpusId, HasCurrentCorpusIdx, InMemoryCorpus},
|
corpus::InMemoryCorpus,
|
||||||
inputs::{Input, NopInput, UsesInput},
|
inputs::{Input, NopInput},
|
||||||
stages::test::{test_resume, test_resume_stages},
|
stages::test::{test_resume, test_resume_stages},
|
||||||
state::{
|
|
||||||
HasCurrentStage, HasExecutions, HasLastReportTime, HasMetadata, HasRand, State,
|
|
||||||
StdState,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
#[cfg(feature = "introspection")]
|
|
||||||
use crate::{monitors::ClientPerfMonitor, state::HasClientPerfMonitor};
|
|
||||||
#[cfg(feature = "scalability_introspection")]
|
|
||||||
use crate::{monitors::ScalabilityMonitor, state::HasScalabilityMonitor};
|
|
||||||
|
|
||||||
/// A very simple state without any bells or whistles, for testing.
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
|
||||||
pub struct NopState<I> {
|
|
||||||
metadata: SerdeAnyMap,
|
|
||||||
execution: usize,
|
|
||||||
rand: StdRand,
|
|
||||||
phantom: PhantomData<I>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I> NopState<I> {
|
|
||||||
/// Create a new State that does nothing (for tests)
|
|
||||||
#[must_use]
|
|
||||||
pub fn new() -> Self {
|
|
||||||
NopState {
|
|
||||||
metadata: SerdeAnyMap::new(),
|
|
||||||
execution: 0,
|
|
||||||
rand: StdRand::default(),
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I> UsesInput for NopState<I>
|
|
||||||
where
|
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
type Input = I;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I> HasExecutions for NopState<I> {
|
|
||||||
fn executions(&self) -> &usize {
|
|
||||||
&self.execution
|
|
||||||
}
|
|
||||||
|
|
||||||
fn executions_mut(&mut self) -> &mut usize {
|
|
||||||
&mut self.execution
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I> HasLastReportTime for NopState<I> {
|
|
||||||
fn last_report_time(&self) -> &Option<Duration> {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn last_report_time_mut(&mut self) -> &mut Option<Duration> {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I> HasMetadata for NopState<I> {
|
|
||||||
fn metadata_map(&self) -> &SerdeAnyMap {
|
|
||||||
&self.metadata
|
|
||||||
}
|
|
||||||
|
|
||||||
fn metadata_map_mut(&mut self) -> &mut SerdeAnyMap {
|
|
||||||
&mut self.metadata
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I> HasRand for NopState<I> {
|
|
||||||
type Rand = StdRand;
|
|
||||||
|
|
||||||
fn rand(&self) -> &Self::Rand {
|
|
||||||
&self.rand
|
|
||||||
}
|
|
||||||
|
|
||||||
fn rand_mut(&mut self) -> &mut Self::Rand {
|
|
||||||
&mut self.rand
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I> State for NopState<I> where I: Input {}
|
|
||||||
|
|
||||||
impl<I> HasCurrentCorpusIdx for NopState<I> {
|
|
||||||
fn set_corpus_idx(&mut self, _idx: CorpusId) -> Result<(), Error> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clear_corpus_idx(&mut self) -> Result<(), Error> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn current_corpus_idx(&self) -> Result<Option<CorpusId>, Error> {
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I> HasCurrentStage for NopState<I> {
|
|
||||||
fn set_stage(&mut self, _idx: usize) -> Result<(), Error> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clear_stage(&mut self) -> Result<(), Error> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn current_stage(&self) -> Result<Option<usize>, Error> {
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "introspection")]
|
|
||||||
impl<I> HasClientPerfMonitor for NopState<I> {
|
|
||||||
fn introspection_monitor(&self) -> &ClientPerfMonitor {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn introspection_monitor_mut(&mut self) -> &mut ClientPerfMonitor {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "scalability_introspection")]
|
|
||||||
impl<I> HasScalabilityMonitor for NopState<I> {
|
|
||||||
fn scalability_monitor(&self) -> &ScalabilityMonitor {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn scalability_monitor_mut(&mut self) -> &mut ScalabilityMonitor {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn test_std_state<I: Input>() -> StdState<I, InMemoryCorpus<I>, StdRand, InMemoryCorpus<I>>
|
pub fn test_std_state<I: Input>() -> StdState<I, InMemoryCorpus<I>, StdRand, InMemoryCorpus<I>>
|
||||||
|
@ -10,7 +10,11 @@ use core::{
|
|||||||
ptr::{self, addr_of, addr_of_mut},
|
ptr::{self, addr_of, addr_of_mut},
|
||||||
};
|
};
|
||||||
|
|
||||||
use libafl::{executors::hooks::inprocess::inprocess_get_state, inputs::UsesInput};
|
use libafl::{
|
||||||
|
executors::{hooks::inprocess::inprocess_get_state, ExitKind},
|
||||||
|
inputs::UsesInput,
|
||||||
|
state::NopState,
|
||||||
|
};
|
||||||
|
|
||||||
pub use crate::emu::SyscallHookResult;
|
pub use crate::emu::SyscallHookResult;
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -337,6 +341,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
static mut HOOKS_IS_INITIALIZED: bool = false;
|
static mut HOOKS_IS_INITIALIZED: bool = false;
|
||||||
|
static mut FIRST_EXEC: bool = true;
|
||||||
|
|
||||||
pub struct QemuHooks<QT, S>
|
pub struct QemuHooks<QT, S>
|
||||||
where
|
where
|
||||||
@ -361,6 +366,36 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<I, QT> QemuHooks<QT, NopState<I>>
|
||||||
|
where
|
||||||
|
QT: QemuHelperTuple<NopState<I>>,
|
||||||
|
NopState<I>: UsesInput<Input = I>,
|
||||||
|
{
|
||||||
|
pub fn reproducer(emulator: Emulator, helpers: QT) -> Box<Self> {
|
||||||
|
Self::new(emulator, helpers)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn repro_run<H>(&mut self, harness: &mut H, input: &I) -> ExitKind
|
||||||
|
where
|
||||||
|
H: FnMut(&I) -> ExitKind,
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
if FIRST_EXEC {
|
||||||
|
self.helpers.first_exec_all(self);
|
||||||
|
FIRST_EXEC = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.helpers.pre_exec_all(&self.emulator, input);
|
||||||
|
|
||||||
|
let mut exit_kind = harness(input);
|
||||||
|
|
||||||
|
self.helpers
|
||||||
|
.post_exec_all(&self.emulator, input, &mut (), &mut exit_kind);
|
||||||
|
|
||||||
|
exit_kind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<QT, S> QemuHooks<QT, S>
|
impl<QT, S> QemuHooks<QT, S>
|
||||||
where
|
where
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user