diff --git a/fuzzers/baby/backtrace_baby_fuzzers/c_code_with_fork_executor/src/main.rs b/fuzzers/baby/backtrace_baby_fuzzers/c_code_with_fork_executor/src/main.rs index 6e2208626f..694aea946f 100644 --- a/fuzzers/baby/backtrace_baby_fuzzers/c_code_with_fork_executor/src/main.rs +++ b/fuzzers/baby/backtrace_baby_fuzzers/c_code_with_fork_executor/src/main.rs @@ -47,9 +47,11 @@ pub fn main() { }; // Create an observation channel using the signals map let observer = unsafe { - ConstMapObserver::::from_mut_ptr( + ConstMapObserver::from_mut_ptr( "signals", - NonNull::new(map_ptr).expect("map ptr is null."), + NonNull::new(map_ptr) + .expect("map ptr is null.") + .cast::<[u8; 3]>(), ) }; // Create a stacktrace observer diff --git a/fuzzers/baby/backtrace_baby_fuzzers/c_code_with_inprocess_executor/src/main.rs b/fuzzers/baby/backtrace_baby_fuzzers/c_code_with_inprocess_executor/src/main.rs index d638032324..88dece4d3e 100644 --- a/fuzzers/baby/backtrace_baby_fuzzers/c_code_with_inprocess_executor/src/main.rs +++ b/fuzzers/baby/backtrace_baby_fuzzers/c_code_with_inprocess_executor/src/main.rs @@ -36,9 +36,11 @@ pub fn main() { }; // Create an observation channel using the signals map let observer = unsafe { - ConstMapObserver::::from_mut_ptr( + ConstMapObserver::from_mut_ptr( "signals", - NonNull::new(array_ptr).expect("map ptr is null"), + NonNull::new(array_ptr) + .expect("map ptr is null") + .cast::<[u8; 3]>(), ) }; // Create a stacktrace observer diff --git a/fuzzers/binary_only/fuzzbench_fork_qemu/src/fuzzer.rs b/fuzzers/binary_only/fuzzbench_fork_qemu/src/fuzzer.rs index 8c89b4a6cc..589052f60b 100644 --- a/fuzzers/binary_only/fuzzbench_fork_qemu/src/fuzzer.rs +++ b/fuzzers/binary_only/fuzzbench_fork_qemu/src/fuzzer.rs @@ -159,9 +159,11 @@ fn fuzz( // Create an observation channel using the coverage map let mut edges_observer = unsafe { - HitcountsMapObserver::new(ConstMapObserver::<_, EDGES_MAP_DEFAULT_SIZE>::from_mut_ptr( + HitcountsMapObserver::new(ConstMapObserver::from_mut_ptr( "edges", - NonNull::new(edges.as_mut_ptr()).expect("map ptr is null."), + NonNull::new(edges.as_mut_ptr()) + .expect("map ptr is null.") + .cast::<[u8; EDGES_MAP_DEFAULT_SIZE]>(), )) .track_indices() }; diff --git a/fuzzers/binary_only/qemu_cmin/src/fuzzer.rs b/fuzzers/binary_only/qemu_cmin/src/fuzzer.rs index b0349c0522..ba00041efd 100644 --- a/fuzzers/binary_only/qemu_cmin/src/fuzzer.rs +++ b/fuzzers/binary_only/qemu_cmin/src/fuzzer.rs @@ -162,9 +162,11 @@ pub fn fuzz() -> Result<(), Error> { unsafe { EDGES_MAP_PTR = edges.as_mut_ptr() }; let mut edges_observer = unsafe { - HitcountsMapObserver::new(ConstMapObserver::<_, EDGES_MAP_DEFAULT_SIZE>::from_mut_ptr( + HitcountsMapObserver::new(ConstMapObserver::from_mut_ptr( "edges", - NonNull::new(edges.as_mut_ptr()).expect("The edge map pointer is null."), + NonNull::new(edges.as_mut_ptr()) + .expect("The edge map pointer is null.") + .cast::<[u8; EDGES_MAP_DEFAULT_SIZE]>(), )) }; diff --git a/fuzzers/structure_aware/baby_fuzzer_multi/Cargo.toml b/fuzzers/structure_aware/baby_fuzzer_multi/Cargo.toml index c349257686..daaf1b22cf 100644 --- a/fuzzers/structure_aware/baby_fuzzer_multi/Cargo.toml +++ b/fuzzers/structure_aware/baby_fuzzer_multi/Cargo.toml @@ -10,7 +10,7 @@ edition = "2021" [features] default = ["std"] -tui = [] +tui = ["libafl/tui_monitor"] std = [] [profile.dev] @@ -24,9 +24,6 @@ opt-level = 3 debug = true [dependencies] -libafl = { path = "../../../libafl", features = [ - "multipart_inputs", - "tui_monitor", -] } +libafl = { path = "../../../libafl", features = ["multipart_inputs"] } libafl_bolts = { path = "../../../libafl_bolts" } log = { version = "0.4.22", features = ["release_max_level_info"] } diff --git a/fuzzers/structure_aware/baby_fuzzer_multi/src/main.rs b/fuzzers/structure_aware/baby_fuzzer_multi/src/main.rs index dbcf35638a..2cda5ebebd 100644 --- a/fuzzers/structure_aware/baby_fuzzer_multi/src/main.rs +++ b/fuzzers/structure_aware/baby_fuzzer_multi/src/main.rs @@ -1,6 +1,6 @@ +use std::path::PathBuf; #[cfg(windows)] use std::ptr::write_volatile; -use std::{path::PathBuf, ptr::write}; #[cfg(feature = "tui")] use libafl::monitors::tui::TuiMonitor; @@ -15,25 +15,24 @@ use libafl::{ fuzzer::{Fuzzer, StdFuzzer}, inputs::{BytesInput, HasTargetBytes, MultipartInput}, mutators::{havoc_mutations::havoc_mutations, scheduled::StdScheduledMutator}, - observers::StdMapObserver, + observers::ConstMapObserver, schedulers::QueueScheduler, stages::mutational::StdMutationalStage, state::StdState, Evaluator, }; -use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice}; +use libafl_bolts::{nonnull_raw_mut, rands::StdRand, tuples::tuple_list, AsSlice}; /// Coverage map with explicit assignments due to the lack of instrumentation static mut SIGNALS: [u8; 128] = [0; 128]; -static mut SIGNALS_PTR: *mut u8 = unsafe { SIGNALS.as_mut_ptr() }; +static mut SIGNALS_PTR: *mut [u8; 128] = &raw mut SIGNALS; /// "Coverage" map for count, just to help things along static mut LAST_COUNT: [usize; 1] = [usize::MAX]; -static mut LAST_COUNT_PTR: *mut usize = unsafe { LAST_COUNT.as_mut_ptr() }; /// Assign a signal to the signals map fn signals_set(idx: usize) { - unsafe { write(SIGNALS_PTR.add(idx), 1) }; + unsafe { (*SIGNALS_PTR)[idx] = 1 }; } /// Assign a count to the count "map" @@ -83,9 +82,9 @@ pub fn main() { // Create an observation channel using the signals map let signals_observer = - unsafe { StdMapObserver::from_mut_ptr("signals", SIGNALS_PTR, SIGNALS.len()) }; + unsafe { ConstMapObserver::from_mut_ptr("signals", nonnull_raw_mut!(SIGNALS)) }; let mut count_observer = - unsafe { StdMapObserver::from_mut_ptr("count", LAST_COUNT_PTR, LAST_COUNT.len()) }; + unsafe { ConstMapObserver::from_mut_ptr("count", nonnull_raw_mut!(LAST_COUNT)) }; *count_observer.initial_mut() = usize::MAX; // we are minimising! // Feedback to rate the interestingness of an input diff --git a/libafl/src/observers/map/const_map.rs b/libafl/src/observers/map/const_map.rs index b84428949a..d383bc0cc3 100644 --- a/libafl/src/observers/map/const_map.rs +++ b/libafl/src/observers/map/const_map.rs @@ -199,11 +199,16 @@ where /// # Safety /// Will dereference the `map_ptr` with up to len elements. #[must_use] - pub unsafe fn from_mut_ptr(name: &'static str, map_ptr: NonNull) -> Self { + pub unsafe fn from_mut_ptr(name: &'static str, map_ptr: NonNull<[T; N]>) -> Self { ConstMapObserver { map: OwnedMutSizedSlice::from_raw_mut(map_ptr), name: Cow::from(name), initial: T::default(), } } + + /// Gets the initial value for this map, mutably + pub fn initial_mut(&mut self) -> &mut T { + &mut self.initial + } } diff --git a/libafl_bolts/src/lib.rs b/libafl_bolts/src/lib.rs index ebfee24327..0ea64b09c9 100644 --- a/libafl_bolts/src/lib.rs +++ b/libafl_bolts/src/lib.rs @@ -1122,6 +1122,18 @@ macro_rules! nonzero { }; } +/// Get a [`core::ptr::NonNull`] to a global static mut (or similar). +/// +/// The same as [`core::ptr::addr_of_mut`] or `&raw mut`, but wrapped in said [`NonNull`](core::ptr::NonNull). +#[macro_export] +macro_rules! nonnull_raw_mut { + ($val:expr) => { + // # Safety + // The pointer to a value will never be null (unless we're on an archaic OS in a CTF challenge). + unsafe { core::ptr::NonNull::new(&raw mut $val).unwrap_unchecked() } + }; +} + #[cfg(feature = "python")] #[allow(missing_docs)] pub mod pybind { diff --git a/libafl_bolts/src/ownedref.rs b/libafl_bolts/src/ownedref.rs index d176a8dc6e..f882554646 100644 --- a/libafl_bolts/src/ownedref.rs +++ b/libafl_bolts/src/ownedref.rs @@ -944,12 +944,9 @@ impl<'a, T: 'a + Sized, const N: usize> OwnedMutSizedSlice<'a, T, N> { /// The pointer must be valid and point to a map of the size `size_of() * N` /// The content will be dereferenced in subsequent operations. #[must_use] - pub unsafe fn from_raw_mut(ptr: NonNull) -> OwnedMutSizedSlice<'a, T, N> { + pub unsafe fn from_raw_mut(ptr: NonNull<[T; N]>) -> OwnedMutSizedSlice<'a, T, N> { Self { - inner: OwnedMutSizedSliceInner::RefRaw( - ptr.as_ptr() as *mut [T; N], - UnsafeMarker::new(), - ), + inner: OwnedMutSizedSliceInner::RefRaw(ptr.as_ptr(), UnsafeMarker::new()), } }