Actually make ConstMapObserver work, introduce nonnull_raw_mut
macro (#2687)
* Actually make ConstMapObserver work * fixes * does that work? * mas
This commit is contained in:
parent
d5db2c0e3f
commit
7938acc4ce
@ -47,9 +47,11 @@ pub fn main() {
|
|||||||
};
|
};
|
||||||
// Create an observation channel using the signals map
|
// Create an observation channel using the signals map
|
||||||
let observer = unsafe {
|
let observer = unsafe {
|
||||||
ConstMapObserver::<u8, 3>::from_mut_ptr(
|
ConstMapObserver::from_mut_ptr(
|
||||||
"signals",
|
"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
|
// Create a stacktrace observer
|
||||||
|
@ -36,9 +36,11 @@ pub fn main() {
|
|||||||
};
|
};
|
||||||
// Create an observation channel using the signals map
|
// Create an observation channel using the signals map
|
||||||
let observer = unsafe {
|
let observer = unsafe {
|
||||||
ConstMapObserver::<u8, 3>::from_mut_ptr(
|
ConstMapObserver::from_mut_ptr(
|
||||||
"signals",
|
"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
|
// Create a stacktrace observer
|
||||||
|
@ -159,9 +159,11 @@ fn fuzz(
|
|||||||
|
|
||||||
// Create an observation channel using the coverage map
|
// Create an observation channel using the coverage map
|
||||||
let mut edges_observer = unsafe {
|
let mut edges_observer = unsafe {
|
||||||
HitcountsMapObserver::new(ConstMapObserver::<_, EDGES_MAP_DEFAULT_SIZE>::from_mut_ptr(
|
HitcountsMapObserver::new(ConstMapObserver::from_mut_ptr(
|
||||||
"edges",
|
"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()
|
.track_indices()
|
||||||
};
|
};
|
||||||
|
@ -162,9 +162,11 @@ pub fn fuzz() -> Result<(), Error> {
|
|||||||
unsafe { EDGES_MAP_PTR = edges.as_mut_ptr() };
|
unsafe { EDGES_MAP_PTR = edges.as_mut_ptr() };
|
||||||
|
|
||||||
let mut edges_observer = unsafe {
|
let mut edges_observer = unsafe {
|
||||||
HitcountsMapObserver::new(ConstMapObserver::<_, EDGES_MAP_DEFAULT_SIZE>::from_mut_ptr(
|
HitcountsMapObserver::new(ConstMapObserver::from_mut_ptr(
|
||||||
"edges",
|
"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]>(),
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ edition = "2021"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
tui = []
|
tui = ["libafl/tui_monitor"]
|
||||||
std = []
|
std = []
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
@ -24,9 +24,6 @@ opt-level = 3
|
|||||||
debug = true
|
debug = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libafl = { path = "../../../libafl", features = [
|
libafl = { path = "../../../libafl", features = ["multipart_inputs"] }
|
||||||
"multipart_inputs",
|
|
||||||
"tui_monitor",
|
|
||||||
] }
|
|
||||||
libafl_bolts = { path = "../../../libafl_bolts" }
|
libafl_bolts = { path = "../../../libafl_bolts" }
|
||||||
log = { version = "0.4.22", features = ["release_max_level_info"] }
|
log = { version = "0.4.22", features = ["release_max_level_info"] }
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
use std::path::PathBuf;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use std::ptr::write_volatile;
|
use std::ptr::write_volatile;
|
||||||
use std::{path::PathBuf, ptr::write};
|
|
||||||
|
|
||||||
#[cfg(feature = "tui")]
|
#[cfg(feature = "tui")]
|
||||||
use libafl::monitors::tui::TuiMonitor;
|
use libafl::monitors::tui::TuiMonitor;
|
||||||
@ -15,25 +15,24 @@ use libafl::{
|
|||||||
fuzzer::{Fuzzer, StdFuzzer},
|
fuzzer::{Fuzzer, StdFuzzer},
|
||||||
inputs::{BytesInput, HasTargetBytes, MultipartInput},
|
inputs::{BytesInput, HasTargetBytes, MultipartInput},
|
||||||
mutators::{havoc_mutations::havoc_mutations, scheduled::StdScheduledMutator},
|
mutators::{havoc_mutations::havoc_mutations, scheduled::StdScheduledMutator},
|
||||||
observers::StdMapObserver,
|
observers::ConstMapObserver,
|
||||||
schedulers::QueueScheduler,
|
schedulers::QueueScheduler,
|
||||||
stages::mutational::StdMutationalStage,
|
stages::mutational::StdMutationalStage,
|
||||||
state::StdState,
|
state::StdState,
|
||||||
Evaluator,
|
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
|
/// Coverage map with explicit assignments due to the lack of instrumentation
|
||||||
static mut SIGNALS: [u8; 128] = [0; 128];
|
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
|
/// "Coverage" map for count, just to help things along
|
||||||
static mut LAST_COUNT: [usize; 1] = [usize::MAX];
|
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
|
/// Assign a signal to the signals map
|
||||||
fn signals_set(idx: usize) {
|
fn signals_set(idx: usize) {
|
||||||
unsafe { write(SIGNALS_PTR.add(idx), 1) };
|
unsafe { (*SIGNALS_PTR)[idx] = 1 };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assign a count to the count "map"
|
/// Assign a count to the count "map"
|
||||||
@ -83,9 +82,9 @@ pub fn main() {
|
|||||||
|
|
||||||
// Create an observation channel using the signals map
|
// Create an observation channel using the signals map
|
||||||
let signals_observer =
|
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 =
|
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!
|
*count_observer.initial_mut() = usize::MAX; // we are minimising!
|
||||||
|
|
||||||
// Feedback to rate the interestingness of an input
|
// Feedback to rate the interestingness of an input
|
||||||
|
@ -199,11 +199,16 @@ where
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
/// Will dereference the `map_ptr` with up to len elements.
|
/// Will dereference the `map_ptr` with up to len elements.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub unsafe fn from_mut_ptr(name: &'static str, map_ptr: NonNull<T>) -> Self {
|
pub unsafe fn from_mut_ptr(name: &'static str, map_ptr: NonNull<[T; N]>) -> Self {
|
||||||
ConstMapObserver {
|
ConstMapObserver {
|
||||||
map: OwnedMutSizedSlice::from_raw_mut(map_ptr),
|
map: OwnedMutSizedSlice::from_raw_mut(map_ptr),
|
||||||
name: Cow::from(name),
|
name: Cow::from(name),
|
||||||
initial: T::default(),
|
initial: T::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the initial value for this map, mutably
|
||||||
|
pub fn initial_mut(&mut self) -> &mut T {
|
||||||
|
&mut self.initial
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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")]
|
#[cfg(feature = "python")]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub mod pybind {
|
pub mod pybind {
|
||||||
|
@ -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<T>() * N`
|
/// The pointer must be valid and point to a map of the size `size_of<T>() * N`
|
||||||
/// The content will be dereferenced in subsequent operations.
|
/// The content will be dereferenced in subsequent operations.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub unsafe fn from_raw_mut(ptr: NonNull<T>) -> OwnedMutSizedSlice<'a, T, N> {
|
pub unsafe fn from_raw_mut(ptr: NonNull<[T; N]>) -> OwnedMutSizedSlice<'a, T, N> {
|
||||||
Self {
|
Self {
|
||||||
inner: OwnedMutSizedSliceInner::RefRaw(
|
inner: OwnedMutSizedSliceInner::RefRaw(ptr.as_ptr(), UnsafeMarker::new()),
|
||||||
ptr.as_ptr() as *mut [T; N],
|
|
||||||
UnsafeMarker::new(),
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user