* Fix as_object UB discussed in #1748 * More cleanup, more less UB * Fix fixes * Added uninit_on_shmem api * clippy * fmt * trying to fix fuzzers, libfuzzer wrapper * Add OwnedRefMit::owned constructor, libfuzzer fix * Some more fixes * Add BacktaceObserver::owned fn * fmt * more fmt
This commit is contained in:
parent
4e7d2caa9f
commit
c93291ab57
@ -18,8 +18,9 @@ use libafl::{
|
||||
};
|
||||
use libafl_bolts::{
|
||||
current_nanos,
|
||||
ownedref::OwnedRefMut,
|
||||
rands::StdRand,
|
||||
shmem::{ShMem, ShMemProvider, StdShMemProvider},
|
||||
shmem::{ShMemProvider, StdShMemProvider},
|
||||
tuples::tuple_list,
|
||||
AsSlice,
|
||||
};
|
||||
@ -47,10 +48,10 @@ pub fn main() {
|
||||
// Create an observation channel using the signals map
|
||||
let observer = unsafe { ConstMapObserver::<u8, 3>::from_mut_ptr("signals", map_ptr) };
|
||||
// Create a stacktrace observer
|
||||
let mut bt = shmem_provider.new_shmem_object::<Option<u64>>().unwrap();
|
||||
let mut bt = shmem_provider.new_on_shmem::<Option<u64>>(None).unwrap();
|
||||
let bt_observer = BacktraceObserver::new(
|
||||
"BacktraceObserver",
|
||||
unsafe { bt.as_object_mut::<Option<u64>>() },
|
||||
unsafe { OwnedRefMut::from_shmem(&mut bt) },
|
||||
libafl::observers::HarnessType::Child,
|
||||
);
|
||||
|
||||
|
@ -37,10 +37,8 @@ pub fn main() {
|
||||
// Create an observation channel using the signals map
|
||||
let observer = unsafe { ConstMapObserver::<u8, 3>::from_mut_ptr("signals", array_ptr) };
|
||||
// Create a stacktrace observer
|
||||
let mut bt = None;
|
||||
let bt_observer = BacktraceObserver::new(
|
||||
let bt_observer = BacktraceObserver::owned(
|
||||
"BacktraceObserver",
|
||||
&mut bt,
|
||||
libafl::observers::HarnessType::InProcess,
|
||||
);
|
||||
|
||||
|
@ -20,6 +20,7 @@ use libafl::{
|
||||
};
|
||||
use libafl_bolts::{
|
||||
current_nanos,
|
||||
ownedref::OwnedRefMut,
|
||||
rands::StdRand,
|
||||
shmem::{unix_shmem, ShMem, ShMemProvider},
|
||||
tuples::tuple_list,
|
||||
@ -32,7 +33,7 @@ pub fn main() {
|
||||
let mut signals = shmem_provider.new_shmem(16).unwrap();
|
||||
let signals_len = signals.len();
|
||||
let signals_ptr = signals.as_mut_slice().as_mut_ptr();
|
||||
let mut bt = shmem_provider.new_shmem_object::<Option<u64>>().unwrap();
|
||||
let mut bt = shmem_provider.new_on_shmem::<Option<u64>>(None).unwrap();
|
||||
|
||||
let signals_set = |idx: usize| {
|
||||
unsafe { write(signals_ptr.add(idx), 1) };
|
||||
@ -69,7 +70,7 @@ pub fn main() {
|
||||
// Create a stacktrace observer
|
||||
let bt_observer = BacktraceObserver::new(
|
||||
"BacktraceObserver",
|
||||
unsafe { bt.as_object_mut::<Option<u64>>() },
|
||||
unsafe { OwnedRefMut::from_shmem(&mut bt) },
|
||||
libafl::observers::HarnessType::Child,
|
||||
);
|
||||
|
||||
|
@ -61,10 +61,8 @@ pub fn main() {
|
||||
// Create an observation channel using the signals map
|
||||
let observer = unsafe { StdMapObserver::from_mut_ptr("signals", SIGNALS_PTR, SIGNALS.len()) };
|
||||
// Create a stacktrace observer to add the observers tuple
|
||||
let mut bt = None;
|
||||
let bt_observer = BacktraceObserver::new(
|
||||
let bt_observer = BacktraceObserver::owned(
|
||||
"BacktraceObserver",
|
||||
&mut bt,
|
||||
libafl::observers::HarnessType::InProcess,
|
||||
);
|
||||
|
||||
|
@ -209,9 +209,7 @@ fn fuzz(
|
||||
let edges = edges_shmem.as_mut_slice();
|
||||
unsafe { EDGES_MAP_PTR = edges.as_mut_ptr() };
|
||||
|
||||
let mut cmp_shmem = shmem_provider
|
||||
.new_shmem(core::mem::size_of::<CmpLogMap>())
|
||||
.unwrap();
|
||||
let mut cmp_shmem = shmem_provider.uninit_on_shmem::<CmpLogMap>().unwrap();
|
||||
let cmplog = cmp_shmem.as_mut_slice();
|
||||
|
||||
// Beginning of a page should be properly aligned.
|
||||
|
@ -34,6 +34,7 @@ use libafl::{
|
||||
};
|
||||
use libafl_bolts::{
|
||||
current_nanos, current_time,
|
||||
ownedref::OwnedRefMut,
|
||||
rands::StdRand,
|
||||
shmem::{ShMem, ShMemProvider, UnixShMemProvider},
|
||||
tuples::{tuple_list, Merge},
|
||||
@ -204,6 +205,7 @@ pub fn main() {
|
||||
}
|
||||
|
||||
/// The actual fuzzer
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn fuzz(
|
||||
corpus_dir: PathBuf,
|
||||
objective_dir: PathBuf,
|
||||
@ -340,12 +342,10 @@ fn fuzz(
|
||||
|
||||
if let Some(exec) = &cmplog_exec {
|
||||
// The cmplog map shared between observer and executor
|
||||
let mut cmplog_shmem = shmem_provider
|
||||
.new_shmem(core::mem::size_of::<AFLppCmpLogMap>())
|
||||
.unwrap();
|
||||
let mut cmplog_shmem = shmem_provider.uninit_on_shmem::<AFLppCmpLogMap>().unwrap();
|
||||
// let the forkserver know the shmid
|
||||
cmplog_shmem.write_to_env("__AFL_CMPLOG_SHM_ID").unwrap();
|
||||
let cmpmap = unsafe { cmplog_shmem.as_object_mut::<AFLppCmpLogMap>() };
|
||||
let cmpmap = unsafe { OwnedRefMut::<AFLppCmpLogMap>::from_shmem(&mut cmplog_shmem) };
|
||||
|
||||
let cmplog_observer = StdCmpValuesObserver::new("cmplog", cmpmap, true);
|
||||
|
||||
|
@ -34,6 +34,7 @@ use libafl::{
|
||||
};
|
||||
use libafl_bolts::{
|
||||
current_nanos, current_time,
|
||||
ownedref::OwnedRefMut,
|
||||
rands::StdRand,
|
||||
shmem::{ShMem, ShMemProvider, UnixShMemProvider},
|
||||
tuples::{tuple_list, Merge},
|
||||
@ -207,6 +208,7 @@ pub fn main() {
|
||||
}
|
||||
|
||||
/// The actual fuzzer
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn fuzz(
|
||||
corpus_dir: PathBuf,
|
||||
objective_dir: PathBuf,
|
||||
@ -344,12 +346,10 @@ fn fuzz(
|
||||
|
||||
if let Some(exec) = &cmplog_exec {
|
||||
// The cmplog map shared between observer and executor
|
||||
let mut cmplog_shmem = shmem_provider
|
||||
.new_shmem(core::mem::size_of::<AFLppCmpLogMap>())
|
||||
.unwrap();
|
||||
let mut cmplog_shmem = shmem_provider.uninit_on_shmem::<AFLppCmpLogMap>().unwrap();
|
||||
// let the forkserver know the shmid
|
||||
cmplog_shmem.write_to_env("__AFL_CMPLOG_SHM_ID").unwrap();
|
||||
let cmpmap = unsafe { cmplog_shmem.as_object_mut::<AFLppCmpLogMap>() };
|
||||
let cmpmap = unsafe { OwnedRefMut::from_shmem(&mut cmplog_shmem) };
|
||||
|
||||
let cmplog_observer = AFLppCmpLogObserver::new("cmplog", cmpmap, true);
|
||||
|
||||
|
@ -333,11 +333,11 @@ where
|
||||
{
|
||||
/// Creates a new [`StdCmpObserver`] with the given name and map.
|
||||
#[must_use]
|
||||
pub fn new(name: &'static str, map: &'a mut CM, add_meta: bool) -> Self {
|
||||
pub fn new(name: &'static str, map: OwnedRefMut<'a, CM>, add_meta: bool) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
size: None,
|
||||
cmp_map: OwnedRefMut::Ref(map),
|
||||
cmp_map: map,
|
||||
add_meta,
|
||||
data: M::Data::default(),
|
||||
phantom: PhantomData,
|
||||
@ -347,11 +347,16 @@ where
|
||||
/// Creates a new [`StdCmpObserver`] with the given name, map, and auxiliary data used to
|
||||
/// populate metadata
|
||||
#[must_use]
|
||||
pub fn with_data(name: &'static str, map: &'a mut CM, add_meta: bool, data: M::Data) -> Self {
|
||||
pub fn with_data(
|
||||
name: &'static str,
|
||||
cmp_map: OwnedRefMut<'a, CM>,
|
||||
add_meta: bool,
|
||||
data: M::Data,
|
||||
) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
size: None,
|
||||
cmp_map: OwnedRefMut::Ref(map),
|
||||
cmp_map,
|
||||
add_meta,
|
||||
data,
|
||||
phantom: PhantomData,
|
||||
@ -362,14 +367,14 @@ where
|
||||
#[must_use]
|
||||
pub fn with_size(
|
||||
name: &'static str,
|
||||
map: &'a mut CM,
|
||||
cmp_map: OwnedRefMut<'a, CM>,
|
||||
add_meta: bool,
|
||||
size: &'a mut usize,
|
||||
size: OwnedRefMut<'a, usize>,
|
||||
) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
size: Some(OwnedRefMut::Ref(size)),
|
||||
cmp_map: OwnedRefMut::Ref(map),
|
||||
size: Some(size),
|
||||
cmp_map,
|
||||
add_meta,
|
||||
data: M::Data::default(),
|
||||
phantom: PhantomData,
|
||||
@ -381,15 +386,15 @@ where
|
||||
#[must_use]
|
||||
pub fn with_size_data(
|
||||
name: &'static str,
|
||||
map: &'a mut CM,
|
||||
cmp_map: OwnedRefMut<'a, CM>,
|
||||
add_meta: bool,
|
||||
data: M::Data,
|
||||
size: &'a mut usize,
|
||||
size: OwnedRefMut<'a, usize>,
|
||||
) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
size: Some(OwnedRefMut::Ref(size)),
|
||||
cmp_map: OwnedRefMut::Ref(map),
|
||||
size: Some(size),
|
||||
cmp_map,
|
||||
add_meta,
|
||||
data,
|
||||
phantom: PhantomData,
|
||||
|
@ -127,12 +127,12 @@ impl<'a> BacktraceObserver<'a> {
|
||||
#[must_use]
|
||||
pub fn new(
|
||||
observer_name: &str,
|
||||
backtrace_hash: &'a mut Option<u64>,
|
||||
backtrace_hash: OwnedRefMut<'a, Option<u64>>,
|
||||
harness_type: HarnessType,
|
||||
) -> Self {
|
||||
Self {
|
||||
observer_name: observer_name.to_string(),
|
||||
hash: OwnedRefMut::Ref(backtrace_hash),
|
||||
hash: backtrace_hash,
|
||||
harness_type,
|
||||
}
|
||||
}
|
||||
@ -142,17 +142,23 @@ impl<'a> BacktraceObserver<'a> {
|
||||
#[must_use]
|
||||
pub fn new(
|
||||
observer_name: &str,
|
||||
backtrace_hash: &'a mut Option<u64>,
|
||||
backtrace_hash: OwnedRefMut<'a, Option<u64>>,
|
||||
harness_type: HarnessType,
|
||||
) -> Self {
|
||||
init_ignored_frames!("rust", "cpp", "go");
|
||||
Self {
|
||||
observer_name: observer_name.to_string(),
|
||||
hash: OwnedRefMut::Ref(backtrace_hash),
|
||||
hash: backtrace_hash,
|
||||
harness_type,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new [`BacktraceObserver`] with the given name, owning a new `backtrace_hash` variable.
|
||||
#[must_use]
|
||||
pub fn owned(observer_name: &str, harness_type: HarnessType) -> Self {
|
||||
Self::new(observer_name, OwnedRefMut::owned(None), harness_type)
|
||||
}
|
||||
|
||||
/// Updates the hash value of this observer.
|
||||
fn update_hash(&mut self, hash: u64) {
|
||||
*self.hash.as_mut() = Some(hash);
|
||||
|
@ -40,10 +40,10 @@ where
|
||||
{
|
||||
/// Creates a new [`ValueObserver`] with the given name.
|
||||
#[must_use]
|
||||
pub fn new(name: &'static str, value: &'a T) -> Self {
|
||||
pub fn new(name: &'static str, value: OwnedRef<'a, T>) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
value: OwnedRef::Ref(value),
|
||||
value,
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,6 +65,7 @@ where
|
||||
T: Clone,
|
||||
{
|
||||
match self.value {
|
||||
OwnedRef::RefRaw(r, _) => unsafe { (*r).clone() },
|
||||
OwnedRef::Ref(r) => r.clone(),
|
||||
OwnedRef::Owned(v) => *v,
|
||||
}
|
||||
@ -119,10 +120,10 @@ where
|
||||
{
|
||||
/// Creates a new [`RefCellValueObserver`] with the given name.
|
||||
#[must_use]
|
||||
pub fn new(name: &'static str, value: &'a RefCell<T>) -> Self {
|
||||
pub fn new(name: &'static str, value: OwnedRef<'a, RefCell<T>>) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
value: OwnedRef::Ref(value),
|
||||
value,
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,6 +148,7 @@ where
|
||||
T: Clone,
|
||||
{
|
||||
match self.value {
|
||||
OwnedRef::RefRaw(r, _) => unsafe { (*r).borrow().deref().clone() },
|
||||
OwnedRef::Ref(r) => r.borrow().deref().clone(),
|
||||
OwnedRef::Owned(v) => v.borrow().clone(),
|
||||
}
|
||||
|
@ -10,7 +10,28 @@ use core::{clone::Clone, fmt::Debug, slice};
|
||||
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use crate::{AsMutSlice, AsSlice, IntoOwned, Truncate};
|
||||
use crate::{shmem::ShMem, AsMutSlice, AsSlice, IntoOwned, Truncate};
|
||||
|
||||
/// Private part of the unsafe marker, making sure this cannot be initialized directly.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
struct UnsafeMarkerInner;
|
||||
|
||||
/// A struct or enum containing this [`UnsafeMarker`] cannot directly be instantiated.
|
||||
/// Usually, this means you'll have to use a constructor like `unsafe { Self::new() }` or similar.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct UnsafeMarker(UnsafeMarkerInner);
|
||||
|
||||
impl UnsafeMarker {
|
||||
/// Return a new unsafe marker.
|
||||
/// This usually means you're about to do something unsafe.
|
||||
///
|
||||
/// # Safety
|
||||
/// Instantiating an [`UnsafeMarker`] isn't unsafe, but the location you need it for
|
||||
/// will likely have potential unsafety.
|
||||
unsafe fn new() -> Self {
|
||||
Self(UnsafeMarkerInner)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Truncate for &'a [T] {
|
||||
fn truncate(&mut self, len: usize) {
|
||||
@ -32,12 +53,54 @@ pub enum OwnedRef<'a, T>
|
||||
where
|
||||
T: 'a + ?Sized,
|
||||
{
|
||||
/// A pointer to a type
|
||||
RefRaw(*const T, UnsafeMarker),
|
||||
/// A ref to a type
|
||||
Ref(&'a T),
|
||||
/// An owned [`Box`] of a type
|
||||
Owned(Box<T>),
|
||||
}
|
||||
|
||||
impl<'a, T> OwnedRef<'a, T>
|
||||
where
|
||||
T: 'a + ?Sized,
|
||||
{
|
||||
/// Returns a new [`OwnedRef`], wrapping a pointer of type `T`.
|
||||
///
|
||||
/// # Safety
|
||||
/// The pointer needs to point to a valid object of type `T`.
|
||||
/// Any use of this [`OwnedRef`] will dereference the pointer accordingly.
|
||||
pub unsafe fn from_ptr(ptr: *const T) -> Self {
|
||||
assert!(
|
||||
!ptr.is_null(),
|
||||
"Null pointer passed to OwnedRef::ref_raw constructor!"
|
||||
);
|
||||
Self::RefRaw(ptr, UnsafeMarker::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> OwnedRef<'a, T>
|
||||
where
|
||||
T: Sized + 'static,
|
||||
{
|
||||
/// Returns a new [`OwnedRef`], pointing to the given [`ShMem`].
|
||||
///
|
||||
/// # Panics
|
||||
/// Panics if the given shared mem is too small
|
||||
///
|
||||
/// # Safety
|
||||
/// The shared memory needs to start with a valid object of type `T`.
|
||||
/// Any use of this [`OwnedRef`] will dereference a pointer to the shared memory accordingly.
|
||||
pub unsafe fn from_shmem<S: ShMem>(shmem: &mut S) -> Self {
|
||||
Self::from_ptr(shmem.as_mut_ptr_of().unwrap())
|
||||
}
|
||||
|
||||
/// Returns a new [`OwnedRef`], owning the given value.
|
||||
pub fn owned(val: T) -> Self {
|
||||
Self::Owned(Box::new(val))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Serialize for OwnedRef<'a, T>
|
||||
where
|
||||
T: 'a + ?Sized + Serialize,
|
||||
@ -47,6 +110,7 @@ where
|
||||
S: Serializer,
|
||||
{
|
||||
match self {
|
||||
OwnedRef::RefRaw(r, _) => unsafe { (*r).as_ref().unwrap() }.serialize(se),
|
||||
OwnedRef::Ref(r) => r.serialize(se),
|
||||
OwnedRef::Owned(b) => b.serialize(se),
|
||||
}
|
||||
@ -73,6 +137,7 @@ where
|
||||
#[must_use]
|
||||
fn as_ref(&self) -> &T {
|
||||
match self {
|
||||
OwnedRef::RefRaw(r, _) => unsafe { (*r).as_ref().unwrap() },
|
||||
OwnedRef::Ref(r) => r,
|
||||
OwnedRef::Owned(v) => v.as_ref(),
|
||||
}
|
||||
@ -86,7 +151,7 @@ where
|
||||
#[must_use]
|
||||
fn is_owned(&self) -> bool {
|
||||
match self {
|
||||
OwnedRef::Ref(_) => false,
|
||||
OwnedRef::RefRaw(..) | OwnedRef::Ref(_) => false,
|
||||
OwnedRef::Owned(_) => true,
|
||||
}
|
||||
}
|
||||
@ -94,6 +159,9 @@ where
|
||||
#[must_use]
|
||||
fn into_owned(self) -> Self {
|
||||
match self {
|
||||
OwnedRef::RefRaw(r, _) => {
|
||||
OwnedRef::Owned(Box::new(unsafe { r.as_ref().unwrap().clone() }))
|
||||
}
|
||||
OwnedRef::Ref(r) => OwnedRef::Owned(Box::new(r.clone())),
|
||||
OwnedRef::Owned(v) => OwnedRef::Owned(v),
|
||||
}
|
||||
@ -102,13 +170,61 @@ where
|
||||
|
||||
/// Wrap a mutable reference and convert to a Box on serialize
|
||||
#[derive(Debug)]
|
||||
pub enum OwnedRefMut<'a, T: 'a + ?Sized> {
|
||||
pub enum OwnedRefMut<'a, T>
|
||||
where
|
||||
T: 'a + ?Sized,
|
||||
{
|
||||
/// A mutable pointer to a type
|
||||
RefRaw(*mut T, UnsafeMarker),
|
||||
/// A mutable ref to a type
|
||||
Ref(&'a mut T),
|
||||
/// An owned [`Box`] of a type
|
||||
Owned(Box<T>),
|
||||
}
|
||||
|
||||
impl<'a, T> OwnedRefMut<'a, T>
|
||||
where
|
||||
T: 'a + ?Sized,
|
||||
{
|
||||
/// Returns a new [`OwnedRefMut`], wrapping a mutable pointer.
|
||||
///
|
||||
/// # Panics
|
||||
/// Panics if the given pointer is `null`
|
||||
///
|
||||
/// # Safety
|
||||
/// The pointer needs to point to a valid object of type `T`.
|
||||
/// Any use of this [`OwnedRefMut`] will dereference the pointer accordingly.
|
||||
pub unsafe fn from_mut_ptr(ptr: *mut T) -> Self {
|
||||
assert!(
|
||||
!ptr.is_null(),
|
||||
"Null pointer passed to OwnedRefMut::from_mut_ptr constructor!"
|
||||
);
|
||||
Self::RefRaw(ptr, UnsafeMarker::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> OwnedRefMut<'a, T>
|
||||
where
|
||||
T: Sized + 'static,
|
||||
{
|
||||
/// Returns a new [`OwnedRefMut`], pointing to the given [`ShMem`].
|
||||
///
|
||||
/// # Panics
|
||||
/// Panics if the given shared mem is too small
|
||||
///
|
||||
/// # Safety
|
||||
/// The shared memory needs to start with a valid object of type `T`.
|
||||
/// Any use of this [`OwnedRefMut`] will dereference a pointer to the shared memory accordingly.
|
||||
pub unsafe fn from_shmem<S: ShMem>(shmem: &mut S) -> Self {
|
||||
Self::from_mut_ptr(shmem.as_mut_ptr_of().unwrap())
|
||||
}
|
||||
|
||||
/// Returns a new [`OwnedRefMut`], owning the given value.
|
||||
pub fn owned(val: T) -> Self {
|
||||
Self::Owned(Box::new(val))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: 'a + ?Sized + Serialize> Serialize for OwnedRefMut<'a, T> {
|
||||
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
@ -116,6 +232,7 @@ impl<'a, T: 'a + ?Sized + Serialize> Serialize for OwnedRefMut<'a, T> {
|
||||
{
|
||||
match self {
|
||||
OwnedRefMut::Ref(r) => r.serialize(se),
|
||||
OwnedRefMut::RefRaw(r, _) => unsafe { r.as_ref().unwrap().serialize(se) },
|
||||
OwnedRefMut::Owned(b) => b.serialize(se),
|
||||
}
|
||||
}
|
||||
@ -137,6 +254,7 @@ impl<'a, T: Sized> AsRef<T> for OwnedRefMut<'a, T> {
|
||||
#[must_use]
|
||||
fn as_ref(&self) -> &T {
|
||||
match self {
|
||||
OwnedRefMut::RefRaw(r, _) => unsafe { r.as_ref().unwrap() },
|
||||
OwnedRefMut::Ref(r) => r,
|
||||
OwnedRefMut::Owned(v) => v.as_ref(),
|
||||
}
|
||||
@ -147,6 +265,7 @@ impl<'a, T: Sized> AsMut<T> for OwnedRefMut<'a, T> {
|
||||
#[must_use]
|
||||
fn as_mut(&mut self) -> &mut T {
|
||||
match self {
|
||||
OwnedRefMut::RefRaw(r, _) => unsafe { r.as_mut().unwrap() },
|
||||
OwnedRefMut::Ref(r) => r,
|
||||
OwnedRefMut::Owned(v) => v.as_mut(),
|
||||
}
|
||||
@ -160,7 +279,7 @@ where
|
||||
#[must_use]
|
||||
fn is_owned(&self) -> bool {
|
||||
match self {
|
||||
OwnedRefMut::Ref(_) => false,
|
||||
OwnedRefMut::RefRaw(..) | OwnedRefMut::Ref(_) => false,
|
||||
OwnedRefMut::Owned(_) => true,
|
||||
}
|
||||
}
|
||||
@ -168,6 +287,9 @@ where
|
||||
#[must_use]
|
||||
fn into_owned(self) -> Self {
|
||||
match self {
|
||||
OwnedRefMut::RefRaw(r, _) => unsafe {
|
||||
OwnedRefMut::Owned(Box::new(r.as_ref().unwrap().clone()))
|
||||
},
|
||||
OwnedRefMut::Ref(r) => OwnedRefMut::Owned(Box::new(r.clone())),
|
||||
OwnedRefMut::Owned(v) => OwnedRefMut::Owned(v),
|
||||
}
|
||||
@ -178,7 +300,7 @@ where
|
||||
#[derive(Clone, Debug)]
|
||||
enum OwnedSliceInner<'a, T: 'a + Sized> {
|
||||
/// A ref to a raw slice and length
|
||||
RefRaw(*const T, usize),
|
||||
RefRaw(*const T, usize, UnsafeMarker),
|
||||
/// A ref to a slice
|
||||
Ref(&'a [T]),
|
||||
/// A ref to an owned [`Vec`]
|
||||
@ -191,7 +313,7 @@ impl<'a, T: 'a + Sized + Serialize> Serialize for OwnedSliceInner<'a, T> {
|
||||
S: Serializer,
|
||||
{
|
||||
match self {
|
||||
OwnedSliceInner::RefRaw(rr, len) => unsafe {
|
||||
OwnedSliceInner::RefRaw(rr, len, _) => unsafe {
|
||||
slice::from_raw_parts(*rr, *len).serialize(se)
|
||||
},
|
||||
OwnedSliceInner::Ref(r) => r.serialize(se),
|
||||
@ -239,14 +361,14 @@ impl<'a, T> OwnedSlice<'a, T> {
|
||||
#[must_use]
|
||||
pub unsafe fn from_raw_parts(ptr: *const T, len: usize) -> Self {
|
||||
Self {
|
||||
inner: OwnedSliceInner::RefRaw(ptr, len),
|
||||
inner: OwnedSliceInner::RefRaw(ptr, len, UnsafeMarker::new()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Truncate the inner slice or vec returning the old size on success or `None` on failure
|
||||
pub fn truncate(&mut self, new_len: usize) -> Option<usize> {
|
||||
match &mut self.inner {
|
||||
OwnedSliceInner::RefRaw(_rr, len) => {
|
||||
OwnedSliceInner::RefRaw(_rr, len, _) => {
|
||||
let tmp = *len;
|
||||
if new_len <= tmp {
|
||||
*len = new_len;
|
||||
@ -323,7 +445,9 @@ impl<'a, T> From<OwnedMutSlice<'a, T>> for OwnedSlice<'a, T> {
|
||||
fn from(mut_slice: OwnedMutSlice<'a, T>) -> Self {
|
||||
Self {
|
||||
inner: match mut_slice.inner {
|
||||
OwnedMutSliceInner::RefRaw(ptr, len) => OwnedSliceInner::RefRaw(ptr as _, len),
|
||||
OwnedMutSliceInner::RefRaw(ptr, len, unsafe_marker) => {
|
||||
OwnedSliceInner::RefRaw(ptr as _, len, unsafe_marker)
|
||||
}
|
||||
OwnedMutSliceInner::Ref(r) => OwnedSliceInner::Ref(r as _),
|
||||
OwnedMutSliceInner::Owned(v) => OwnedSliceInner::Owned(v),
|
||||
},
|
||||
@ -338,7 +462,7 @@ impl<'a, T: Sized> AsSlice for OwnedSlice<'a, T> {
|
||||
fn as_slice(&self) -> &[T] {
|
||||
match &self.inner {
|
||||
OwnedSliceInner::Ref(r) => r,
|
||||
OwnedSliceInner::RefRaw(rr, len) => unsafe { slice::from_raw_parts(*rr, *len) },
|
||||
OwnedSliceInner::RefRaw(rr, len, _) => unsafe { slice::from_raw_parts(*rr, *len) },
|
||||
OwnedSliceInner::Owned(v) => v.as_slice(),
|
||||
}
|
||||
}
|
||||
@ -351,7 +475,7 @@ where
|
||||
#[must_use]
|
||||
fn is_owned(&self) -> bool {
|
||||
match self.inner {
|
||||
OwnedSliceInner::RefRaw(_, _) | OwnedSliceInner::Ref(_) => false,
|
||||
OwnedSliceInner::RefRaw(..) | OwnedSliceInner::Ref(_) => false,
|
||||
OwnedSliceInner::Owned(_) => true,
|
||||
}
|
||||
}
|
||||
@ -359,7 +483,7 @@ where
|
||||
#[must_use]
|
||||
fn into_owned(self) -> Self {
|
||||
match self.inner {
|
||||
OwnedSliceInner::RefRaw(rr, len) => Self {
|
||||
OwnedSliceInner::RefRaw(rr, len, _) => Self {
|
||||
inner: OwnedSliceInner::Owned(unsafe { slice::from_raw_parts(rr, len).to_vec() }),
|
||||
},
|
||||
OwnedSliceInner::Ref(r) => Self {
|
||||
@ -392,7 +516,7 @@ where
|
||||
#[derive(Debug)]
|
||||
pub enum OwnedMutSliceInner<'a, T: 'a + Sized> {
|
||||
/// A raw ptr to a memory location and a length
|
||||
RefRaw(*mut T, usize),
|
||||
RefRaw(*mut T, usize, UnsafeMarker),
|
||||
/// A ptr to a mutable slice of the type
|
||||
Ref(&'a mut [T]),
|
||||
/// An owned [`Vec`] of the type
|
||||
@ -405,7 +529,7 @@ impl<'a, T: 'a + Sized + Serialize> Serialize for OwnedMutSliceInner<'a, T> {
|
||||
S: Serializer,
|
||||
{
|
||||
match self {
|
||||
OwnedMutSliceInner::RefRaw(rr, len) => {
|
||||
OwnedMutSliceInner::RefRaw(rr, len, _) => {
|
||||
unsafe { slice::from_raw_parts_mut(*rr, *len) }.serialize(se)
|
||||
}
|
||||
OwnedMutSliceInner::Ref(r) => r.serialize(se),
|
||||
@ -466,7 +590,7 @@ impl<'a, T: 'a + Sized> OwnedMutSlice<'a, T> {
|
||||
}
|
||||
} else {
|
||||
Self {
|
||||
inner: OwnedMutSliceInner::RefRaw(ptr, len),
|
||||
inner: OwnedMutSliceInner::RefRaw(ptr, len, UnsafeMarker::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -474,7 +598,7 @@ impl<'a, T: 'a + Sized> OwnedMutSlice<'a, T> {
|
||||
/// Truncate the inner slice or vec returning the old size on success or `None` on failure
|
||||
pub fn truncate(&mut self, new_len: usize) -> Option<usize> {
|
||||
match &mut self.inner {
|
||||
OwnedMutSliceInner::RefRaw(_rr, len) => {
|
||||
OwnedMutSliceInner::RefRaw(_rr, len, _) => {
|
||||
let tmp = *len;
|
||||
if new_len <= tmp {
|
||||
*len = new_len;
|
||||
@ -521,7 +645,7 @@ impl<'a, T: Sized> AsSlice for OwnedMutSlice<'a, T> {
|
||||
#[must_use]
|
||||
fn as_slice(&self) -> &[T] {
|
||||
match &self.inner {
|
||||
OwnedMutSliceInner::RefRaw(rr, len) => unsafe { slice::from_raw_parts(*rr, *len) },
|
||||
OwnedMutSliceInner::RefRaw(rr, len, _) => unsafe { slice::from_raw_parts(*rr, *len) },
|
||||
OwnedMutSliceInner::Ref(r) => r,
|
||||
OwnedMutSliceInner::Owned(v) => v.as_slice(),
|
||||
}
|
||||
@ -533,7 +657,9 @@ impl<'a, T: Sized> AsMutSlice for OwnedMutSlice<'a, T> {
|
||||
#[must_use]
|
||||
fn as_mut_slice(&mut self) -> &mut [T] {
|
||||
match &mut self.inner {
|
||||
OwnedMutSliceInner::RefRaw(rr, len) => unsafe { slice::from_raw_parts_mut(*rr, *len) },
|
||||
OwnedMutSliceInner::RefRaw(rr, len, _) => unsafe {
|
||||
slice::from_raw_parts_mut(*rr, *len)
|
||||
},
|
||||
OwnedMutSliceInner::Ref(r) => r,
|
||||
OwnedMutSliceInner::Owned(v) => v.as_mut_slice(),
|
||||
}
|
||||
@ -547,7 +673,7 @@ where
|
||||
#[must_use]
|
||||
fn is_owned(&self) -> bool {
|
||||
match self.inner {
|
||||
OwnedMutSliceInner::RefRaw(_, _) | OwnedMutSliceInner::Ref(_) => false,
|
||||
OwnedMutSliceInner::RefRaw(..) | OwnedMutSliceInner::Ref(_) => false,
|
||||
OwnedMutSliceInner::Owned(_) => true,
|
||||
}
|
||||
}
|
||||
@ -555,7 +681,7 @@ where
|
||||
#[must_use]
|
||||
fn into_owned(self) -> Self {
|
||||
let vec = match self.inner {
|
||||
OwnedMutSliceInner::RefRaw(rr, len) => unsafe {
|
||||
OwnedMutSliceInner::RefRaw(rr, len, _) => unsafe {
|
||||
slice::from_raw_parts_mut(rr, len).to_vec()
|
||||
},
|
||||
OwnedMutSliceInner::Ref(r) => r.to_vec(),
|
||||
|
@ -3,11 +3,11 @@
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::{rc::Rc, string::ToString};
|
||||
use core::fmt::Debug;
|
||||
#[cfg(feature = "alloc")]
|
||||
use core::fmt::Display;
|
||||
#[cfg(feature = "alloc")]
|
||||
use core::{cell::RefCell, fmt, mem::ManuallyDrop};
|
||||
use core::{fmt::Debug, mem};
|
||||
#[cfg(feature = "std")]
|
||||
use std::env;
|
||||
#[cfg(all(unix, feature = "std", not(target_os = "haiku")))]
|
||||
@ -204,52 +204,24 @@ pub trait ShMem: Sized + Debug + Clone + AsSlice<Entry = u8> + AsMutSlice<Entry
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
/// Convert to an owned object reference
|
||||
///
|
||||
/// # Safety
|
||||
/// This function is not safe as the object may be not initialized.
|
||||
/// The user is responsible to initialize the object with something like
|
||||
/// `*shmem.as_object_mut::<T>() = T::new();`
|
||||
unsafe fn as_object<T: Sized + 'static>(&self) -> &T {
|
||||
assert!(self.len() >= core::mem::size_of::<T>());
|
||||
(self.as_slice().as_ptr() as *const () as *const T)
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
/// Convert to a ptr of a given type, checking the size.
|
||||
/// If the map is too small, returns `None`
|
||||
fn as_ptr_of<T: Sized>(&self) -> Option<*const T> {
|
||||
if self.len() >= mem::size_of::<T>() {
|
||||
Some(self.as_slice().as_ptr() as *const T)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert to an owned object mutable reference
|
||||
///
|
||||
/// # Safety
|
||||
/// This function is not safe as the object may be not initialized.
|
||||
/// The user is responsible to initialize the object with something like
|
||||
/// `*shmem.as_object_mut::<T>() = T::new();`
|
||||
unsafe fn as_object_mut<T: Sized + 'static>(&mut self) -> &mut T {
|
||||
assert!(self.len() >= core::mem::size_of::<T>());
|
||||
(self.as_mut_slice().as_mut_ptr() as *mut () as *mut T)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
/// Convert to a mut ptr of a given type, checking the size.
|
||||
/// If the map is too small, returns `None`
|
||||
fn as_mut_ptr_of<T: Sized>(&mut self) -> Option<*mut T> {
|
||||
if self.len() >= mem::size_of::<T>() {
|
||||
Some(self.as_mut_slice().as_mut_ptr() as *mut T)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
||||
/// Convert to a slice of type &\[T\]
|
||||
///
|
||||
/// # Safety
|
||||
/// This function is not safe as the object may be not initialized.
|
||||
/// The user is responsible to initialize the objects in the slice
|
||||
unsafe fn as_objects_slice<T: Sized + 'static>(&self, len: usize) -> &[T] {
|
||||
assert!(self.len() >= core::mem::size_of::<T>() * len);
|
||||
let ptr = self.as_slice().as_ptr() as *const () as *const T;
|
||||
core::slice::from_raw_parts(ptr, len)
|
||||
}
|
||||
|
||||
/// Convert to a slice of type &mut \[T\]
|
||||
///
|
||||
/// # Safety
|
||||
/// This function is not safe as the object may be not initialized.
|
||||
/// The user is responsible to initialize the objects in the slice
|
||||
unsafe fn as_objects_slice_mut<T: Sized + 'static>(&mut self, len: usize) -> &mut [T] {
|
||||
assert!(self.len() >= core::mem::size_of::<T>() * len);
|
||||
let ptr = self.as_mut_slice().as_mut_ptr() as *mut () as *mut T;
|
||||
core::slice::from_raw_parts_mut(ptr, len)
|
||||
}
|
||||
|
||||
/// Get the description of the shared memory mapping
|
||||
@ -287,25 +259,20 @@ pub trait ShMemProvider: Clone + Default + Debug {
|
||||
/// Get a mapping given its id and size
|
||||
fn shmem_from_id_and_size(&mut self, id: ShMemId, size: usize) -> Result<Self::ShMem, Error>;
|
||||
|
||||
/// Create a new shared memory mapping to hold an object of the given type
|
||||
fn new_shmem_object<T: Sized + 'static>(&mut self) -> Result<Self::ShMem, Error> {
|
||||
self.new_shmem(core::mem::size_of::<T>())
|
||||
/// Create a new shared memory mapping to hold an object of the given type, and initializes it with the given value.
|
||||
fn new_on_shmem<T: Sized + 'static>(&mut self, value: T) -> Result<Self::ShMem, Error> {
|
||||
self.uninit_on_shmem::<T>().map(|mut shmem| {
|
||||
// # Safety
|
||||
// The map has been created at this point in time, and is large enough.
|
||||
// The map is fresh from the OS and, hence, the pointer should be properly aligned for any object.
|
||||
unsafe { shmem.as_mut_ptr_of::<T>().unwrap().write_volatile(value) };
|
||||
shmem
|
||||
})
|
||||
}
|
||||
|
||||
/// Create a new shared memory mapping to hold an array of objects of the given type
|
||||
fn new_shmem_objects_array<T: Sized + 'static>(
|
||||
&mut self,
|
||||
len: usize,
|
||||
) -> Result<Self::ShMem, Error> {
|
||||
self.new_shmem(core::mem::size_of::<T>() * len)
|
||||
}
|
||||
|
||||
/// Get a mapping given its id to hold an object of the given type
|
||||
fn shmem_object_from_id<T: Sized + 'static>(
|
||||
&mut self,
|
||||
id: ShMemId,
|
||||
) -> Result<Self::ShMem, Error> {
|
||||
self.shmem_from_id_and_size(id, core::mem::size_of::<T>())
|
||||
/// Create a new shared memory mapping to hold an object of the given type, and initializes it with the given value.
|
||||
fn uninit_on_shmem<T: Sized + 'static>(&mut self) -> Result<Self::ShMem, Error> {
|
||||
self.new_shmem(mem::size_of::<T>())
|
||||
}
|
||||
|
||||
/// Get a mapping given a description
|
||||
|
@ -115,8 +115,6 @@ use mimalloc::MiMalloc;
|
||||
#[cfg(feature = "mimalloc")]
|
||||
static GLOBAL: MiMalloc = MiMalloc;
|
||||
|
||||
static mut BACKTRACE: Option<u64> = None;
|
||||
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
struct CustomMutationStatus {
|
||||
std_mutational: bool,
|
||||
@ -184,11 +182,13 @@ macro_rules! fuzz_with {
|
||||
use rand::{thread_rng, RngCore};
|
||||
use std::{env::temp_dir, fs::create_dir, path::PathBuf};
|
||||
|
||||
use crate::{BACKTRACE, CustomMutationStatus};
|
||||
use crate::corpus::{ArtifactCorpus, LibfuzzerCorpus};
|
||||
use crate::feedbacks::{LibfuzzerCrashCauseFeedback, LibfuzzerKeepFeedback, ShrinkMapFeedback};
|
||||
use crate::misc::should_use_grimoire;
|
||||
use crate::observers::{MappedEdgeMapObserver, SizeValueObserver};
|
||||
use crate::{
|
||||
CustomMutationStatus,
|
||||
corpus::{ArtifactCorpus, LibfuzzerCorpus},
|
||||
feedbacks::{LibfuzzerCrashCauseFeedback, LibfuzzerKeepFeedback, ShrinkMapFeedback},
|
||||
misc::should_use_grimoire,
|
||||
observers::{MappedEdgeMapObserver, SizeValueObserver},
|
||||
};
|
||||
|
||||
let edge_maker = &$edge_maker;
|
||||
|
||||
@ -213,9 +213,8 @@ macro_rules! fuzz_with {
|
||||
let cmplog_observer = CmpLogObserver::new("cmplog", true);
|
||||
|
||||
// Create a stacktrace observer
|
||||
let backtrace_observer = BacktraceObserver::new(
|
||||
let backtrace_observer = BacktraceObserver::owned(
|
||||
"BacktraceObserver",
|
||||
unsafe { &mut BACKTRACE },
|
||||
if $options.forks().is_some() || $options.tui() { libafl::observers::HarnessType::Child } else { libafl::observers::HarnessType::InProcess }
|
||||
);
|
||||
|
||||
|
@ -428,7 +428,7 @@ pub static mut libafl_cmplog_map_extended: AFLppCmpLogMap = AFLppCmpLogMap {
|
||||
pub use libafl_cmplog_map as CMPLOG_MAP;
|
||||
pub use libafl_cmplog_map_extended as CMPLOG_MAP_EXTENDED;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone)]
|
||||
#[repr(C, packed)]
|
||||
/// Comparison map compatible with AFL++ cmplog instrumentation
|
||||
pub struct AFLppCmpLogMap {
|
||||
|
@ -179,11 +179,15 @@ where
|
||||
{
|
||||
/// Creates a new [`AFLppCmpLogObserver`] with the given name and map.
|
||||
#[must_use]
|
||||
pub fn new(name: &'static str, map: &'a mut AFLppCmpLogMap, add_meta: bool) -> Self {
|
||||
pub fn new(
|
||||
name: &'static str,
|
||||
cmp_map: OwnedRefMut<'a, AFLppCmpLogMap>,
|
||||
add_meta: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
size: None,
|
||||
cmp_map: OwnedRefMut::Ref(map),
|
||||
cmp_map,
|
||||
add_meta,
|
||||
original: false,
|
||||
phantom: PhantomData,
|
||||
@ -198,15 +202,15 @@ where
|
||||
#[must_use]
|
||||
pub fn with_size(
|
||||
name: &'static str,
|
||||
map: &'a mut AFLppCmpLogMap,
|
||||
cmp_map: OwnedRefMut<'a, AFLppCmpLogMap>,
|
||||
add_meta: bool,
|
||||
original: bool,
|
||||
size: &'a mut usize,
|
||||
size: OwnedRefMut<'a, usize>,
|
||||
) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
size: Some(OwnedRefMut::Ref(size)),
|
||||
cmp_map: OwnedRefMut::Ref(map),
|
||||
size: Some(size),
|
||||
cmp_map,
|
||||
add_meta,
|
||||
original,
|
||||
phantom: PhantomData,
|
||||
|
Loading…
x
Reference in New Issue
Block a user