make nopstate public so that it can be used as reproducer (#1888)

This commit is contained in:
Addison Crump 2024-02-27 16:48:08 +01:00 committed by GitHub
parent 1dcfe8ef56
commit 7a4fb06d02
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 169 additions and 144 deletions

View File

@ -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]

View File

@ -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();

View File

@ -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.

View File

@ -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)]

View File

@ -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]

View File

@ -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,37 +998,16 @@ impl<I, C, R, SC> HasScalabilityMonitor for StdState<I, C, R, SC> {
} }
} }
#[cfg(test)] /// A very simple state without any bells or whistles, for testing.
pub mod test { #[derive(Debug, Serialize, Deserialize, Default)]
use core::{marker::PhantomData, time::Duration}; pub struct NopState<I> {
use libafl_bolts::{rands::StdRand, serdeany::SerdeAnyMap, Error};
use serde::{Deserialize, Serialize};
use crate::{
corpus::{CorpusId, HasCurrentCorpusIdx, InMemoryCorpus},
inputs::{Input, NopInput, UsesInput},
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, metadata: SerdeAnyMap,
execution: usize, execution: usize,
rand: StdRand, rand: StdRand,
phantom: PhantomData<I>, phantom: PhantomData<I>,
} }
impl<I> NopState<I> { impl<I> NopState<I> {
/// Create a new State that does nothing (for tests) /// Create a new State that does nothing (for tests)
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
@ -1039,16 +1018,16 @@ pub mod test {
phantom: PhantomData, phantom: PhantomData,
} }
} }
} }
impl<I> UsesInput for NopState<I> impl<I> UsesInput for NopState<I>
where where
I: Input, I: Input,
{ {
type Input = I; type Input = I;
} }
impl<I> HasExecutions for NopState<I> { impl<I> HasExecutions for NopState<I> {
fn executions(&self) -> &usize { fn executions(&self) -> &usize {
&self.execution &self.execution
} }
@ -1056,9 +1035,9 @@ pub mod test {
fn executions_mut(&mut self) -> &mut usize { fn executions_mut(&mut self) -> &mut usize {
&mut self.execution &mut self.execution
} }
} }
impl<I> HasLastReportTime for NopState<I> { impl<I> HasLastReportTime for NopState<I> {
fn last_report_time(&self) -> &Option<Duration> { fn last_report_time(&self) -> &Option<Duration> {
unimplemented!(); unimplemented!();
} }
@ -1066,9 +1045,9 @@ pub mod test {
fn last_report_time_mut(&mut self) -> &mut Option<Duration> { fn last_report_time_mut(&mut self) -> &mut Option<Duration> {
unimplemented!(); unimplemented!();
} }
} }
impl<I> HasMetadata for NopState<I> { impl<I> HasMetadata for NopState<I> {
fn metadata_map(&self) -> &SerdeAnyMap { fn metadata_map(&self) -> &SerdeAnyMap {
&self.metadata &self.metadata
} }
@ -1076,9 +1055,9 @@ pub mod test {
fn metadata_map_mut(&mut self) -> &mut SerdeAnyMap { fn metadata_map_mut(&mut self) -> &mut SerdeAnyMap {
&mut self.metadata &mut self.metadata
} }
} }
impl<I> HasRand for NopState<I> { impl<I> HasRand for NopState<I> {
type Rand = StdRand; type Rand = StdRand;
fn rand(&self) -> &Self::Rand { fn rand(&self) -> &Self::Rand {
@ -1088,11 +1067,11 @@ pub mod test {
fn rand_mut(&mut self) -> &mut Self::Rand { fn rand_mut(&mut self) -> &mut Self::Rand {
&mut self.rand &mut self.rand
} }
} }
impl<I> State for NopState<I> where I: Input {} impl<I> State for NopState<I> where I: Input {}
impl<I> HasCurrentCorpusIdx for NopState<I> { impl<I> HasCurrentCorpusIdx for NopState<I> {
fn set_corpus_idx(&mut self, _idx: CorpusId) -> Result<(), Error> { fn set_corpus_idx(&mut self, _idx: CorpusId) -> Result<(), Error> {
Ok(()) Ok(())
} }
@ -1104,9 +1083,9 @@ pub mod test {
fn current_corpus_idx(&self) -> Result<Option<CorpusId>, Error> { fn current_corpus_idx(&self) -> Result<Option<CorpusId>, Error> {
Ok(None) Ok(None)
} }
} }
impl<I> HasCurrentStage for NopState<I> { impl<I> HasCurrentStage for NopState<I> {
fn set_stage(&mut self, _idx: usize) -> Result<(), Error> { fn set_stage(&mut self, _idx: usize) -> Result<(), Error> {
Ok(()) Ok(())
} }
@ -1118,10 +1097,10 @@ pub mod test {
fn current_stage(&self) -> Result<Option<usize>, Error> { fn current_stage(&self) -> Result<Option<usize>, Error> {
Ok(None) Ok(None)
} }
} }
#[cfg(feature = "introspection")] #[cfg(feature = "introspection")]
impl<I> HasClientPerfMonitor for NopState<I> { impl<I> HasClientPerfMonitor for NopState<I> {
fn introspection_monitor(&self) -> &ClientPerfMonitor { fn introspection_monitor(&self) -> &ClientPerfMonitor {
unimplemented!(); unimplemented!();
} }
@ -1129,10 +1108,10 @@ pub mod test {
fn introspection_monitor_mut(&mut self) -> &mut ClientPerfMonitor { fn introspection_monitor_mut(&mut self) -> &mut ClientPerfMonitor {
unimplemented!(); unimplemented!();
} }
} }
#[cfg(feature = "scalability_introspection")] #[cfg(feature = "scalability_introspection")]
impl<I> HasScalabilityMonitor for NopState<I> { impl<I> HasScalabilityMonitor for NopState<I> {
fn scalability_monitor(&self) -> &ScalabilityMonitor { fn scalability_monitor(&self) -> &ScalabilityMonitor {
unimplemented!(); unimplemented!();
} }
@ -1140,7 +1119,18 @@ pub mod test {
fn scalability_monitor_mut(&mut self) -> &mut ScalabilityMonitor { fn scalability_monitor_mut(&mut self) -> &mut ScalabilityMonitor {
unimplemented!(); unimplemented!();
} }
} }
#[cfg(test)]
pub mod test {
use libafl_bolts::rands::StdRand;
use super::StdState;
use crate::{
corpus::InMemoryCorpus,
inputs::{Input, NopInput},
stages::test::{test_resume, test_resume_stages},
};
#[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>>

View File

@ -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>,