diff --git a/docs/src/DEBUGGING.md b/docs/src/DEBUGGING.md index 06f1abefcc..7492c3f827 100644 --- a/docs/src/DEBUGGING.md +++ b/docs/src/DEBUGGING.md @@ -25,5 +25,5 @@ You should *never* use the `EDGES_MAP`'s size as this is just the size of the al ## Q. I still have problems with my fuzzer. Finally, if you really have no idea what is going on, run your fuzzer with logging enabled. (You can use `env_logger`, `SimpleStdoutLogger`, `SimpleStderrLogger` from `libafl_bolts`. `fuzzbench_text` has an example to show how to use it.) (Don't forget to enable stdout and stderr), and you can open an issue or ask us in Discord. -## My fuzzer died of `Fuzzer-respawner: Storing state in crashed fuzzer instance did not work, no point to spawn the next client! This can happen if the child calls `exit()`, in that case make sure it uses `abort()`, if it got killed unrecoverable (OOM), or if there is a bug in the fuzzer itself. (Child exited with: 0)`. +## My fuzzer died of ``Storing state in crashed fuzzer instance did not work''. If the exit code is zero, then this is because either your harness exited or you are using fuzzer_loop_for and forgot to add `mgr.on_restart` at the end of the fuzzer. In the first case, you should patch your harness not to exit. (or use `utils/deexit`). diff --git a/docs/src/core_concepts/executor.md b/docs/src/core_concepts/executor.md index 6f2146d3eb..1a677b6ef9 100644 --- a/docs/src/core_concepts/executor.md +++ b/docs/src/core_concepts/executor.md @@ -57,7 +57,7 @@ On your fuzzer side, you can allocate a shared memory region and make the `EDGES ```rust,ignore let mut shmem; unsafe{ - shmem = StdShMemProvider::new().unwrap().new_shmem(MAX_EDGES_NUM).unwrap(); + shmem = StdShMemProvider::new().unwrap().new_shmem(EDGES_MAP_SIZE_IN_USE).unwrap(); } let shmem_buf = shmem.as_slice_mut(); unsafe{ diff --git a/docs/src/design/migration-0.9.md b/docs/src/design/migration-0.9.md index 64c961c53f..b48c3e7711 100644 --- a/docs/src/design/migration-0.9.md +++ b/docs/src/design/migration-0.9.md @@ -169,7 +169,7 @@ from libafl_target's `EDGES_MAP`. In the future, instead of using: ```rust,ignore -let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] }; +let edges = unsafe { &mut EDGES_MAP[0..EDGES_MAP_SIZE_IN_USE] }; let edges_observer = StdMapObserver::new("edges", edges); ``` diff --git a/fuzzers/baby_fuzzer_swap_differential/src/main.rs b/fuzzers/baby_fuzzer_swap_differential/src/main.rs index ac4e5846ca..cf5719006b 100644 --- a/fuzzers/baby_fuzzer_swap_differential/src/main.rs +++ b/fuzzers/baby_fuzzer_swap_differential/src/main.rs @@ -84,7 +84,7 @@ pub fn main() { } }; - let num_edges: usize = edges_max_num(); + let num_edges: usize = edges_max_num(); // upper bound #[cfg(feature = "multimap")] let ( @@ -202,7 +202,7 @@ pub fn main() { // The Monitor trait define how the fuzzer stats are displayed to the user #[cfg(not(feature = "tui"))] - let mon = SimpleMonitor::new(|s| println!("{s}")); + let mon = SimpleMonitor::with_user_monitor(|s| println!("{s}")); #[cfg(feature = "tui")] let ui = TuiUI::new(String::from("Baby Fuzzer"), false); #[cfg(feature = "tui")] diff --git a/fuzzers/fuzzbench_qemu/src/fuzzer.rs b/fuzzers/fuzzbench_qemu/src/fuzzer.rs index 795372f2c0..01da2df575 100644 --- a/fuzzers/fuzzbench_qemu/src/fuzzer.rs +++ b/fuzzers/fuzzbench_qemu/src/fuzzer.rs @@ -39,6 +39,7 @@ use libafl::{ use libafl_bolts::{ current_nanos, current_time, os::{dup2, unix_signals::Signal}, + ownedref::OwnedMutSlice, rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::{tuple_list, Merge}, @@ -47,9 +48,9 @@ use libafl_bolts::{ use libafl_qemu::{ // asan::{init_with_asan, QemuAsanHelper}, cmplog::{CmpLogObserver, QemuCmpLogHelper}, - edges::edges_map_mut_slice, + edges::edges_map_mut_ptr, edges::QemuEdgeCoverageHelper, - edges::MAX_EDGES_NUM, + edges::{EDGES_MAP_SIZE_IN_USE, MAX_EDGES_FOUND}, elf::EasyElf, filter_qemu_args, hooks::QemuHooks, @@ -257,8 +258,8 @@ fn fuzz( let edges_observer = unsafe { HitcountsMapObserver::new(VariableMapObserver::from_mut_slice( "edges", - edges_map_mut_slice(), - addr_of_mut!(MAX_EDGES_NUM), + OwnedMutSlice::from_raw_parts_mut(edges_map_mut_ptr(), EDGES_MAP_SIZE_IN_USE), + addr_of_mut!(MAX_EDGES_FOUND), )) .track_indices() }; diff --git a/fuzzers/libfuzzer_libpng/src/lib.rs b/fuzzers/libfuzzer_libpng/src/lib.rs index 977fdc8daf..b946617326 100644 --- a/fuzzers/libfuzzer_libpng/src/lib.rs +++ b/fuzzers/libfuzzer_libpng/src/lib.rs @@ -32,7 +32,7 @@ use libafl_bolts::{ tuples::{tuple_list, Merge}, AsSlice, }; -use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, EDGES_MAP, MAX_EDGES_NUM}; +use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, EDGES_MAP, MAX_EDGES_FOUND}; use mimalloc::MiMalloc; #[global_allocator] @@ -83,7 +83,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re HitcountsMapObserver::new(StdMapObserver::from_mut_ptr( "edges", EDGES_MAP.as_mut_ptr(), - MAX_EDGES_NUM, + MAX_EDGES_FOUND, )) .track_indices() }; diff --git a/fuzzers/libfuzzer_libpng_accounting/src/lib.rs b/fuzzers/libfuzzer_libpng_accounting/src/lib.rs index 2a7bd4f950..28005bfaa8 100644 --- a/fuzzers/libfuzzer_libpng_accounting/src/lib.rs +++ b/fuzzers/libfuzzer_libpng_accounting/src/lib.rs @@ -34,7 +34,8 @@ use libafl_bolts::{ AsSlice, }; use libafl_targets::{ - libfuzzer_initialize, libfuzzer_test_one_input, ACCOUNTING_MEMOP_MAP, EDGES_MAP, MAX_EDGES_NUM, + libfuzzer_initialize, libfuzzer_test_one_input, ACCOUNTING_MEMOP_MAP, EDGES_MAP, + MAX_EDGES_FOUND, }; use mimalloc::MiMalloc; @@ -139,7 +140,7 @@ pub extern "C" fn libafl_main() { let mut run_client = |state: Option<_>, mut restarting_mgr, _core_id| { // Create an observation channel using the coverage map let edges_observer = HitcountsMapObserver::new(unsafe { - StdMapObserver::from_mut_ptr("edges", EDGES_MAP.as_mut_ptr(), MAX_EDGES_NUM) + StdMapObserver::from_mut_ptr("edges", EDGES_MAP.as_mut_ptr(), MAX_EDGES_FOUND) }) .track_indices(); diff --git a/fuzzers/libfuzzer_libpng_aflpp_ui/src/lib.rs b/fuzzers/libfuzzer_libpng_aflpp_ui/src/lib.rs index 4241cb3ed7..04a231f974 100644 --- a/fuzzers/libfuzzer_libpng_aflpp_ui/src/lib.rs +++ b/fuzzers/libfuzzer_libpng_aflpp_ui/src/lib.rs @@ -32,7 +32,7 @@ use libafl_bolts::{ tuples::{tuple_list, Merge}, AsSlice, }; -use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, EDGES_MAP, MAX_EDGES_NUM}; +use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, EDGES_MAP, MAX_EDGES_FOUND}; use mimalloc::MiMalloc; #[global_allocator] @@ -97,7 +97,7 @@ fn fuzz( HitcountsMapObserver::new(StdMapObserver::from_mut_ptr( "edges", EDGES_MAP.as_mut_ptr(), - MAX_EDGES_NUM, + MAX_EDGES_FOUND, )) .track_indices() }; diff --git a/fuzzers/libfuzzer_libpng_tcp_manager/src/lib.rs b/fuzzers/libfuzzer_libpng_tcp_manager/src/lib.rs index 17a47cffed..0f1ef35f47 100644 --- a/fuzzers/libfuzzer_libpng_tcp_manager/src/lib.rs +++ b/fuzzers/libfuzzer_libpng_tcp_manager/src/lib.rs @@ -32,7 +32,7 @@ use libafl_bolts::{ tuples::{tuple_list, Merge}, AsSlice, }; -use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, EDGES_MAP, MAX_EDGES_NUM}; +use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, EDGES_MAP, MAX_EDGES_FOUND}; use mimalloc::MiMalloc; #[global_allocator] @@ -81,7 +81,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re HitcountsMapObserver::new(StdMapObserver::from_mut_ptr( "edges", EDGES_MAP.as_mut_ptr(), - MAX_EDGES_NUM, + MAX_EDGES_FOUND, )) .track_indices() }; diff --git a/fuzzers/qemu_launcher/Cargo.toml b/fuzzers/qemu_launcher/Cargo.toml index cfddf33e39..30c23a3026 100644 --- a/fuzzers/qemu_launcher/Cargo.toml +++ b/fuzzers/qemu_launcher/Cargo.toml @@ -38,7 +38,7 @@ vergen = { version = "8.2.1", features = ["build", "cargo", "git", "gitcl", "rus [dependencies] clap = { version = "4.3.0", features = ["derive", "string"]} libafl = { path = "../../libafl/" } -libafl_bolts = { path = "../../libafl_bolts/" } +libafl_bolts = { path = "../../libafl_bolts/", features = ["errors_backtrace"] } libafl_qemu = { path = "../../libafl_qemu/", features = ["usermode"] } log = {version = "0.4.20" } nix = { version = "0.27", features = ["fs"] } diff --git a/fuzzers/qemu_launcher/src/instance.rs b/fuzzers/qemu_launcher/src/instance.rs index 379da0c9cd..079ee7239e 100644 --- a/fuzzers/qemu_launcher/src/instance.rs +++ b/fuzzers/qemu_launcher/src/instance.rs @@ -34,12 +34,13 @@ use libafl_bolts::shmem::StdShMemProvider; use libafl_bolts::{ core_affinity::CoreId, current_nanos, + ownedref::OwnedMutSlice, rands::StdRand, tuples::{tuple_list, Merge}, }; use libafl_qemu::{ cmplog::CmpLogObserver, - edges::{edges_map_mut_slice, MAX_EDGES_NUM}, + edges::{edges_map_mut_ptr, EDGES_MAP_SIZE_IN_USE, MAX_EDGES_FOUND}, helpers::QemuHelperTuple, Qemu, QemuExecutor, QemuHooks, }; @@ -78,8 +79,8 @@ impl<'a, M: Monitor> Instance<'a, M> { let edges_observer = unsafe { HitcountsMapObserver::new(VariableMapObserver::from_mut_slice( "edges", - edges_map_mut_slice(), - addr_of_mut!(MAX_EDGES_NUM), + OwnedMutSlice::from_raw_parts_mut(edges_map_mut_ptr(), EDGES_MAP_SIZE_IN_USE), + addr_of_mut!(MAX_EDGES_FOUND), )) .track_indices() }; diff --git a/fuzzers/qemu_systemmode/src/fuzzer_breakpoint.rs b/fuzzers/qemu_systemmode/src/fuzzer_breakpoint.rs index 03143fd91f..167cc58da8 100644 --- a/fuzzers/qemu_systemmode/src/fuzzer_breakpoint.rs +++ b/fuzzers/qemu_systemmode/src/fuzzer_breakpoint.rs @@ -22,6 +22,7 @@ use libafl::{ use libafl_bolts::{ core_affinity::Cores, current_nanos, + ownedref::OwnedMutSlice, rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::tuple_list, @@ -29,7 +30,7 @@ use libafl_bolts::{ use libafl_qemu::{ breakpoint::Breakpoint, command::{Command, EmulatorMemoryChunk, EndCommand, StartCommand}, - edges::{edges_map_mut_slice, QemuEdgeCoverageHelper, MAX_EDGES_NUM}, + edges::{edges_map_mut_ptr, QemuEdgeCoverageHelper, EDGES_MAP_SIZE_IN_USE, MAX_EDGES_FOUND}, elf::EasyElf, emu::Emulator, executor::{stateful::StatefulQemuExecutor, QemuExecutorState}, @@ -154,8 +155,8 @@ pub fn fuzz() { let edges_observer = unsafe { HitcountsMapObserver::new(VariableMapObserver::from_mut_slice( "edges", - edges_map_mut_slice(), - addr_of_mut!(MAX_EDGES_NUM), + OwnedMutSlice::from_raw_parts_mut(edges_map_mut_ptr(), EDGES_MAP_SIZE_IN_USE), + addr_of_mut!(MAX_EDGES_FOUND), )) .track_indices() }; diff --git a/fuzzers/qemu_systemmode/src/fuzzer_classic.rs b/fuzzers/qemu_systemmode/src/fuzzer_classic.rs index 7276b9a606..44e964e621 100644 --- a/fuzzers/qemu_systemmode/src/fuzzer_classic.rs +++ b/fuzzers/qemu_systemmode/src/fuzzer_classic.rs @@ -23,13 +23,14 @@ use libafl_bolts::{ core_affinity::Cores, current_nanos, os::unix_signals::Signal, + ownedref::OwnedMutSlice, rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::tuple_list, AsSlice, }; use libafl_qemu::{ - edges::{edges_map_mut_slice, QemuEdgeCoverageHelper, MAX_EDGES_NUM}, + edges::{edges_map_mut_ptr, QemuEdgeCoverageHelper, EDGES_MAP_SIZE_IN_USE, MAX_EDGES_FOUND}, elf::EasyElf, emu::Qemu, QemuExecutor, QemuExitReason, QemuExitReasonError, QemuHooks, QemuShutdownCause, Regs, @@ -161,8 +162,8 @@ pub fn fuzz() { let edges_observer = unsafe { HitcountsMapObserver::new(VariableMapObserver::from_mut_slice( "edges", - edges_map_mut_slice(), - addr_of_mut!(MAX_EDGES_NUM), + OwnedMutSlice::from_raw_parts_mut(edges_map_mut_ptr(), EDGES_MAP_SIZE_IN_USE), + addr_of_mut!(MAX_EDGES_FOUND), )) .track_indices() }; diff --git a/fuzzers/qemu_systemmode/src/fuzzer_sync_exit.rs b/fuzzers/qemu_systemmode/src/fuzzer_sync_exit.rs index c792e8e29d..1e5cd25733 100644 --- a/fuzzers/qemu_systemmode/src/fuzzer_sync_exit.rs +++ b/fuzzers/qemu_systemmode/src/fuzzer_sync_exit.rs @@ -22,12 +22,13 @@ use libafl::{ use libafl_bolts::{ core_affinity::Cores, current_nanos, + ownedref::OwnedMutSlice, rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::tuple_list, }; use libafl_qemu::{ - edges::{edges_map_mut_slice, QemuEdgeCoverageHelper, MAX_EDGES_NUM}, + edges::{edges_map_mut_ptr, QemuEdgeCoverageHelper, EDGES_MAP_SIZE_IN_USE, MAX_EDGES_FOUND}, emu::Emulator, executor::{stateful::StatefulQemuExecutor, QemuExecutorState}, EmuExitReasonError, FastSnapshotManager, HandlerError, HandlerResult, QemuHooks, @@ -95,8 +96,8 @@ pub fn fuzz() { let edges_observer = unsafe { HitcountsMapObserver::new(VariableMapObserver::from_mut_slice( "edges", - edges_map_mut_slice(), - addr_of_mut!(MAX_EDGES_NUM), + OwnedMutSlice::from_raw_parts_mut(edges_map_mut_ptr(), EDGES_MAP_SIZE_IN_USE), + addr_of_mut!(MAX_EDGES_FOUND), )) .track_indices() }; diff --git a/libafl_qemu/src/helpers/edges.rs b/libafl_qemu/src/helpers/edges.rs index 3debbe46a1..097d4d3c4c 100644 --- a/libafl_qemu/src/helpers/edges.rs +++ b/libafl_qemu/src/helpers/edges.rs @@ -6,8 +6,8 @@ use libafl_qemu_sys::GuestAddr; #[cfg(emulation_mode = "systemmode")] use libafl_qemu_sys::GuestPhysAddr; pub use libafl_targets::{ - edges_map_mut_ptr, edges_map_mut_slice, edges_max_num, std_edges_map_observer, EDGES_MAP, - EDGES_MAP_PTR, EDGES_MAP_PTR_NUM, EDGES_MAP_SIZE_IN_USE, MAX_EDGES_NUM, + edges_map_mut_ptr, EDGES_MAP, EDGES_MAP_PTR, EDGES_MAP_SIZE_IN_USE, EDGES_MAP_SIZE_MAX, + MAX_EDGES_FOUND, }; use serde::{Deserialize, Serialize}; @@ -553,18 +553,18 @@ where match meta.map.entry((src, dest)) { Entry::Occupied(e) => { let id = *e.get(); - let nxt = (id as usize + 1) & (EDGES_MAP_SIZE_IN_USE - 1); + let nxt = (id as usize + 1) & (EDGES_MAP_SIZE_MAX - 1); unsafe { - MAX_EDGES_NUM = max(MAX_EDGES_NUM, nxt); + MAX_EDGES_FOUND = max(MAX_EDGES_FOUND, nxt); } Some(id) } Entry::Vacant(e) => { let id = meta.current_id; e.insert(id); - meta.current_id = (id + 1) & (EDGES_MAP_SIZE_IN_USE as u64 - 1); + meta.current_id = (id + 1) & (EDGES_MAP_SIZE_MAX as u64 - 1); unsafe { - MAX_EDGES_NUM = meta.current_id as usize; + MAX_EDGES_FOUND = meta.current_id as usize; } // GuestAddress is u32 for 32 bit guests #[allow(clippy::unnecessary_cast)] @@ -619,7 +619,7 @@ where } // GuestAddress is u32 for 32 bit guests #[allow(clippy::unnecessary_cast)] - Some((hash_me(src as u64) ^ hash_me(dest as u64)) & (unsafe { EDGES_MAP_PTR_NUM } as u64 - 1)) + Some((hash_me(src as u64) ^ hash_me(dest as u64)) & (EDGES_MAP_SIZE_MAX as u64 - 1)) } pub extern "C" fn trace_edge_hitcount_ptr(_: *const (), id: u64) { @@ -692,7 +692,7 @@ where pub extern "C" fn trace_block_transition_hitcount(_: *const (), id: u64) { unsafe { PREV_LOC.with(|prev_loc| { - let x = ((*prev_loc.get() ^ id) as usize) & (EDGES_MAP_PTR_NUM - 1); + let x = ((*prev_loc.get() ^ id) as usize) & (EDGES_MAP_SIZE_MAX - 1); let entry = EDGES_MAP_PTR.add(x); *entry = (*entry).wrapping_add(1); *prev_loc.get() = id.overflowing_shr(1).0; @@ -703,7 +703,7 @@ pub extern "C" fn trace_block_transition_hitcount(_: *const (), id: u64) { pub extern "C" fn trace_block_transition_single(_: *const (), id: u64) { unsafe { PREV_LOC.with(|prev_loc| { - let x = ((*prev_loc.get() ^ id) as usize) & (EDGES_MAP_PTR_NUM - 1); + let x = ((*prev_loc.get() ^ id) as usize) & (EDGES_MAP_SIZE_MAX - 1); let entry = EDGES_MAP_PTR.add(x); *entry = 1; *prev_loc.get() = id.overflowing_shr(1).0; diff --git a/libafl_sugar/src/inmemory.rs b/libafl_sugar/src/inmemory.rs index d89e77f7f2..34fbefa923 100644 --- a/libafl_sugar/src/inmemory.rs +++ b/libafl_sugar/src/inmemory.rs @@ -18,7 +18,7 @@ use libafl::{ scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator}, token_mutations::{I2SRandReplace, Tokens}, }, - observers::{CanTrack, HitcountsMapObserver, TimeObserver}, + observers::{CanTrack, HitcountsMapObserver, StdMapObserver, TimeObserver}, schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, stages::{ShadowTracingStage, StdMutationalStage}, state::{HasCorpus, StdState}, @@ -27,12 +27,13 @@ use libafl::{ use libafl_bolts::{ core_affinity::Cores, current_nanos, + ownedref::OwnedMutSlice, rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::{tuple_list, Merge, Referenceable}, AsSlice, }; -use libafl_targets::{std_edges_map_observer, CmpLogObserver}; +use libafl_targets::{edges_map_mut_ptr, CmpLogObserver}; use typed_builder::TypedBuilder; use crate::{CORPUS_CACHE_SIZE, DEFAULT_TIMEOUT_SECS}; @@ -72,6 +73,9 @@ where /// Bytes harness #[builder(setter(strip_option))] harness: Option, + /// The map size used for the fuzzer + #[builder(default = 65536usize)] + map_size: usize, /// Fuzz `iterations` number of times, instead of indefinitely; implies use of `fuzz_loop_for` #[builder(default = None)] iterations: Option, @@ -148,9 +152,13 @@ where let time_observer = time_observer.clone(); // Create an observation channel using the coverage map - let edges_observer = - HitcountsMapObserver::new(unsafe { std_edges_map_observer("edges") }) - .track_indices(); + let edges_observer = HitcountsMapObserver::new(unsafe { + StdMapObserver::from_mut_slice( + "edges", + OwnedMutSlice::from_raw_parts_mut(edges_map_mut_ptr(), self.map_size), + ) + }) + .track_indices(); let cmplog_observer = CmpLogObserver::new("cmplog", true); diff --git a/libafl_sugar/src/qemu.rs b/libafl_sugar/src/qemu.rs index 56063d9622..a9d981bf67 100644 --- a/libafl_sugar/src/qemu.rs +++ b/libafl_sugar/src/qemu.rs @@ -30,6 +30,7 @@ use libafl::{ use libafl_bolts::{ core_affinity::Cores, current_nanos, + ownedref::OwnedMutSlice, rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::{tuple_list, Merge, Referenceable}, @@ -39,7 +40,7 @@ pub use libafl_qemu::emu::Qemu; #[cfg(not(any(feature = "mips", feature = "hexagon")))] use libafl_qemu::QemuCmpLogHelper; use libafl_qemu::{edges, QemuEdgeCoverageHelper, QemuExecutor, QemuHooks}; -use libafl_targets::{edges_map_mut_slice, CmpLogObserver}; +use libafl_targets::{edges_map_mut_ptr, CmpLogObserver}; use typed_builder::TypedBuilder; use crate::{CORPUS_CACHE_SIZE, DEFAULT_TIMEOUT_SECS}; @@ -159,8 +160,11 @@ where let edges_observer = unsafe { HitcountsMapObserver::new(VariableMapObserver::from_mut_slice( "edges", - edges_map_mut_slice(), - addr_of_mut!(edges::MAX_EDGES_NUM), + OwnedMutSlice::from_raw_parts_mut( + edges_map_mut_ptr(), + edges::EDGES_MAP_SIZE_IN_USE, + ), + addr_of_mut!(edges::MAX_EDGES_FOUND), )) .track_indices() }; diff --git a/libafl_targets/src/coverage.rs b/libafl_targets/src/coverage.rs index a578c2645a..1d7b88f0e0 100644 --- a/libafl_targets/src/coverage.rs +++ b/libafl_targets/src/coverage.rs @@ -1,5 +1,11 @@ //! Coverage maps as static mut array +#[cfg(any( + feature = "sancov_pcguard_edges", + feature = "sancov_pcguard_hitcounts", + feature = "sancov_ngram4", + feature = "sancov_ctx" +))] use alloc::borrow::Cow; #[cfg(any(target_os = "linux", target_vendor = "apple"))] @@ -22,8 +28,10 @@ pub use __ddg_area_ptr_local as DDG_MAP; pub static mut __afl_acc_memop_ptr_local: [u32; ACCOUNTING_MAP_SIZE] = [0; ACCOUNTING_MAP_SIZE]; pub use __afl_acc_memop_ptr_local as ACCOUNTING_MEMOP_MAP; -/// The max count of edges tracked. -pub static mut MAX_EDGES_NUM: usize = 0; +/// The max count of edges found. +/// This is either computed during the compilation time or at runtime (in this case this is used to shrink the map). +/// You can use this for the initial map size for the observer only if you compute this time at compilation time. +pub static mut MAX_EDGES_FOUND: usize = 0; extern "C" { /// The area pointer points to the edges map. @@ -60,21 +68,40 @@ pub fn autotokens() -> Result { } } -/// The size of the map for edges. +/// The actual size we use for the map of edges. +/// This is used for forkserver backend #[no_mangle] pub static mut __afl_map_size: usize = EDGES_MAP_SIZE_IN_USE; -pub use __afl_map_size as EDGES_MAP_PTR_NUM; + +#[cfg(any( + feature = "sancov_pcguard_edges", + feature = "sancov_pcguard_hitcounts", + feature = "sancov_ngram4", + feature = "sancov_ctx" +))] use libafl::observers::StdMapObserver; +#[cfg(any( + feature = "sancov_pcguard_edges", + feature = "sancov_pcguard_hitcounts", + feature = "sancov_ngram4", + feature = "sancov_ctx" +))] use libafl_bolts::ownedref::OwnedMutSlice; /// Gets the edges map from the `EDGES_MAP_PTR` raw pointer. -/// Assumes a `len` of `EDGES_MAP_PTR_NUM`. +/// Assumes a `len` of at least `EDGES_MAP_PTR_MAX`. /// /// # Safety /// /// This function will crash if `edges_map_mut_ptr` is not a valid pointer. /// The [`edges_max_num`] needs to be smaller than, or equal to the size of the map. #[must_use] +#[cfg(any( + feature = "sancov_pcguard_edges", + feature = "sancov_pcguard_hitcounts", + feature = "sancov_ngram4", + feature = "sancov_ctx" +))] pub unsafe fn edges_map_mut_slice<'a>() -> OwnedMutSlice<'a, u8> { OwnedMutSlice::from_raw_parts_mut(edges_map_mut_ptr(), edges_max_num()) } @@ -84,11 +111,11 @@ pub unsafe fn edges_map_mut_slice<'a>() -> OwnedMutSlice<'a, u8> { /// /// ```rust,ignore /// use libafl::observers::StdMapObserver; -/// use libafl_targets::{EDGES_MAP, MAX_EDGES_NUM}; +/// use libafl_targets::{EDGES_MAP, EDGES_MAP_SIZE_IN_USE}; /// /// #[cfg(not(feature = "pointer_maps"))] /// let observer = unsafe { -/// StdMapObserver::from_mut_ptr("edges", EDGES_MAP.as_mut_ptr(), MAX_EDGES_NUM) +/// StdMapObserver::from_mut_ptr("edges", EDGES_MAP.as_mut_ptr(), EDGES_MAP_SIZE_IN_USE) /// }; /// ``` /// @@ -106,6 +133,12 @@ pub unsafe fn edges_map_mut_slice<'a>() -> OwnedMutSlice<'a, u8> { /// /// # Safety /// This will dereference [`edges_map_mut_ptr`] and crash if it is not a valid address. +#[cfg(any( + feature = "sancov_pcguard_edges", + feature = "sancov_pcguard_hitcounts", + feature = "sancov_ngram4", + feature = "sancov_ctx" +))] pub unsafe fn std_edges_map_observer<'a, S>(name: S) -> StdMapObserver<'a, u8, false> where S: Into>, @@ -129,15 +162,21 @@ pub fn edges_map_mut_ptr() -> *mut u8 { } /// Gets the current maximum number of edges tracked. +#[cfg(any( + feature = "sancov_pcguard_edges", + feature = "sancov_pcguard_hitcounts", + feature = "sancov_ngram4", + feature = "sancov_ctx" +))] #[must_use] pub fn edges_max_num() -> usize { unsafe { - if MAX_EDGES_NUM > 0 { - MAX_EDGES_NUM + if MAX_EDGES_FOUND > 0 { + MAX_EDGES_FOUND } else { #[cfg(feature = "pointer_maps")] { - EDGES_MAP_PTR_NUM + EDGES_MAP_SIZE_MAX // the upper bound } #[cfg(not(feature = "pointer_maps"))] { @@ -163,7 +202,7 @@ mod swap { use libafl_bolts::{ownedref::OwnedMutSlice, AsSliceMut, Named}; use serde::{Deserialize, Serialize}; - use super::{EDGES_MAP_PTR, EDGES_MAP_PTR_NUM}; + use super::EDGES_MAP_PTR; /// Observer to be used with `DiffExecutor`s when executing a differential target that shares /// the AFL map in order to swap out the maps (and thus allow for map observing the two targets @@ -243,7 +282,6 @@ mod swap { let slice = self.first_map.as_slice_mut(); unsafe { EDGES_MAP_PTR = slice.as_mut_ptr(); - EDGES_MAP_PTR_NUM = slice.len(); } Ok(()) } @@ -252,7 +290,6 @@ mod swap { let slice = self.second_map.as_slice_mut(); unsafe { EDGES_MAP_PTR = slice.as_mut_ptr(); - EDGES_MAP_PTR_NUM = slice.len(); } Ok(()) } diff --git a/libafl_targets/src/sancov_pcguard.rs b/libafl_targets/src/sancov_pcguard.rs index e27cc1abc0..0d09dd084e 100644 --- a/libafl_targets/src/sancov_pcguard.rs +++ b/libafl_targets/src/sancov_pcguard.rs @@ -16,11 +16,11 @@ use libafl::executors::{hooks::ExecutorHook, HasObservers}; feature = "sancov_ngram4", ))] use crate::coverage::EDGES_MAP; -use crate::coverage::MAX_EDGES_NUM; -#[cfg(feature = "pointer_maps")] -use crate::coverage::{EDGES_MAP_PTR, EDGES_MAP_PTR_NUM}; +use crate::coverage::MAX_EDGES_FOUND; #[cfg(feature = "sancov_ngram4")] use crate::EDGES_MAP_SIZE_IN_USE; +#[cfg(feature = "pointer_maps")] +use crate::{coverage::EDGES_MAP_PTR, EDGES_MAP_SIZE_MAX}; #[cfg(all(feature = "sancov_pcguard_edges", feature = "sancov_pcguard_hitcounts"))] #[cfg(not(any(doc, feature = "clippy")))] @@ -263,7 +263,6 @@ pub unsafe extern "C" fn __sanitizer_cov_trace_pc_guard_init(mut start: *mut u32 #[cfg(feature = "pointer_maps")] if EDGES_MAP_PTR.is_null() { EDGES_MAP_PTR = EDGES_MAP.as_mut_ptr(); - EDGES_MAP_PTR_NUM = EDGES_MAP.len(); } if start == stop || *start != 0 { @@ -271,17 +270,17 @@ pub unsafe extern "C" fn __sanitizer_cov_trace_pc_guard_init(mut start: *mut u32 } while start < stop { - *start = MAX_EDGES_NUM as u32; + *start = MAX_EDGES_FOUND as u32; start = start.offset(1); #[cfg(feature = "pointer_maps")] { - MAX_EDGES_NUM = MAX_EDGES_NUM.wrapping_add(1) % EDGES_MAP_PTR_NUM; + MAX_EDGES_FOUND = MAX_EDGES_FOUND.wrapping_add(1) % EDGES_MAP_SIZE_MAX; } #[cfg(not(feature = "pointer_maps"))] { - MAX_EDGES_NUM = MAX_EDGES_NUM.wrapping_add(1); - assert!((MAX_EDGES_NUM <= EDGES_MAP.len()), "The number of edges reported by SanitizerCoverage exceed the size of the edges map ({}). Use the LIBAFL_EDGES_MAP_SIZE_IN_USE env to increase it at compile time.", EDGES_MAP.len()); + MAX_EDGES_FOUND = MAX_EDGES_FOUND.wrapping_add(1); + assert!((MAX_EDGES_FOUND <= EDGES_MAP.len()), "The number of edges reported by SanitizerCoverage exceed the size of the edges map ({}). Use the LIBAFL_EDGES_MAP_SIZE_IN_USE env to increase it at compile time.", EDGES_MAP.len()); } } }