No more (direct) mutable references to mutable statics (#2550)
* No more (direct) mutable references to mutable statics * More * Fix build, but it's unsafe dude * more * fmt * More fix * more?
This commit is contained in:
parent
691fd1f8cb
commit
f0d85aaaa5
@ -938,7 +938,7 @@ pub trait AdaptiveSerializer {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use core::ptr::addr_of_mut;
|
||||
use core::ptr::{addr_of, addr_of_mut};
|
||||
|
||||
use libafl_bolts::{current_time, tuples::tuple_list, Named};
|
||||
use tuple_list::tuple_list_type;
|
||||
@ -955,7 +955,8 @@ mod tests {
|
||||
#[test]
|
||||
fn test_event_serde() {
|
||||
let obv = unsafe {
|
||||
StdMapObserver::from_mut_ptr("test", addr_of_mut!(MAP) as *mut u32, MAP.len())
|
||||
let len = (*addr_of!(MAP)).len();
|
||||
StdMapObserver::from_mut_ptr("test", addr_of_mut!(MAP) as *mut u32, len)
|
||||
};
|
||||
let map = tuple_list!(obv);
|
||||
let observers_buf = postcard::to_allocvec(&map).unwrap();
|
||||
|
@ -1,6 +1,12 @@
|
||||
//! Hitcount map observer is for implementing AFL's hit count bucket
|
||||
use alloc::{borrow::Cow, vec::Vec};
|
||||
use core::{fmt::Debug, hash::Hash, mem::size_of, slice};
|
||||
use core::{
|
||||
fmt::Debug,
|
||||
hash::Hash,
|
||||
mem::size_of,
|
||||
ptr::{addr_of, addr_of_mut},
|
||||
slice,
|
||||
};
|
||||
|
||||
use libafl_bolts::{AsIter, AsIterMut, AsSlice, AsSliceMut, HasLen, Named, Truncate};
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -35,17 +41,19 @@ static mut COUNT_CLASS_LOOKUP_16: Vec<u16> = vec![];
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Calling this from multiple threads may be racey and hence leak 65k mem
|
||||
/// Calling this from multiple threads may be racey and hence leak 65k mem or even create a broken lookup vec.
|
||||
fn init_count_class_16() {
|
||||
unsafe {
|
||||
if !COUNT_CLASS_LOOKUP_16.is_empty() {
|
||||
let count_class_lookup_16 = &mut *addr_of_mut!(COUNT_CLASS_LOOKUP_16);
|
||||
|
||||
if !count_class_lookup_16.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
COUNT_CLASS_LOOKUP_16 = vec![0; 65536];
|
||||
*count_class_lookup_16 = vec![0; 65536];
|
||||
for i in 0..256 {
|
||||
for j in 0..256 {
|
||||
COUNT_CLASS_LOOKUP_16[(i << 8) + j] =
|
||||
count_class_lookup_16[(i << 8) + j] =
|
||||
(u16::from(COUNT_CLASS_LOOKUP[i]) << 8) | u16::from(COUNT_CLASS_LOOKUP[j]);
|
||||
}
|
||||
}
|
||||
@ -117,7 +125,7 @@ where
|
||||
#[allow(clippy::unused_enumerate_index)]
|
||||
for (_i, item) in map16[0..cnt].iter_mut().enumerate() {
|
||||
unsafe {
|
||||
*item = *COUNT_CLASS_LOOKUP_16.get_unchecked(*item as usize);
|
||||
*item = *(*addr_of!(COUNT_CLASS_LOOKUP_16)).get_unchecked(*item as usize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -446,7 +446,7 @@ where
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use core::ptr::addr_of_mut;
|
||||
use core::ptr::{addr_of, addr_of_mut};
|
||||
|
||||
use libafl_bolts::{
|
||||
ownedref::OwnedMutSlice,
|
||||
@ -461,9 +461,10 @@ mod tests {
|
||||
#[test]
|
||||
fn test_observer_serde() {
|
||||
let obv = tuple_list!(TimeObserver::new("time"), unsafe {
|
||||
let len = (*addr_of!(MAP)).len();
|
||||
StdMapObserver::from_ownedref(
|
||||
"map",
|
||||
OwnedMutSlice::from_raw_parts_mut(addr_of_mut!(MAP) as *mut u32, MAP.len()),
|
||||
OwnedMutSlice::from_raw_parts_mut(addr_of_mut!(MAP) as *mut u32, len),
|
||||
)
|
||||
});
|
||||
let vec = postcard::to_allocvec(&obv).unwrap();
|
||||
|
@ -992,7 +992,7 @@ impl SimpleFdLogger {
|
||||
// The passed-in `fd` has to be a legal file descriptor to log to.
|
||||
// We also access a shared variable here.
|
||||
unsafe {
|
||||
LIBAFL_RAWFD_LOGGER.set_fd(log_fd);
|
||||
(*ptr::addr_of_mut!(LIBAFL_RAWFD_LOGGER)).set_fd(log_fd);
|
||||
log::set_logger(&*ptr::addr_of!(LIBAFL_RAWFD_LOGGER))?;
|
||||
}
|
||||
Ok(())
|
||||
|
@ -118,7 +118,12 @@ pub mod serdeany_registry {
|
||||
boxed::Box,
|
||||
string::{String, ToString},
|
||||
};
|
||||
use core::{any::TypeId, fmt, hash::BuildHasherDefault};
|
||||
use core::{
|
||||
any::TypeId,
|
||||
fmt,
|
||||
hash::BuildHasherDefault,
|
||||
ptr::{addr_of, addr_of_mut},
|
||||
};
|
||||
|
||||
use hashbrown::{
|
||||
hash_map::{Values, ValuesMut},
|
||||
@ -156,7 +161,7 @@ pub mod serdeany_registry {
|
||||
let id: TypeRepr = visitor.next_element()?.unwrap();
|
||||
|
||||
let cb = unsafe {
|
||||
REGISTRY
|
||||
(*addr_of!(REGISTRY))
|
||||
.deserializers
|
||||
.as_ref()
|
||||
.ok_or_else(||
|
||||
@ -228,7 +233,7 @@ pub mod serdeany_registry {
|
||||
T: crate::serdeany::SerdeAny + Serialize + serde::de::DeserializeOwned,
|
||||
{
|
||||
unsafe {
|
||||
REGISTRY.register::<T>();
|
||||
(*addr_of_mut!(REGISTRY)).register::<T>();
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,7 +244,7 @@ pub mod serdeany_registry {
|
||||
/// It dereferences the `REGISTRY` hashmap and adds the given type to it.
|
||||
pub fn finalize() {
|
||||
unsafe {
|
||||
REGISTRY.finalize();
|
||||
(*addr_of_mut!(REGISTRY)).finalize();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -366,7 +371,7 @@ pub mod serdeany_registry {
|
||||
|
||||
assert!(
|
||||
unsafe {
|
||||
REGISTRY
|
||||
(*addr_of!(REGISTRY))
|
||||
.deserializers
|
||||
.as_ref()
|
||||
.expect(super::ERR_EMPTY_TYPES_REGISTER)
|
||||
@ -629,7 +634,7 @@ pub mod serdeany_registry {
|
||||
|
||||
assert!(
|
||||
unsafe {
|
||||
REGISTRY
|
||||
(*addr_of!(REGISTRY))
|
||||
.deserializers
|
||||
.as_ref()
|
||||
.expect(super::ERR_EMPTY_TYPES_REGISTER)
|
||||
|
@ -58,9 +58,8 @@ where
|
||||
|
||||
impl BreakpointId {
|
||||
pub fn new() -> Self {
|
||||
static mut BREAKPOINT_ID_COUNTER: OnceLock<AtomicU64> = OnceLock::new();
|
||||
|
||||
let counter = unsafe { BREAKPOINT_ID_COUNTER.get_or_init(|| AtomicU64::new(0)) };
|
||||
static BREAKPOINT_ID_COUNTER: OnceLock<AtomicU64> = OnceLock::new();
|
||||
let counter = BREAKPOINT_ID_COUNTER.get_or_init(|| AtomicU64::new(0));
|
||||
|
||||
BreakpointId(counter.fetch_add(1, Ordering::SeqCst))
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use std::fmt::Debug;
|
||||
use hashbrown::HashMap;
|
||||
use libafl::{
|
||||
inputs::{HasTargetBytes, UsesInput},
|
||||
prelude::{HasExecutions, State},
|
||||
state::{HasExecutions, State},
|
||||
};
|
||||
use libafl_qemu_sys::GuestPhysAddr;
|
||||
|
||||
|
@ -100,6 +100,7 @@ pub fn python_module(m: &Bound<'_, PyModule>) -> PyResult<()> {
|
||||
}
|
||||
m.add_submodule(&mmapm)?;
|
||||
|
||||
#[cfg(emulation_mode = "usermode")]
|
||||
m.add_class::<sys::MapInfo>()?;
|
||||
|
||||
#[cfg(emulation_mode = "usermode")]
|
||||
|
@ -1,4 +1,4 @@
|
||||
use core::{cell::UnsafeCell, fmt::Debug};
|
||||
use core::{cell::UnsafeCell, fmt::Debug, ptr::addr_of_mut};
|
||||
|
||||
use capstone::prelude::*;
|
||||
use libafl::{
|
||||
@ -541,13 +541,13 @@ impl Default for FullBacktraceCollector {
|
||||
|
||||
impl FullBacktraceCollector {
|
||||
pub fn new() -> Self {
|
||||
unsafe { CALLSTACKS = Some(ThreadLocal::new()) };
|
||||
unsafe { *(&mut *addr_of_mut!(CALLSTACKS)) = Some(ThreadLocal::new()) };
|
||||
Self {}
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
unsafe {
|
||||
for tls in CALLSTACKS.as_mut().unwrap().iter_mut() {
|
||||
for tls in (*addr_of_mut!(CALLSTACKS)).as_mut().unwrap().iter_mut() {
|
||||
(*tls.get()).clear();
|
||||
}
|
||||
}
|
||||
@ -555,7 +555,7 @@ impl FullBacktraceCollector {
|
||||
|
||||
pub fn backtrace() -> Option<&'static [GuestAddr]> {
|
||||
unsafe {
|
||||
if let Some(c) = CALLSTACKS.as_mut() {
|
||||
if let Some(c) = (*addr_of_mut!(CALLSTACKS)).as_mut() {
|
||||
Some(&*c.get_or_default().get())
|
||||
} else {
|
||||
None
|
||||
@ -578,7 +578,12 @@ impl CallTraceCollector for FullBacktraceCollector {
|
||||
{
|
||||
// TODO handle Thumb
|
||||
unsafe {
|
||||
(*CALLSTACKS.as_mut().unwrap().get_or_default().get()).push(pc + call_len as GuestAddr);
|
||||
(*(*addr_of_mut!(CALLSTACKS))
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.get_or_default()
|
||||
.get())
|
||||
.push(pc + call_len as GuestAddr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -594,7 +599,11 @@ impl CallTraceCollector for FullBacktraceCollector {
|
||||
S: Unpin + UsesInput,
|
||||
{
|
||||
unsafe {
|
||||
let v = &mut *CALLSTACKS.as_mut().unwrap().get_or_default().get();
|
||||
let v = &mut *(*addr_of_mut!(CALLSTACKS))
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.get_or_default()
|
||||
.get();
|
||||
if !v.is_empty() {
|
||||
// if *v.last().unwrap() == ret_addr {
|
||||
// v.pop();
|
||||
|
@ -1,5 +1,4 @@
|
||||
use core::{fmt::Debug, ops::Range};
|
||||
use std::{cell::UnsafeCell, hash::BuildHasher};
|
||||
use core::{cell::UnsafeCell, fmt::Debug, hash::BuildHasher, ops::Range, ptr::addr_of_mut};
|
||||
|
||||
use hashbrown::HashSet;
|
||||
use libafl::{executors::ExitKind, inputs::UsesInput, observers::ObserversTuple};
|
||||
@ -311,7 +310,7 @@ impl HasInstrumentationFilter<QemuInstrumentationAddressRangeFilter> for () {
|
||||
}
|
||||
|
||||
fn filter_mut(&mut self) -> &mut QemuInstrumentationAddressRangeFilter {
|
||||
unsafe { EMPTY_ADDRESS_FILTER.get_mut() }
|
||||
unsafe { (*addr_of_mut!(EMPTY_ADDRESS_FILTER)).get_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
@ -321,7 +320,7 @@ impl HasInstrumentationFilter<QemuInstrumentationPagingFilter> for () {
|
||||
}
|
||||
|
||||
fn filter_mut(&mut self) -> &mut QemuInstrumentationPagingFilter {
|
||||
unsafe { EMPTY_PAGING_FILTER.get_mut() }
|
||||
unsafe { (*addr_of_mut!(EMPTY_PAGING_FILTER)).get_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,16 +3,18 @@
|
||||
//! This module exposes the low-level QEMU library through [`Qemu`].
|
||||
//! To access higher-level features of QEMU, it is recommended to use [`crate::Emulator`] instead.
|
||||
|
||||
use core::fmt;
|
||||
use std::{
|
||||
use core::{
|
||||
cmp::{Ordering, PartialOrd},
|
||||
fmt,
|
||||
ptr::{self, addr_of_mut},
|
||||
};
|
||||
use std::{
|
||||
ffi::{c_void, CString},
|
||||
fmt::{Display, Formatter},
|
||||
intrinsics::{copy_nonoverlapping, transmute},
|
||||
mem::MaybeUninit,
|
||||
ops::Range,
|
||||
pin::Pin,
|
||||
ptr,
|
||||
};
|
||||
|
||||
use libafl_bolts::os::unix_signals::Signal;
|
||||
@ -141,7 +143,7 @@ pub struct QemuMemoryChunk {
|
||||
}
|
||||
|
||||
#[allow(clippy::vec_box)]
|
||||
static mut GDB_COMMANDS: Vec<Box<FatPtr>> = vec![];
|
||||
static mut GDB_COMMANDS: Vec<Box<FatPtr>> = Vec::new();
|
||||
|
||||
unsafe extern "C" fn gdb_cmd(data: *mut c_void, buf: *mut u8, len: usize) -> bool {
|
||||
unsafe {
|
||||
@ -768,16 +770,16 @@ impl Qemu {
|
||||
id.remove(invalidate_block)
|
||||
}
|
||||
|
||||
// # Safety
|
||||
// Calling this multiple times concurrently will access static variables and is unsafe.
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub fn add_gdb_cmd(&self, callback: Box<dyn FnMut(&Self, &str) -> bool>) {
|
||||
unsafe {
|
||||
let fat: Box<FatPtr> = Box::new(transmute::<
|
||||
Box<dyn for<'a, 'b> FnMut(&'a Qemu, &'b str) -> bool>,
|
||||
FatPtr,
|
||||
>(callback));
|
||||
libafl_qemu_add_gdb_cmd(Some(gdb_cmd), ptr::from_ref(&*fat) as *mut c_void);
|
||||
GDB_COMMANDS.push(fat);
|
||||
}
|
||||
pub unsafe fn add_gdb_cmd(&self, callback: Box<dyn FnMut(&Self, &str) -> bool>) {
|
||||
let fat: Box<FatPtr> = Box::new(transmute::<
|
||||
Box<dyn for<'a, 'b> FnMut(&'a Qemu, &'b str) -> bool>,
|
||||
FatPtr,
|
||||
>(callback));
|
||||
libafl_qemu_add_gdb_cmd(Some(gdb_cmd), ptr::from_ref(&*fat) as *mut c_void);
|
||||
(*addr_of_mut!(GDB_COMMANDS)).push(fat);
|
||||
}
|
||||
|
||||
pub fn gdb_reply(&self, output: &str) {
|
||||
@ -956,7 +958,10 @@ pub mod pybind {
|
||||
static mut PY_GENERIC_HOOKS: Vec<(GuestAddr, PyObject)> = vec![];
|
||||
|
||||
extern "C" fn py_generic_hook_wrapper(idx: u64, _pc: GuestAddr) {
|
||||
let obj = unsafe { &PY_GENERIC_HOOKS[idx as usize].1 };
|
||||
let obj = unsafe {
|
||||
let hooks = &mut *core::ptr::addr_of_mut!(PY_GENERIC_HOOKS);
|
||||
&hooks[idx as usize].1
|
||||
};
|
||||
Python::with_gil(|py| {
|
||||
obj.call0(py).expect("Error in the hook");
|
||||
});
|
||||
@ -1032,8 +1037,9 @@ pub mod pybind {
|
||||
|
||||
fn set_hook(&self, addr: GuestAddr, hook: PyObject) {
|
||||
unsafe {
|
||||
let idx = PY_GENERIC_HOOKS.len();
|
||||
PY_GENERIC_HOOKS.push((addr, hook));
|
||||
let hooks = &mut *core::ptr::addr_of_mut!(PY_GENERIC_HOOKS);
|
||||
let idx = hooks.len();
|
||||
hooks.push((addr, hook));
|
||||
self.qemu.hooks().add_instruction_hooks(
|
||||
idx as u64,
|
||||
addr,
|
||||
@ -1045,7 +1051,8 @@ pub mod pybind {
|
||||
|
||||
fn remove_hooks_at(&self, addr: GuestAddr) -> usize {
|
||||
unsafe {
|
||||
PY_GENERIC_HOOKS.retain(|(a, _)| *a != addr);
|
||||
let hooks = &mut *core::ptr::addr_of_mut!(PY_GENERIC_HOOKS);
|
||||
hooks.retain(|(a, _)| *a != addr);
|
||||
}
|
||||
self.qemu.hooks().remove_instruction_hooks_at(addr, true)
|
||||
}
|
||||
|
@ -261,7 +261,7 @@ pub mod pybind {
|
||||
a6: u64,
|
||||
a7: u64,
|
||||
) -> SyscallHookResult {
|
||||
unsafe { PY_SYSCALL_HOOK.as_ref() }.map_or_else(
|
||||
unsafe { (*core::ptr::addr_of!(PY_SYSCALL_HOOK)).as_ref() }.map_or_else(
|
||||
|| SyscallHookResult::new(None),
|
||||
|obj| {
|
||||
let args = (sys_num, a0, a1, a2, a3, a4, a5, a6, a7);
|
||||
@ -340,7 +340,7 @@ pub mod pybind {
|
||||
|
||||
fn set_syscall_hook(&self, hook: PyObject) {
|
||||
unsafe {
|
||||
PY_SYSCALL_HOOK = Some(hook);
|
||||
*(&mut *core::ptr::addr_of_mut!(PY_SYSCALL_HOOK)) = Some(hook);
|
||||
}
|
||||
self.qemu
|
||||
.hooks()
|
||||
|
@ -1,4 +1,4 @@
|
||||
use core::marker::PhantomData;
|
||||
use core::{marker::PhantomData, ptr::addr_of_mut};
|
||||
|
||||
use hashbrown::HashMap;
|
||||
use libafl::{
|
||||
@ -12,9 +12,11 @@ pub static mut FUNCTION_LIST: Lazy<HashMap<usize, usize>> = Lazy::new(HashMap::n
|
||||
#[no_mangle]
|
||||
/// The runtime code inserted at every callinst invokation (if you used the function-logging.cc)
|
||||
/// # Safety
|
||||
/// unsafe because it touches pub static mut
|
||||
/// unsafe because it touches the pub static mut `FUNCTION_LIST`.
|
||||
/// May not be called concurrently.
|
||||
pub unsafe extern "C" fn __libafl_target_call_hook(id: usize) {
|
||||
*FUNCTION_LIST.entry(id).or_insert(0) += 1;
|
||||
let function_list = &mut *addr_of_mut!(FUNCTION_LIST);
|
||||
*function_list.entry(id).or_insert(0) += 1;
|
||||
}
|
||||
|
||||
/// The empty struct to clear the `FUNCTION_LIST` before the execution
|
||||
@ -41,7 +43,13 @@ where
|
||||
|
||||
fn pre_exec(&mut self, _state: &mut S, _input: &<S as UsesInput>::Input) {
|
||||
// clear it before the execution
|
||||
unsafe { FUNCTION_LIST.clear() }
|
||||
// # Safety
|
||||
// This typically happens while no other execution happens.
|
||||
// In theory there is a race, but we can ignore it _for this use case_.
|
||||
unsafe {
|
||||
let function_list = &mut *addr_of_mut!(FUNCTION_LIST);
|
||||
function_list.clear();
|
||||
}
|
||||
}
|
||||
|
||||
fn post_exec(&mut self, _state: &mut S, _input: &<S as UsesInput>::Input) {}
|
||||
|
@ -7,6 +7,7 @@
|
||||
feature = "sancov_ctx"
|
||||
))]
|
||||
use alloc::borrow::Cow;
|
||||
use core::ptr::addr_of_mut;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_vendor = "apple"))]
|
||||
use libafl::{mutators::Tokens, Error};
|
||||
@ -157,7 +158,7 @@ pub fn edges_map_mut_ptr() -> *mut u8 {
|
||||
assert!(!EDGES_MAP_PTR.is_null());
|
||||
EDGES_MAP_PTR
|
||||
} else {
|
||||
EDGES_MAP.as_mut_ptr()
|
||||
addr_of_mut!(EDGES_MAP) as *mut u8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! [`LLVM` `8-bit-counters`](https://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs-with-guards) runtime for `LibAFL`.
|
||||
use alloc::vec::Vec;
|
||||
use core::ptr::addr_of_mut;
|
||||
use core::ptr::{addr_of, addr_of_mut};
|
||||
|
||||
use libafl_bolts::{ownedref::OwnedMutSlice, AsSlice, AsSliceMut};
|
||||
|
||||
@ -14,7 +14,8 @@ pub static mut COUNTERS_MAPS: Vec<OwnedMutSlice<'static, u8>> = Vec::new();
|
||||
/// You are responsible for ensuring there is no multi-mutability!
|
||||
#[must_use]
|
||||
pub unsafe fn extra_counters() -> Vec<OwnedMutSlice<'static, u8>> {
|
||||
COUNTERS_MAPS
|
||||
let counter_maps = &*addr_of!(COUNTERS_MAPS);
|
||||
counter_maps
|
||||
.iter()
|
||||
.map(|counters| {
|
||||
OwnedMutSlice::from_raw_parts_mut(
|
||||
@ -31,7 +32,8 @@ pub unsafe fn extra_counters() -> Vec<OwnedMutSlice<'static, u8>> {
|
||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||
pub extern "C" fn __sanitizer_cov_8bit_counters_init(start: *mut u8, stop: *mut u8) {
|
||||
unsafe {
|
||||
for existing in &mut *addr_of_mut!(COUNTERS_MAPS) {
|
||||
let counter_maps = &mut *addr_of_mut!(COUNTERS_MAPS);
|
||||
for existing in counter_maps {
|
||||
let range = existing.as_slice_mut().as_mut_ptr()
|
||||
..=existing
|
||||
.as_slice_mut()
|
||||
@ -46,8 +48,10 @@ pub extern "C" fn __sanitizer_cov_8bit_counters_init(start: *mut u8, stop: *mut
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let counter_maps = &mut *addr_of_mut!(COUNTERS_MAPS);
|
||||
// we didn't overlap; keep going
|
||||
COUNTERS_MAPS.push(OwnedMutSlice::from_raw_parts_mut(
|
||||
counter_maps.push(OwnedMutSlice::from_raw_parts_mut(
|
||||
start,
|
||||
stop.offset_from(start) as usize,
|
||||
));
|
||||
@ -327,7 +331,10 @@ mod observers {
|
||||
type IntoIter = Flatten<Iter<'it, OwnedMutSlice<'static, u8>>>;
|
||||
|
||||
fn as_iter(&'it self) -> Self::IntoIter {
|
||||
unsafe { COUNTERS_MAPS.iter().flatten() }
|
||||
unsafe {
|
||||
let counters_maps = &*addr_of!(COUNTERS_MAPS);
|
||||
counters_maps.iter().flatten()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -336,7 +343,10 @@ mod observers {
|
||||
type IntoIterMut = Flatten<IterMut<'it, OwnedMutSlice<'static, u8>>>;
|
||||
|
||||
fn as_iter_mut(&'it mut self) -> Self::IntoIterMut {
|
||||
unsafe { COUNTERS_MAPS.iter_mut().flatten() }
|
||||
unsafe {
|
||||
let counters_maps = &mut *addr_of_mut!(COUNTERS_MAPS);
|
||||
counters_maps.iter_mut().flatten()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,8 @@ pub static SHR_4: Ngram4 = Ngram4::from_array([1, 1, 1, 1]);
|
||||
#[rustversion::nightly]
|
||||
pub static SHR_8: Ngram8 = Ngram8::from_array([1, 1, 1, 1, 1, 1, 1, 1]);
|
||||
|
||||
static mut PC_TABLES: Vec<&'static [PcTableEntry]> = Vec::new();
|
||||
|
||||
use alloc::vec::Vec;
|
||||
#[cfg(any(
|
||||
feature = "sancov_ngram4",
|
||||
@ -184,17 +186,19 @@ unsafe fn update_ngram(pos: usize) -> usize {
|
||||
let mut reduced = pos;
|
||||
#[cfg(feature = "sancov_ngram4")]
|
||||
{
|
||||
PREV_ARRAY_4 = PREV_ARRAY_4.rotate_elements_right::<1>();
|
||||
PREV_ARRAY_4.shl_assign(SHR_4);
|
||||
PREV_ARRAY_4.as_mut_array()[0] = pos as u32;
|
||||
reduced = PREV_ARRAY_4.reduce_xor() as usize;
|
||||
let prev_array_4 = &mut *core::ptr::addr_of_mut!(PREV_ARRAY_4);
|
||||
*prev_array_4 = prev_array_4.rotate_elements_right::<1>();
|
||||
prev_array_4.shl_assign(SHR_4);
|
||||
prev_array_4.as_mut_array()[0] = pos as u32;
|
||||
reduced = prev_array_4.reduce_xor() as usize;
|
||||
}
|
||||
#[cfg(feature = "sancov_ngram8")]
|
||||
{
|
||||
PREV_ARRAY_8 = PREV_ARRAY_8.rotate_elements_right::<1>();
|
||||
PREV_ARRAY_8.shl_assign(SHR_8);
|
||||
PREV_ARRAY_8.as_mut_array()[0] = pos as u32;
|
||||
reduced = PREV_ARRAY_8.reduce_xor() as usize;
|
||||
let prev_array_8 = &mut *core::ptr::addr_of_mut!(PREV_ARRAY_8);
|
||||
*prev_array_8 = prev_array_8.rotate_elements_right::<1>();
|
||||
prev_array_8.shl_assign(SHR_8);
|
||||
prev_array_8.as_mut_array()[0] = pos as u32;
|
||||
reduced = prev_array_8.reduce_xor() as usize;
|
||||
}
|
||||
reduced %= EDGES_MAP_SIZE_IN_USE;
|
||||
reduced
|
||||
@ -269,7 +273,7 @@ pub unsafe extern "C" fn __sanitizer_cov_trace_pc_guard(guard: *mut u32) {
|
||||
pub unsafe extern "C" fn __sanitizer_cov_trace_pc_guard_init(mut start: *mut u32, stop: *mut u32) {
|
||||
#[cfg(feature = "pointer_maps")]
|
||||
if EDGES_MAP_PTR.is_null() {
|
||||
EDGES_MAP_PTR = EDGES_MAP.as_mut_ptr();
|
||||
EDGES_MAP_PTR = core::ptr::addr_of_mut!(EDGES_MAP) as *mut u8;
|
||||
}
|
||||
|
||||
if start == stop || *start != 0 {
|
||||
@ -292,8 +296,6 @@ pub unsafe extern "C" fn __sanitizer_cov_trace_pc_guard_init(mut start: *mut u32
|
||||
}
|
||||
}
|
||||
|
||||
static mut PC_TABLES: Vec<&'static [PcTableEntry]> = Vec::new();
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn __sanitizer_cov_pcs_init(pcs_beg: *const usize, pcs_end: *const usize) {
|
||||
// "The Unsafe Code Guidelines also notably defines that usize and isize are respectively compatible with uintptr_t and intptr_t defined in C."
|
||||
@ -312,7 +314,8 @@ unsafe extern "C" fn __sanitizer_cov_pcs_init(pcs_beg: *const usize, pcs_end: *c
|
||||
"Unaligned PC Table - start: {pcs_beg:x?} end: {pcs_end:x?}"
|
||||
);
|
||||
|
||||
PC_TABLES.push(slice::from_raw_parts(pcs_beg as *const PcTableEntry, len));
|
||||
let pc_tables = &mut *core::ptr::addr_of_mut!(PC_TABLES);
|
||||
pc_tables.push(slice::from_raw_parts(pcs_beg as *const PcTableEntry, len));
|
||||
}
|
||||
|
||||
/// An entry to the `sanitizer_cov` `pc_table`
|
||||
@ -338,8 +341,11 @@ impl PcTableEntry {
|
||||
}
|
||||
|
||||
/// Returns an iterator over the PC tables. If no tables were registered, this will be empty.
|
||||
pub fn sanitizer_cov_pc_table() -> impl Iterator<Item = &'static [PcTableEntry]> {
|
||||
pub fn sanitizer_cov_pc_table<'a>() -> impl Iterator<Item = &'a [PcTableEntry]> {
|
||||
// SAFETY: Once PCS_BEG and PCS_END have been initialized, will not be written to again. So
|
||||
// there's no TOCTOU issue.
|
||||
unsafe { PC_TABLES.iter().copied() }
|
||||
unsafe {
|
||||
let pc_tables = &*core::ptr::addr_of!(PC_TABLES);
|
||||
pc_tables.iter().copied()
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user