Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 63 additions & 2 deletions crates/libafl/src/corpus/inmemory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,9 @@ impl<I> TestcaseStorage<I> {
id
}

/// Insert a testcase with a specific `CorpusId`. Handle with care!
#[cfg(not(feature = "corpus_btreemap"))]
fn insert_inner_with_id(
pub fn insert_inner_with_id(
&mut self,
testcase: RefCell<Testcase<I>>,
is_disabled: bool,
Expand Down Expand Up @@ -325,8 +326,9 @@ impl<I> TestcaseStorage<I> {
Ok(())
}

/// Insert a testcase with a specific `CorpusId`. Handle with care!
#[cfg(feature = "corpus_btreemap")]
fn insert_inner_with_id(
pub fn insert_inner_with_id(
&mut self,
testcase: RefCell<Testcase<I>>,
is_disabled: bool,
Expand Down Expand Up @@ -716,4 +718,63 @@ mod tests {

Ok(())
}

#[test]
#[cfg(not(feature = "corpus_btreemap"))]
fn test_corpus_linked_list_integrity() -> Result<(), Error> {
let (mut corpus, ids) = setup_corpus();
// ids: [0, 1, 2]
// Enabled: 0 -> 1 -> 2
// First: 0, Last: 2

assert_eq!(corpus.first(), Some(ids[0]));
assert_eq!(corpus.last(), Some(ids[2]));
assert_eq!(corpus.next(ids[0]), Some(ids[1]));
assert_eq!(corpus.next(ids[1]), Some(ids[2]));
assert_eq!(corpus.next(ids[2]), None);
assert_eq!(corpus.prev(ids[0]), None);
assert_eq!(corpus.prev(ids[1]), Some(ids[0]));
assert_eq!(corpus.prev(ids[2]), Some(ids[1]));

// Disable first (0)
corpus.disable(ids[0])?;
// Enabled: 1 -> 2
// Disabled: 0
assert_eq!(corpus.first(), Some(ids[1]));
assert_eq!(corpus.last(), Some(ids[2]));
assert_eq!(corpus.prev(ids[1]), None);
assert_eq!(corpus.next(ids[1]), Some(ids[2]));

// Disable last (2)
corpus.disable(ids[2])?;
// Enabled: 1
// Disabled: 0 -> 2
assert_eq!(corpus.first(), Some(ids[1]));
assert_eq!(corpus.last(), Some(ids[1]));
assert_eq!(corpus.prev(ids[1]), None);
assert_eq!(corpus.next(ids[1]), None);

// Disable remaining (1)
corpus.disable(ids[1])?;
// Enabled: (empty)
// Disabled: 0 -> 2 -> 1
assert_eq!(corpus.first(), None);
assert_eq!(corpus.last(), None);

// Enable 0
corpus.enable(ids[0])?;
// Enabled: 0
assert_eq!(corpus.first(), Some(ids[0]));
assert_eq!(corpus.last(), Some(ids[0]));

// Enable 1
corpus.enable(ids[1])?;
// Enabled: 0 -> 1
assert_eq!(corpus.first(), Some(ids[0]));
assert_eq!(corpus.last(), Some(ids[1]));
assert_eq!(corpus.next(ids[0]), Some(ids[1]));
assert_eq!(corpus.prev(ids[1]), Some(ids[0]));

Ok(())
}
}
6 changes: 4 additions & 2 deletions crates/libafl/src/corpus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,12 @@ pub trait HasCurrentCorpusId {
/// Set the current corpus index; we have started processing this corpus entry
fn set_corpus_id(&mut self, id: CorpusId) -> Result<(), Error>;

/// Clear the current corpus index; we are done with this entry
/// Clear the current corpus index; we are done with this entry.
/// This can also be used by as stage to signal that subsequent stages should be skipped.
fn clear_corpus_id(&mut self) -> Result<(), Error>;

/// Fetch the current corpus index -- typically used after a state recovery or transfer
/// Fetch the current corpus index -- typically used after a state recovery or transfer.
/// If it is `None`, the corpus scheduler should be called to schedule the next testcase.
fn current_corpus_id(&self) -> Result<Option<CorpusId>, Error>;
}

Expand Down
2 changes: 1 addition & 1 deletion crates/libafl/src/corpus/testcase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ impl<I> Testcase<I> {

/// Get `disabled`
#[inline]
pub fn disabled(&mut self) -> bool {
pub fn disabled(&self) -> bool {
self.disabled
}

Expand Down
2 changes: 0 additions & 2 deletions crates/libafl/src/events/simple.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//! A very simple event manager, that just supports log outputs, but no multiprocessing

use alloc::vec::Vec;
#[cfg(feature = "std")]
use core::sync::atomic::{Ordering, compiler_fence};
Expand Down Expand Up @@ -189,7 +188,6 @@ impl<I, MT, S> SimpleEventManager<I, MT, S>
where
I: Debug,
MT: Monitor,
S: Stoppable,
{
/// Creates a new [`SimpleEventManager`].
pub fn new(monitor: MT) -> Self {
Expand Down
48 changes: 27 additions & 21 deletions crates/libafl/src/executors/forkserver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,26 +119,30 @@ const FAILED_TO_START_FORKSERVER_MSG: &str = "Failed to start forkserver";
fn report_error_and_exit(status: i32) -> Result<(), Error> {
/* Report on the error received via the forkserver controller and exit */
match status {
FS_ERROR_MAP_SIZE =>
Err(Error::unknown(
format!(
"{AFL_MAP_SIZE_ENV_VAR} is not set and fuzzing target reports that the required size is very large. Solution: Run the fuzzing target stand-alone with the environment variable AFL_DEBUG=1 set and set the value for __afl_final_loc in the {AFL_MAP_SIZE_ENV_VAR} environment variable for afl-fuzz."))),
FS_ERROR_MAP_ADDR =>
Err(Error::unknown(
"the fuzzing target reports that hardcoded map address might be the reason the mmap of the shared memory failed. Solution: recompile the target with either afl-clang-lto and do not set AFL_LLVM_MAP_ADDR or recompile with afl-clang-fast.".to_string())),
FS_ERROR_SHM_OPEN =>
Err(Error::unknown("the fuzzing target reports that the shm_open() call failed.".to_string())),
FS_ERROR_SHMAT =>
Err(Error::unknown("the fuzzing target reports that the shmat() call failed.".to_string())),
FS_ERROR_MMAP =>
Err(Error::unknown("the fuzzing target reports that the mmap() call to the shared memory failed.".to_string())),
FS_ERROR_OLD_CMPLOG =>
Err(Error::unknown(
"the -c cmplog target was instrumented with an too old AFL++ version, you need to recompile it.".to_string())),
FS_ERROR_OLD_CMPLOG_QEMU =>
Err(Error::unknown("The AFL++ QEMU/FRIDA loaders are from an older version, for -c you need to recompile it.".to_string())),
_ =>
Err(Error::unknown(format!("unknown error code {status} from fuzzing target!"))),
FS_ERROR_MAP_SIZE => Err(Error::unknown(format!(
"{AFL_MAP_SIZE_ENV_VAR} is not set and fuzzing target reports that the required size is very large. Solution: Run the fuzzing target stand-alone with the environment variable AFL_DEBUG=1 set and set the value for __afl_final_loc in the {AFL_MAP_SIZE_ENV_VAR} environment variable for afl-fuzz."
))),
FS_ERROR_MAP_ADDR => Err(Error::unknown(
"the fuzzing target reports that hardcoded map address might be the reason the mmap of the shared memory failed. Solution: recompile the target with either afl-clang-lto and do not set AFL_LLVM_MAP_ADDR or recompile with afl-clang-fast.",
)),
FS_ERROR_SHM_OPEN => Err(Error::unknown(
"the fuzzing target reports that the shm_open() call failed.",
)),
FS_ERROR_SHMAT => Err(Error::unknown(
"the fuzzing target reports that the shmat() call failed.",
)),
FS_ERROR_MMAP => Err(Error::unknown(
"the fuzzing target reports that the mmap() call to the shared memory failed.",
)),
FS_ERROR_OLD_CMPLOG => Err(Error::unknown(
"the -c cmplog target was instrumented with an too old AFL++ version, you need to recompile it.",
)),
FS_ERROR_OLD_CMPLOG_QEMU => Err(Error::unknown(
"The AFL++ QEMU/FRIDA loaders are from an older version, for -c you need to recompile it.",
)),
_ => Err(Error::unknown(format!(
"unknown error code {status} from fuzzing target!"
))),
}
}

Expand Down Expand Up @@ -422,7 +426,9 @@ impl Forkserver {
};

if env::var(SHM_ENV_VAR).is_err() {
return Err(Error::unknown("__AFL_SHM_ID not set. It is necessary to set this env, otherwise the forkserver cannot communicate with the fuzzer".to_string()));
return Err(Error::unknown(
"__AFL_SHM_ID not set. It is necessary to set this env, otherwise the forkserver cannot communicate with the fuzzer",
));
}

let afl_debug = if let Ok(afl_debug) = env::var("AFL_DEBUG") {
Expand Down
3 changes: 3 additions & 0 deletions crates/libafl/src/executors/inprocess/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,8 @@ pub fn run_observers_and_save_state<E, EM, I, OF, S, Z>(
#[cfg(test)]
mod tests {
use libafl_bolts::{rands::XkcdRand, tuples::tuple_list};
#[cfg(feature = "serial_test")]
use serial_test::serial;

use crate::{
StdFuzzer,
Expand All @@ -401,6 +403,7 @@ mod tests {
};

#[test]
#[cfg_attr(feature = "std", serial)]
fn test_inmem_exec() {
let mut harness = |_buf: &NopInput| ExitKind::Ok;
let rand = XkcdRand::new();
Expand Down
2 changes: 2 additions & 0 deletions crates/libafl/src/fuzzer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1409,6 +1409,7 @@ mod tests {
use core::cell::RefCell;

use libafl_bolts::rands::StdRand;
use serial_test::serial;

use crate::{
StdFuzzer,
Expand All @@ -1422,6 +1423,7 @@ mod tests {
};

#[test]
#[serial]
fn filtered_execution() {
let execution_count = RefCell::new(0);
let scheduler = StdScheduler::new();
Expand Down
2 changes: 2 additions & 0 deletions crates/libafl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ mod tests {
rands::{RomuDuoJrRand, StdRand},
tuples::tuple_list,
};
use serial_test::serial;

#[cfg(miri)]
use crate::stages::ExecutionCountRestartHelperMetadata;
Expand All @@ -127,6 +128,7 @@ mod tests {
};

#[test]
#[serial]
fn test_fuzzer() {
// # Safety
// No concurrency per testcase
Expand Down
4 changes: 2 additions & 2 deletions crates/libafl/src/observers/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ pub use owned_map::*;
/// # &mut feedback,
/// # &mut (),
/// # ).unwrap();
/// let scheduler = IndexesLenTimeMinimizerScheduler::new(&edges_observer, QueueScheduler::new());
/// # scheduler.cull(&state).unwrap();
/// let mut scheduler = IndexesLenTimeMinimizerScheduler::new(&edges_observer, QueueScheduler::new());
/// # scheduler.cull(&mut state).unwrap();
/// ```
///
/// [`MapObserver`] implementors: see [`StdMapObserver`] for an example implementation.
Expand Down
4 changes: 2 additions & 2 deletions crates/libafl/src/schedulers/accounting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
corpus::{Corpus, CorpusId},
observers::CanTrack,
schedulers::{
Scheduler,
RemovableScheduler, Scheduler,
minimizer::{DEFAULT_SKIP_NON_FAVORED_PROB, IsFavoredMetadata, MinimizerScheduler},
},
state::{HasCorpus, HasRand},
Expand Down Expand Up @@ -112,7 +112,7 @@ pub struct CoverageAccountingScheduler<'a, CS, I, O> {

impl<CS, I, O, S> Scheduler<I, S> for CoverageAccountingScheduler<'_, CS, I, O>
where
CS: Scheduler<I, S>,
CS: Scheduler<I, S> + RemovableScheduler<I, S>,
S: HasCorpus<I> + HasMetadata + HasRand,
I: HasLen,
O: CanTrack,
Expand Down
Loading
Loading