Fix fuzzers after HasTestcase (#1123) (#1162)

* Fix fuzzers after HasTestcase (#1123)

* Make the trait a trait

* Implement HasTestcase for Corpora

* fix

* fix

* a

* a

* fix

* wasm32

* a

* f

* f

* aa

---------

Co-authored-by: tokatoka <tokazerkje@outlook.com>
This commit is contained in:
Dominik Maier 2023-03-19 03:58:32 +01:00 committed by GitHub
parent bbe4e85768
commit f4f23de32b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 181 additions and 56 deletions

View File

@ -181,6 +181,8 @@ jobs:
run: rustup toolchain install nightly --component rustfmt --component clippy --allow-downgrade
- name: Add no_std toolchain
run: rustup toolchain install nightly-x86_64-unknown-linux-gnu ; rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
- name: Add wasm target
run: rustup target add wasm32-unknown-unknown
- name: Install cxxbridge
if: runner.os == 'macOS'
run: cargo install cxxbridge-cmd

View File

@ -74,7 +74,11 @@ pub fn main() {
)
.unwrap();
if state.metadata_map().get::<NautilusChunksMetadata>().is_none() {
if state
.metadata_map()
.get::<NautilusChunksMetadata>()
.is_none()
{
state.add_metadata(NautilusChunksMetadata::new("/tmp/".into()));
}

View File

@ -8,7 +8,7 @@ use libafl::{
rands::StdRand,
shmem::{ShMem, ShMemProvider, UnixShMemProvider},
tuples::{tuple_list, MatchName, Merge},
AsMutSlice,
AsMutSlice, Truncate,
},
corpus::{Corpus, InMemoryCorpus, OnDiskCorpus},
events::SimpleEventManager,
@ -22,7 +22,7 @@ use libafl::{
inputs::BytesInput,
monitors::SimpleMonitor,
mutators::{scheduled::havoc_mutations, tokens_mutations, StdScheduledMutator, Tokens},
observers::{HitcountsMapObserver, MapObserver, StdMapObserver, TimeObserver},
observers::{HitcountsMapObserver, StdMapObserver, TimeObserver},
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
stages::mutational::StdMutationalStage,
state::{HasCorpus, HasMetadata, StdState},

View File

@ -8,7 +8,7 @@ use libafl::{
rands::StdRand,
shmem::{ShMem, ShMemProvider, UnixShMemProvider},
tuples::{tuple_list, MatchName, Merge},
AsMutSlice,
AsMutSlice, Truncate,
},
corpus::{Corpus, InMemoryCorpus, OnDiskCorpus},
events::SimpleEventManager,
@ -22,7 +22,7 @@ use libafl::{
inputs::BytesInput,
monitors::SimpleMonitor,
mutators::{scheduled::havoc_mutations, tokens_mutations, StdScheduledMutator, Tokens},
observers::{HitcountsMapObserver, MapObserver, StdMapObserver, TimeObserver},
observers::{HitcountsMapObserver, StdMapObserver, TimeObserver},
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
stages::mutational::StdMutationalStage,
state::{HasCorpus, HasMetadata, StdState},

View File

@ -81,7 +81,7 @@ mkdir in || true
echo a > in/a
# Allow sigterm as exit code
timeout 11s ./${FUZZER_NAME} -o out -i in >fuzz_stdout.log || true
if [ -z "$(grep "corpus: 30" fuzz_stdout.log)" ]; then
if [ -z "$(grep "objectives: 10" fuzz_stdout.log)" ]; then
echo "Fuzzer does not generate any testcases or any crashes"
exit 1
else

View File

@ -82,7 +82,7 @@ mkdir in || true
echo a > in/a
# Allow sigterm as exit code
timeout 11s ./${FUZZER_NAME} -o out -i in >fuzz_stdout.log || true
if [ -z "$(grep "corpus: 30" fuzz_stdout.log)" ]; then
if [ -z "$(grep "objectives: 10" fuzz_stdout.log)" ]; then
echo "Fuzzer does not generate any testcases or any crashes"
exit 1
else

View File

@ -105,7 +105,7 @@ script_runner = "@shell"
script='''
rm -rf libafl_unix_shmem_server || true
timeout 11s ./${FUZZER_NAME} --cores 0 >fuzz_stdout.log 2>/dev/null || true
if [ -z "$(grep "corpus: 30" fuzz_stdout.log)" ]; then
if [ -z "$(grep "corpus: 8" fuzz_stdout.log)" ]; then
echo "Fuzzer does not generate any testcases or any crashes"
exit 1
else

View File

@ -172,7 +172,11 @@ pub fn libafl_main() {
.unwrap()
});
if state.metadata_map().get::<NautilusChunksMetadata>().is_none() {
if state
.metadata_map()
.get::<NautilusChunksMetadata>()
.is_none()
{
state.add_metadata(NautilusChunksMetadata::new("/tmp/".into()));
}

View File

@ -63,9 +63,10 @@ where
}
#[inline]
fn append_metadata(
fn append_metadata<OT>(
&mut self,
_state: &mut S,
_observers: &OT,
testcase: &mut Testcase<PacketData>,
) -> Result<(), Error> {
testcase

View File

@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
use crate::{
corpus::{
inmemory_ondisk::InMemoryOnDiskCorpus, ondisk::OnDiskMetadataFormat, Corpus, CorpusId,
Testcase,
HasTestcase, Testcase,
},
inputs::{Input, UsesInput},
Error,
@ -130,6 +130,22 @@ where
}
}
impl<I> HasTestcase for CachedOnDiskCorpus<I>
where
I: Input,
{
fn testcase(&self, id: CorpusId) -> Result<core::cell::Ref<Testcase<Self::Input>>, Error> {
Ok(self.get(id)?.borrow())
}
fn testcase_mut(
&self,
id: CorpusId,
) -> Result<core::cell::RefMut<Testcase<Self::Input>>, Error> {
Ok(self.get(id)?.borrow_mut())
}
}
impl<I> CachedOnDiskCorpus<I>
where
I: Input,

View File

@ -5,6 +5,7 @@ use core::cell::RefCell;
use serde::{Deserialize, Serialize};
use super::HasTestcase;
use crate::{
corpus::{Corpus, CorpusId, Testcase},
inputs::{Input, UsesInput},
@ -381,6 +382,25 @@ where
}
}
impl<I> HasTestcase for InMemoryCorpus<I>
where
I: Input,
{
fn testcase(
&self,
id: CorpusId,
) -> Result<core::cell::Ref<Testcase<<Self as UsesInput>::Input>>, Error> {
Ok(self.get(id)?.borrow())
}
fn testcase_mut(
&self,
id: CorpusId,
) -> Result<core::cell::RefMut<Testcase<<Self as UsesInput>::Input>>, Error> {
Ok(self.get(id)?.borrow_mut())
}
}
impl<I> InMemoryCorpus<I>
where
I: Input,

View File

@ -13,7 +13,10 @@ use std::{
use serde::{Deserialize, Serialize};
use super::ondisk::{OnDiskMetadata, OnDiskMetadataFormat};
use super::{
ondisk::{OnDiskMetadata, OnDiskMetadataFormat},
HasTestcase,
};
#[cfg(feature = "gzip")]
use crate::bolts::compress::GzipCompressor;
use crate::{
@ -134,6 +137,25 @@ where
}
}
impl<I> HasTestcase for InMemoryOnDiskCorpus<I>
where
I: Input,
{
fn testcase(
&self,
id: CorpusId,
) -> Result<core::cell::Ref<Testcase<<Self as UsesInput>::Input>>, Error> {
Ok(self.get(id)?.borrow())
}
fn testcase_mut(
&self,
id: CorpusId,
) -> Result<core::cell::RefMut<Testcase<<Self as UsesInput>::Input>>, Error> {
Ok(self.get(id)?.borrow_mut())
}
}
impl<I> InMemoryOnDiskCorpus<I>
where
I: Input,

View File

@ -1,7 +1,7 @@
//! Corpuses contain the testcases, either in memory, on disk, or somewhere else.
pub mod testcase;
pub use testcase::{SchedulerTestcaseMetadata, Testcase};
pub use testcase::{HasTestcase, SchedulerTestcaseMetadata, Testcase};
pub mod inmemory;
pub use inmemory::InMemoryCorpus;
@ -187,7 +187,7 @@ pub mod pybind {
cached::pybind::PythonCachedOnDiskCorpus, inmemory::pybind::PythonInMemoryCorpus,
inmemory_ondisk::pybind::PythonInMemoryOnDiskCorpus,
ondisk::pybind::PythonOnDiskCorpus, testcase::pybind::PythonTestcaseWrapper, Corpus,
CorpusId, Testcase,
CorpusId, HasTestcase, Testcase,
},
inputs::{BytesInput, UsesInput},
Error,
@ -384,6 +384,22 @@ pub mod pybind {
}*/
}
impl HasTestcase for PythonCorpus {
fn testcase(
&self,
id: CorpusId,
) -> Result<core::cell::Ref<Testcase<<Self as UsesInput>::Input>>, Error> {
Ok(self.get(id)?.borrow())
}
fn testcase_mut(
&self,
id: CorpusId,
) -> Result<core::cell::RefMut<Testcase<<Self as UsesInput>::Input>>, Error> {
Ok(self.get(id)?.borrow_mut())
}
}
/// Register the classes to the python module
pub fn register(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_class::<PythonCorpus>()?;

View File

@ -9,7 +9,7 @@ use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize};
use super::CachedOnDiskCorpus;
use super::{CachedOnDiskCorpus, HasTestcase};
use crate::{
bolts::serdeany::SerdeAnyMap,
corpus::{Corpus, CorpusId, Testcase},
@ -140,6 +140,25 @@ where
}
}
impl<I> HasTestcase for OnDiskCorpus<I>
where
I: Input,
{
fn testcase(
&self,
id: CorpusId,
) -> Result<core::cell::Ref<Testcase<<Self as UsesInput>::Input>>, Error> {
Ok(self.get(id)?.borrow())
}
fn testcase_mut(
&self,
id: CorpusId,
) -> Result<core::cell::RefMut<Testcase<<Self as UsesInput>::Input>>, Error> {
Ok(self.get(id)?.borrow_mut())
}
}
impl<I> OnDiskCorpus<I>
where
I: Input,

View File

@ -2,18 +2,38 @@
//! It will contain a respective input, and metadata.
use alloc::string::String;
use core::{default::Default, option::Option, time::Duration};
use core::{
cell::{Ref, RefMut},
default::Default,
option::Option,
time::Duration,
};
use serde::{Deserialize, Serialize};
use crate::{
bolts::{serdeany::SerdeAnyMap, HasLen},
corpus::CorpusId,
inputs::Input,
inputs::{Input, UsesInput},
state::HasMetadata,
Error,
};
/// Shorthand to receive a [`Ref`] or [`RefMut`] to a stored [`Testcase`], by [`CorpusId`].
/// For a normal state, this should return a [`Testcase`] in the corpus, not the objectives.
pub trait HasTestcase: UsesInput {
/// Shorthand to receive a [`Ref`] to a stored [`Testcase`], by [`CorpusId`].
/// For a normal state, this should return a [`Testcase`] in the corpus, not the objectives.
fn testcase(&self, id: CorpusId) -> Result<Ref<Testcase<<Self as UsesInput>::Input>>, Error>;
/// Shorthand to receive a [`RefMut`] to a stored [`Testcase`], by [`CorpusId`].
/// For a normal state, this should return a [`Testcase`] in the corpus, not the objectives.
fn testcase_mut(
&self,
id: CorpusId,
) -> Result<RefMut<Testcase<<Self as UsesInput>::Input>>, Error>;
}
/// An entry in the Testcase Corpus
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(bound = "I: serde::de::DeserializeOwned")]

View File

@ -8,12 +8,12 @@ use serde::{Deserialize, Serialize};
use crate::{
bolts::{rands::Rand, tuples::Named},
corpus::Corpus,
corpus::{Corpus, HasTestcase},
generators::GramatronGenerator,
inputs::{GramatronInput, Terminal},
mutators::{MutationResult, Mutator},
random_corpus_id,
state::{HasCorpus, HasMetadata, HasRand, HasTestcase},
state::{HasCorpus, HasMetadata, HasRand},
Error,
};

View File

@ -6,11 +6,11 @@ use core::marker::PhantomData;
use serde::{Deserialize, Serialize};
use crate::{
corpus::{Corpus, CorpusId, SchedulerTestcaseMetadata, Testcase},
corpus::{Corpus, CorpusId, HasTestcase, SchedulerTestcaseMetadata, Testcase},
inputs::UsesInput,
observers::{MapObserver, ObserversTuple},
schedulers::{powersched::SchedulerMetadata, testcase_score::TestcaseScore, Scheduler},
state::{HasCorpus, HasExecutions, HasMetadata, HasRand, HasTestcase, UsesState},
state::{HasCorpus, HasExecutions, HasMetadata, HasRand, UsesState},
Error,
};

View File

@ -9,11 +9,11 @@ use core::{marker::PhantomData, time::Duration};
use serde::{Deserialize, Serialize};
use crate::{
corpus::{Corpus, CorpusId, SchedulerTestcaseMetadata, Testcase},
corpus::{Corpus, CorpusId, HasTestcase, SchedulerTestcaseMetadata, Testcase},
inputs::UsesInput,
observers::{MapObserver, ObserversTuple},
schedulers::{RemovableScheduler, Scheduler},
state::{HasCorpus, HasMetadata, HasTestcase, UsesState},
state::{HasCorpus, HasMetadata, UsesState},
Error,
};

View File

@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
use crate::{
bolts::rands::Rand,
corpus::{Corpus, CorpusId, SchedulerTestcaseMetadata},
corpus::{Corpus, CorpusId, HasTestcase, SchedulerTestcaseMetadata},
inputs::UsesInput,
observers::{MapObserver, ObserversTuple},
random_corpus_id,
@ -18,7 +18,7 @@ use crate::{
testcase_score::{CorpusWeightTestcaseScore, TestcaseScore},
RemovableScheduler, Scheduler,
},
state::{HasCorpus, HasMetadata, HasRand, HasTestcase, UsesState},
state::{HasCorpus, HasMetadata, HasRand, UsesState},
Error,
};

View File

@ -11,16 +11,13 @@ use serde::{Deserialize, Serialize};
use crate::{
bolts::{current_time, shmem::ShMemProvider},
corpus::{Corpus, CorpusId},
corpus::{Corpus, CorpusId, HasTestcase},
events::{llmp::LlmpEventConverter, Event, EventConfig, EventFirer},
executors::{Executor, ExitKind, HasObservers},
fuzzer::{Evaluator, EvaluatorObservers, ExecutionProcessor},
inputs::{Input, InputConverter, UsesInput},
stages::Stage,
state::{
HasClientPerfMonitor, HasCorpus, HasExecutions, HasMetadata, HasRand, HasTestcase,
UsesState,
},
state::{HasClientPerfMonitor, HasCorpus, HasExecutions, HasMetadata, HasRand, UsesState},
Error,
};

View File

@ -22,7 +22,7 @@ use crate::{
rands::Rand,
serdeany::{NamedSerdeAnyMap, SerdeAny, SerdeAnyMap},
},
corpus::{Corpus, CorpusId, Testcase},
corpus::{Corpus, CorpusId, HasTestcase, Testcase},
events::{Event, EventFirer, LogSeverity},
feedbacks::Feedback,
fuzzer::{Evaluator, ExecuteInputResult},
@ -219,22 +219,6 @@ pub trait HasStartTime {
fn start_time_mut(&mut self) -> &mut Duration;
}
/// Trait for the testcase
pub trait HasTestcase: HasCorpus {
/// To get the testcase
fn testcase(&self, id: CorpusId) -> Result<Ref<Testcase<<Self as UsesInput>::Input>>, Error> {
Ok(self.corpus().get(id)?.borrow())
}
/// To get mutable testcase
fn testcase_mut(
&self,
id: CorpusId,
) -> Result<RefMut<Testcase<<Self as UsesInput>::Input>>, Error> {
Ok(self.corpus().get(id)?.borrow_mut())
}
}
/// The state a fuzz run.
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(bound = "
@ -324,6 +308,26 @@ where
}
}
impl<I, C, R, SC> HasTestcase for StdState<I, C, R, SC>
where
I: Input,
C: Corpus<Input = <Self as UsesInput>::Input>,
R: Rand,
{
/// To get the testcase
fn testcase(&self, id: CorpusId) -> Result<Ref<Testcase<<Self as UsesInput>::Input>>, Error> {
Ok(self.corpus().get(id)?.borrow())
}
/// To get mutable testcase
fn testcase_mut(
&self,
id: CorpusId,
) -> Result<RefMut<Testcase<<Self as UsesInput>::Input>>, Error> {
Ok(self.corpus().get(id)?.borrow_mut())
}
}
impl<I, C, R, SC> HasSolutions for StdState<I, C, R, SC>
where
I: Input,

View File

@ -23,5 +23,5 @@ fn main() {
}
}
log::info!("{}", fuzzers.join("\n"));
println!("{}", fuzzers.join("\n"));
}

View File

@ -9,7 +9,7 @@ extern "C" {
/// Hooked `exit` function
#[no_mangle]
pub extern "C" fn exit(status: i32) {
log::info!("DeExit: The target called exit with status code {status}");
println!("DeExit: The target called exit with status code {status}");
unsafe {
abort();
}

View File

@ -165,7 +165,7 @@ fn prepare_transitions(
state_stacks.s.insert(dest, state_stack_sorted);
pda.push(transition);
log::info!("worklist size: {}", worklist.len());
println!("worklist size: {}", worklist.len());
*state_count += 1;
// i += 1;
@ -193,10 +193,10 @@ fn postprocess(pda: &[Transition], stack_limit: usize) -> Automaton {
assert!(initial.len() == 1);
log::info!("# transitions: {}", pda.len());
log::info!("# states: {}", states.len());
log::info!("initial state: {:?}", &initial);
log::info!("final states: {:?}", &finals);
println!("# transitions: {}", pda.len());
println!("# states: {}", states.len());
println!("initial state: {:?}", &initial);
println!("final states: {:?}", &finals);
let mut memoized = Vec::with_capacity(states.len());
//let mut memoized_unique = Vec::with_capacity(states.len());
@ -238,7 +238,7 @@ fn postprocess(pda: &[Transition], stack_limit: usize) -> Automaton {
});
if num_transition % 4096 == 0 {
log::info!(
println!(
"processed {} transitions over {}",
num_transition,
culled_pda.len()
@ -279,7 +279,7 @@ fn postprocess(pda: &[Transition], stack_limit: usize) -> Automaton {
});
if num_transition % 4096 == 0 {
log::info!(
println!(
"processed {} transitions over {}",
num_transition,
pda.len()