Replace static borrows with addr_of!, rust 2024 compatibility (#1800)

* Less UB

* fmt

* fix warning

* clippy fixes

* addr_of_mut allthethings

* removed duplicate import

* fix imports

* remove comment

* more windows

* fmt

* fix tests

* fixes

* qemu

* fix more cases, qemu

* fix

* fmt
This commit is contained in:
Dominik Maier 2024-01-24 17:47:55 +01:00 committed by GitHub
parent bb443027f7
commit 0cb7b25f39
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 263 additions and 193 deletions

View File

@ -73,7 +73,7 @@ You can then link this observer to `FridaInProcessExecutor` as follows:
tuple_list!(
edges_observer,
time_observer,
AsanErrorsObserver::new(&ASAN_ERRORS)
AsanErrorsObserver::new(addr_of!(ASAN_ERRORS))
),
&mut fuzzer,
&mut state,

View File

@ -5,6 +5,8 @@ use alloc::{
string::{String, ToString},
vec::Vec,
};
#[cfg(all(unix, not(miri), feature = "std"))]
use core::ptr::addr_of_mut;
#[cfg(feature = "std")]
use core::sync::atomic::{compiler_fence, Ordering};
use core::{marker::PhantomData, num::NonZeroUsize, time::Duration};
@ -1261,7 +1263,9 @@ where
// We setup signal handlers to clean up shmem segments used by state restorer
#[cfg(all(unix, not(miri)))]
if let Err(_e) = unsafe { setup_signal_handler(&mut EVENTMGR_SIGHANDLER_STATE) } {
if let Err(_e) =
unsafe { setup_signal_handler(addr_of_mut!(EVENTMGR_SIGHANDLER_STATE)) }
{
// We can live without a proper ctrl+c signal handler. Print and ignore.
log::error!("Failed to setup signal handlers: {_e}");
}

View File

@ -697,6 +697,8 @@ impl<S> HasEventManagerId for NopEventManager<S> {
#[cfg(test)]
mod tests {
use core::ptr::addr_of_mut;
use libafl_bolts::{current_time, tuples::tuple_list, Named};
use tuple_list::tuple_list_type;
@ -711,7 +713,9 @@ mod tests {
#[test]
fn test_event_serde() {
let obv = unsafe { StdMapObserver::new("test", &mut MAP) };
let obv = unsafe {
StdMapObserver::from_mut_ptr("test", addr_of_mut!(MAP) as *mut u32, MAP.len())
};
let map = tuple_list!(obv);
let observers_buf = postcard::to_allocvec(&map).unwrap();

View File

@ -5,6 +5,8 @@ use alloc::{
string::{String, ToString},
vec::Vec,
};
#[cfg(all(unix, not(miri), feature = "std"))]
use core::ptr::addr_of_mut;
use core::{fmt::Debug, marker::PhantomData};
#[cfg(feature = "std")]
use core::{
@ -485,7 +487,9 @@ where
// We setup signal handlers to clean up shmem segments used by state restorer
#[cfg(all(unix, not(miri)))]
if let Err(_e) = unsafe { setup_signal_handler(&mut EVENTMGR_SIGHANDLER_STATE) } {
if let Err(_e) =
unsafe { setup_signal_handler(addr_of_mut!(EVENTMGR_SIGHANDLER_STATE)) }
{
// We can live without a proper ctrl+c signal handler. Print and ignore.
log::error!("Failed to setup signal handlers: {_e}");
}

View File

@ -5,6 +5,8 @@ use alloc::{
string::{String, ToString},
vec::Vec,
};
#[cfg(all(unix, feature = "std", not(miri)))]
use core::ptr::addr_of_mut;
use core::{
marker::PhantomData,
num::NonZeroUsize,
@ -1143,7 +1145,9 @@ where
// We setup signal handlers to clean up shmem segments used by state restorer
#[cfg(all(unix, not(miri)))]
if let Err(_e) = unsafe { setup_signal_handler(&mut EVENTMGR_SIGHANDLER_STATE) } {
if let Err(_e) =
unsafe { setup_signal_handler(addr_of_mut!(EVENTMGR_SIGHANDLER_STATE)) }
{
// We can live without a proper ctrl+c signal handler. Print and ignore.
log::error!("Failed to setup signal handlers: {_e}");
}

View File

@ -1,4 +1,6 @@
//! The hook for `InProcessExecutor`
#[cfg(any(unix, feature = "std"))]
use core::ptr::addr_of_mut;
#[cfg(any(unix, all(windows, feature = "std")))]
use core::sync::atomic::{compiler_fence, Ordering};
use core::{
@ -123,7 +125,7 @@ impl HasTimeout for InProcessHooks {
fn handle_timeout(&mut self, data: &mut InProcessExecutorHandlerData) -> bool {
#[cfg(not(target_os = "linux"))]
{
return false;
false
}
#[cfg(target_os = "linux")]
@ -190,10 +192,10 @@ impl ExecutorHook for InProcessHooks {
#[allow(unused_variables)]
fn pre_exec<EM, I, S, Z>(&mut self, fuzzer: &mut Z, state: &mut S, mgr: &mut EM, input: &I) {
#[cfg(feature = "std")]
{
let data = unsafe { &mut GLOBAL_STATE };
data.crash_handler = self.crash_handler;
data.timeout_handler = self.timeout_handler;
unsafe {
let data = addr_of_mut!(GLOBAL_STATE);
(*data).crash_handler = self.crash_handler;
(*data).timeout_handler = self.timeout_handler;
}
#[cfg(feature = "std")]
@ -209,7 +211,6 @@ impl ExecutorHook for InProcessHooks {
_mgr: &mut EM,
_input: &I,
) {
// let _data = unsafe { &mut GLOBAL_STATE };
// timeout stuff
#[cfg(feature = "std")]
self.timer_mut().unset_timer();
@ -230,7 +231,7 @@ impl InProcessHooks {
{
#[cfg_attr(miri, allow(unused_variables))]
unsafe {
let data = &mut GLOBAL_STATE;
let data = addr_of_mut!(GLOBAL_STATE);
#[cfg(feature = "std")]
unix_signal_handler::setup_panic_hook::<E, EM, OF, Z>();
#[cfg(all(not(miri), unix, feature = "std"))]
@ -263,7 +264,7 @@ impl InProcessHooks {
let ret;
#[cfg(feature = "std")]
unsafe {
let data = &mut GLOBAL_STATE;
let data = addr_of_mut!(GLOBAL_STATE);
crate::executors::hooks::windows::windows_exception_handler::setup_panic_hook::<
E,
EM,

View File

@ -2,7 +2,7 @@
use alloc::vec::Vec;
use core::{
ffi::c_void,
ptr::null,
ptr::{addr_of_mut, null},
sync::atomic::{compiler_fence, Ordering},
};
use std::intrinsics::transmute;
@ -44,9 +44,9 @@ impl ExecutorHook for InChildProcessHooks {
_input: &I,
) {
unsafe {
let data = &mut FORK_EXECUTOR_GLOBAL_DATA;
data.crash_handler = self.crash_handler;
data.timeout_handler = self.timeout_handler;
let data = addr_of_mut!(FORK_EXECUTOR_GLOBAL_DATA);
(*data).crash_handler = self.crash_handler;
(*data).timeout_handler = self.timeout_handler;
compiler_fence(Ordering::SeqCst);
}
}
@ -69,7 +69,7 @@ impl InChildProcessHooks {
{
#[cfg_attr(miri, allow(unused_variables))]
unsafe {
let data = &mut FORK_EXECUTOR_GLOBAL_DATA;
let data = addr_of_mut!(FORK_EXECUTOR_GLOBAL_DATA);
// child_signal_handlers::setup_child_panic_hook::<E, I, OT, S>();
#[cfg(not(miri))]
setup_signal_handler(data)?;
@ -153,14 +153,24 @@ impl Handler for InProcessForkExecutorGlobalData {
if !FORK_EXECUTOR_GLOBAL_DATA.timeout_handler.is_null() {
let func: ForkHandlerFuncPtr =
transmute(FORK_EXECUTOR_GLOBAL_DATA.timeout_handler);
(func)(signal, info, context, &mut FORK_EXECUTOR_GLOBAL_DATA);
(func)(
signal,
info,
context,
addr_of_mut!(FORK_EXECUTOR_GLOBAL_DATA),
);
}
},
_ => unsafe {
if !FORK_EXECUTOR_GLOBAL_DATA.crash_handler.is_null() {
let func: ForkHandlerFuncPtr =
transmute(FORK_EXECUTOR_GLOBAL_DATA.crash_handler);
(func)(signal, info, context, &mut FORK_EXECUTOR_GLOBAL_DATA);
(func)(
signal,
info,
context,
addr_of_mut!(FORK_EXECUTOR_GLOBAL_DATA),
);
}
},
}

View File

@ -12,7 +12,7 @@ use core::{
};
#[cfg(all(unix, not(target_os = "linux")))]
pub const ITIMER_REAL: core::ffi::c_int = 0;
pub(crate) const ITIMER_REAL: core::ffi::c_int = 0;
#[cfg(windows)]
use core::sync::atomic::{compiler_fence, Ordering};
@ -64,7 +64,7 @@ pub(crate) struct Itimerval {
#[cfg(all(feature = "std", unix, not(target_os = "linux")))]
extern "C" {
pub fn setitimer(
pub(crate) fn setitimer(
which: libc::c_int,
new_value: *mut Itimerval,
old_value: *mut Itimerval,
@ -156,6 +156,7 @@ impl TimerStruct {
/// Create a `TimerStruct` with the specified timeout
#[cfg(all(unix, not(target_os = "linux")))]
#[must_use]
pub fn new(exec_tmout: Duration) -> Self {
let milli_sec = exec_tmout.as_millis();
let it_value = Timeval {
@ -264,11 +265,11 @@ impl TimerStruct {
/// Set timer
pub fn set_timer(&mut self) {
unsafe {
let data = &mut GLOBAL_STATE;
let data = addr_of_mut!(GLOBAL_STATE);
write_volatile(&mut data.ptp_timer, Some(*self.ptp_timer()));
write_volatile(addr_of_mut!((*data).ptp_timer), Some(*self.ptp_timer()));
write_volatile(
&mut data.critical,
addr_of_mut!((*data).critical),
addr_of_mut!(*self.critical_mut()) as *mut c_void,
);
let tm: i64 = -self.milli_sec() * 10 * 1000;
@ -281,7 +282,7 @@ impl TimerStruct {
compiler_fence(Ordering::SeqCst);
EnterCriticalSection(self.critical_mut());
compiler_fence(Ordering::SeqCst);
data.in_target = 1;
(*data).in_target = 1;
compiler_fence(Ordering::SeqCst);
LeaveCriticalSection(self.critical_mut());
compiler_fence(Ordering::SeqCst);
@ -295,8 +296,11 @@ impl TimerStruct {
pub fn set_timer(&mut self) {
unsafe {
if self.batch_mode {
let data = &mut GLOBAL_STATE;
write_volatile(&mut data.executor_ptr, self as *mut _ as *mut c_void);
let data = addr_of_mut!(GLOBAL_STATE);
write_volatile(
addr_of_mut!((*data).executor_ptr),
self as *mut _ as *mut c_void,
);
if self.executions == 0 {
libc::timer_settime(self.timerid, 0, addr_of_mut!(self.itimerspec), null_mut());
@ -360,13 +364,13 @@ impl TimerStruct {
/// Disalarm
pub fn unset_timer(&mut self) {
unsafe {
let data = &mut GLOBAL_STATE;
let data = addr_of_mut!(GLOBAL_STATE);
compiler_fence(Ordering::SeqCst);
EnterCriticalSection(self.critical_mut());
compiler_fence(Ordering::SeqCst);
// Timeout handler will do nothing after we increment in_target value.
data.in_target = 0;
(*data).in_target = 0;
compiler_fence(Ordering::SeqCst);
LeaveCriticalSection(self.critical_mut());
compiler_fence(Ordering::SeqCst);

View File

@ -2,7 +2,7 @@
#[cfg(unix)]
pub mod unix_signal_handler {
use alloc::{boxed::Box, string::String, vec::Vec};
use core::mem::transmute;
use core::{mem::transmute, ptr::addr_of_mut};
use std::{io::Write, panic};
use libafl_bolts::os::unix_signals::{ucontext_t, Handler, Signal};
@ -26,7 +26,7 @@ pub mod unix_signal_handler {
Signal,
&mut siginfo_t,
Option<&mut ucontext_t>,
data: &mut InProcessExecutorHandlerData,
data: *mut InProcessExecutorHandlerData,
);
/// A handler that does nothing.
@ -47,23 +47,23 @@ pub mod unix_signal_handler {
context: Option<&mut ucontext_t>,
) {
unsafe {
let data = &mut GLOBAL_STATE;
let in_handler = data.set_in_handler(true);
let data = addr_of_mut!(GLOBAL_STATE);
let in_handler = (*data).set_in_handler(true);
match signal {
Signal::SigUser2 | Signal::SigAlarm => {
if !data.timeout_handler.is_null() {
let func: HandlerFuncPtr = transmute(data.timeout_handler);
if !(*data).timeout_handler.is_null() {
let func: HandlerFuncPtr = transmute((*data).timeout_handler);
(func)(signal, info, context, data);
}
}
_ => {
if !data.crash_handler.is_null() {
let func: HandlerFuncPtr = transmute(data.crash_handler);
if !(*data).crash_handler.is_null() {
let func: HandlerFuncPtr = transmute((*data).crash_handler);
(func)(signal, info, context, data);
}
}
}
data.set_in_handler(in_handler);
(*data).set_in_handler(in_handler);
}
}
@ -82,17 +82,17 @@ pub mod unix_signal_handler {
Z: HasObjective<Objective = OF, State = E::State>,
{
let old_hook = panic::take_hook();
panic::set_hook(Box::new(move |panic_info| {
panic::set_hook(Box::new(move |panic_info| unsafe {
old_hook(panic_info);
let data = unsafe { &mut GLOBAL_STATE };
let in_handler = data.set_in_handler(true);
if data.is_valid() {
let data = addr_of_mut!(GLOBAL_STATE);
let in_handler = (*data).set_in_handler(true);
if (*data).is_valid() {
// We are fuzzing!
let executor = data.executor_mut::<E>();
let state = data.state_mut::<E::State>();
let input = data.take_current_input::<<E::State as UsesInput>::Input>();
let fuzzer = data.fuzzer_mut::<Z>();
let event_mgr = data.event_mgr_mut::<EM>();
let executor = (*data).executor_mut::<E>();
let state = (*data).state_mut::<E::State>();
let input = (*data).take_current_input::<<E::State as UsesInput>::Input>();
let fuzzer = (*data).fuzzer_mut::<Z>();
let event_mgr = (*data).event_mgr_mut::<EM>();
run_observers_and_save_state::<E, EM, OF, Z>(
executor,
@ -103,11 +103,9 @@ pub mod unix_signal_handler {
ExitKind::Crash,
);
unsafe {
libc::_exit(128 + 6);
} // SIGABRT exit code
libc::_exit(128 + 6); // SIGABRT exit code
}
data.set_in_handler(in_handler);
(*data).set_in_handler(in_handler);
}));
}

View File

@ -2,7 +2,10 @@
#[cfg(all(windows, feature = "std"))]
pub mod windows_asan_handler {
use alloc::string::String;
use core::sync::atomic::{compiler_fence, Ordering};
use core::{
ptr::addr_of_mut,
sync::atomic::{compiler_fence, Ordering},
};
use windows::Win32::System::Threading::{
EnterCriticalSection, LeaveCriticalSection, CRITICAL_SECTION,
@ -30,26 +33,26 @@ pub mod windows_asan_handler {
E::State: HasExecutions + HasSolutions + HasCorpus,
Z: HasObjective<Objective = OF, State = E::State>,
{
let data = &mut GLOBAL_STATE;
data.set_in_handler(true);
let data = addr_of_mut!(GLOBAL_STATE);
(*data).set_in_handler(true);
// Have we set a timer_before?
if data.ptp_timer.is_some() {
if (*data).ptp_timer.is_some() {
/*
We want to prevent the timeout handler being run while the main thread is executing the crash handler
Timeout handler runs if it has access to the critical section or data.in_target == 0
Writing 0 to the data.in_target makes the timeout handler makes the timeout handler invalid.
*/
compiler_fence(Ordering::SeqCst);
EnterCriticalSection(data.critical as *mut CRITICAL_SECTION);
EnterCriticalSection((*data).critical as *mut CRITICAL_SECTION);
compiler_fence(Ordering::SeqCst);
data.in_target = 0;
(*data).in_target = 0;
compiler_fence(Ordering::SeqCst);
LeaveCriticalSection(data.critical as *mut CRITICAL_SECTION);
LeaveCriticalSection((*data).critical as *mut CRITICAL_SECTION);
compiler_fence(Ordering::SeqCst);
}
log::error!("ASAN detected crash!");
if data.current_input_ptr.is_null() {
if (*data).current_input_ptr.is_null() {
{
log::error!("Double crash\n");
log::error!(
@ -67,20 +70,20 @@ pub mod windows_asan_handler {
// TODO tell the parent to not restart
} else {
let executor = data.executor_mut::<E>();
let executor = (*data).executor_mut::<E>();
// reset timer
if data.ptp_timer.is_some() {
data.ptp_timer = None;
if (*data).ptp_timer.is_some() {
(*data).ptp_timer = None;
}
let state = data.state_mut::<E::State>();
let fuzzer = data.fuzzer_mut::<Z>();
let event_mgr = data.event_mgr_mut::<EM>();
let state = (*data).state_mut::<E::State>();
let fuzzer = (*data).fuzzer_mut::<Z>();
let event_mgr = (*data).event_mgr_mut::<EM>();
log::error!("Child crashed!");
// Make sure we don't crash in the crash handler forever.
let input = data.take_current_input::<<E::State as UsesInput>::Input>();
let input = (*data).take_current_input::<<E::State as UsesInput>::Input>();
run_observers_and_save_state::<E, EM, OF, Z>(
executor,
@ -106,6 +109,7 @@ pub mod windows_exception_handler {
ffi::c_void,
mem::transmute,
ptr,
ptr::addr_of_mut,
sync::atomic::{compiler_fence, Ordering},
};
#[cfg(feature = "std")]
@ -132,7 +136,7 @@ pub mod windows_exception_handler {
};
pub(crate) type HandlerFuncPtr =
unsafe fn(*mut EXCEPTION_POINTERS, &mut InProcessExecutorHandlerData);
unsafe fn(*mut EXCEPTION_POINTERS, *mut InProcessExecutorHandlerData);
/*pub unsafe fn nop_handler(
_code: ExceptionCode,
@ -145,13 +149,13 @@ pub mod windows_exception_handler {
#[allow(clippy::not_unsafe_ptr_arg_deref)]
fn handle(&mut self, _code: ExceptionCode, exception_pointers: *mut EXCEPTION_POINTERS) {
unsafe {
let data = &mut GLOBAL_STATE;
let in_handler = data.set_in_handler(true);
if !data.crash_handler.is_null() {
let func: HandlerFuncPtr = transmute(data.crash_handler);
let data = addr_of_mut!(GLOBAL_STATE);
let in_handler = (*data).set_in_handler(true);
if !(*data).crash_handler.is_null() {
let func: HandlerFuncPtr = transmute((*data).crash_handler);
(func)(exception_pointers, data);
}
data.set_in_handler(in_handler);
(*data).set_in_handler(in_handler);
}
}
@ -176,35 +180,33 @@ pub mod windows_exception_handler {
Z: HasObjective<Objective = OF, State = E::State>,
{
let old_hook = panic::take_hook();
panic::set_hook(Box::new(move |panic_info| {
let data = unsafe { &mut GLOBAL_STATE };
let in_handler = data.set_in_handler(true);
panic::set_hook(Box::new(move |panic_info| unsafe {
let data = addr_of_mut!(GLOBAL_STATE);
let in_handler = (*data).set_in_handler(true);
// Have we set a timer_before?
unsafe {
if data.ptp_timer.is_some() {
/*
We want to prevent the timeout handler being run while the main thread is executing the crash handler
Timeout handler runs if it has access to the critical section or data.in_target == 0
Writing 0 to the data.in_target makes the timeout handler makes the timeout handler invalid.
*/
compiler_fence(Ordering::SeqCst);
EnterCriticalSection(data.critical as *mut CRITICAL_SECTION);
compiler_fence(Ordering::SeqCst);
data.in_target = 0;
compiler_fence(Ordering::SeqCst);
LeaveCriticalSection(data.critical as *mut CRITICAL_SECTION);
compiler_fence(Ordering::SeqCst);
}
if (*data).ptp_timer.is_some() {
/*
We want to prevent the timeout handler being run while the main thread is executing the crash handler
Timeout handler runs if it has access to the critical section or data.in_target == 0
Writing 0 to the data.in_target makes the timeout handler makes the timeout handler invalid.
*/
compiler_fence(Ordering::SeqCst);
EnterCriticalSection((*data).critical as *mut CRITICAL_SECTION);
compiler_fence(Ordering::SeqCst);
(*data).in_target = 0;
compiler_fence(Ordering::SeqCst);
LeaveCriticalSection((*data).critical as *mut CRITICAL_SECTION);
compiler_fence(Ordering::SeqCst);
}
if data.is_valid() {
if (*data).is_valid() {
// We are fuzzing!
let executor = data.executor_mut::<E>();
let state = data.state_mut::<E::State>();
let fuzzer = data.fuzzer_mut::<Z>();
let event_mgr = data.event_mgr_mut::<EM>();
let executor = (*data).executor_mut::<E>();
let state = (*data).state_mut::<E::State>();
let fuzzer = (*data).fuzzer_mut::<Z>();
let event_mgr = (*data).event_mgr_mut::<EM>();
let input = data.take_current_input::<<E::State as UsesInput>::Input>();
let input = (*data).take_current_input::<<E::State as UsesInput>::Input>();
run_observers_and_save_state::<E, EM, OF, Z>(
executor,
@ -215,12 +217,10 @@ pub mod windows_exception_handler {
ExitKind::Crash,
);
unsafe {
ExitProcess(1);
}
ExitProcess(1);
}
old_hook(panic_info);
data.set_in_handler(in_handler);
(*data).set_in_handler(in_handler);
}));
}

View File

@ -10,7 +10,7 @@ use core::{
ffi::c_void,
fmt::{self, Debug, Formatter},
marker::PhantomData,
ptr::{null, write_volatile},
ptr::{addr_of_mut, null, write_volatile},
sync::atomic::{compiler_fence, Ordering},
time::Duration,
};
@ -175,17 +175,29 @@ where
input: &<Self as UsesInput>::Input,
) {
unsafe {
let data = &mut GLOBAL_STATE;
let data = addr_of_mut!(GLOBAL_STATE);
write_volatile(
&mut data.current_input_ptr,
addr_of_mut!((*data).current_input_ptr),
input as *const _ as *const c_void,
);
write_volatile(&mut data.executor_ptr, self as *const _ as *const c_void);
write_volatile(
addr_of_mut!((*data).executor_ptr),
self as *const _ as *const c_void,
);
// Direct raw pointers access /aliasing is pretty undefined behavior.
// Since the state and event may have moved in memory, refresh them right before the signal may happen
write_volatile(&mut data.state_ptr, state as *mut _ as *mut c_void);
write_volatile(&mut data.event_mgr_ptr, mgr as *mut _ as *mut c_void);
write_volatile(&mut data.fuzzer_ptr, fuzzer as *mut _ as *mut c_void);
write_volatile(
addr_of_mut!((*data).state_ptr),
state as *mut _ as *mut c_void,
);
write_volatile(
addr_of_mut!((*data).event_mgr_ptr),
mgr as *mut _ as *mut c_void,
);
write_volatile(
addr_of_mut!((*data).fuzzer_ptr),
fuzzer as *mut _ as *mut c_void,
);
compiler_fence(Ordering::SeqCst);
}
}
@ -200,9 +212,9 @@ where
_input: &<Self as UsesInput>::Input,
) {
unsafe {
let data = &mut GLOBAL_STATE;
let data = addr_of_mut!(GLOBAL_STATE);
write_volatile(&mut data.current_input_ptr, null());
write_volatile(addr_of_mut!((*data).current_input_ptr), null());
compiler_fence(Ordering::SeqCst);
}
}
@ -559,8 +571,11 @@ pub fn run_observers_and_save_state<E, EM, OF, Z>(
// TODO remove this after executor refactor and libafl qemu new executor
/// Expose a version of the crash handler that can be called from e.g. an emulator
///
/// # Safety
/// This will directly access `GLOBAL_STATE` and related data pointers
#[cfg(any(unix, feature = "std"))]
pub fn generic_inproc_crash_handler<E, EM, OF, Z>()
pub unsafe fn generic_inproc_crash_handler<E, EM, OF, Z>()
where
E: Executor<EM, Z> + HasObservers,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
@ -568,15 +583,15 @@ where
E::State: HasExecutions + HasSolutions + HasCorpus,
Z: HasObjective<Objective = OF, State = E::State>,
{
let data = unsafe { &mut GLOBAL_STATE };
let in_handler = data.set_in_handler(true);
let data = addr_of_mut!(GLOBAL_STATE);
let in_handler = (*data).set_in_handler(true);
if data.is_valid() {
let executor = data.executor_mut::<E>();
let state = data.state_mut::<E::State>();
let event_mgr = data.event_mgr_mut::<EM>();
let fuzzer = data.fuzzer_mut::<Z>();
let input = data.take_current_input::<<E::State as UsesInput>::Input>();
if (*data).is_valid() {
let executor = (*data).executor_mut::<E>();
let state = (*data).state_mut::<E::State>();
let event_mgr = (*data).event_mgr_mut::<EM>();
let fuzzer = (*data).fuzzer_mut::<Z>();
let input = (*data).take_current_input::<<E::State as UsesInput>::Input>();
run_observers_and_save_state::<E, EM, OF, Z>(
executor,
@ -588,7 +603,7 @@ where
);
}
data.set_in_handler(in_handler);
(*data).set_in_handler(in_handler);
}
#[cfg(test)]

View File

@ -1,11 +1,9 @@
//! The `GenericInProcessForkExecutor` to do forking before executing the harness in-processly
#[cfg(target_os = "linux")]
use core::ptr::addr_of_mut;
use core::{
ffi::c_void,
fmt::{self, Debug, Formatter},
marker::PhantomData,
ptr::{null_mut, write_volatile},
ptr::{addr_of_mut, null_mut, write_volatile},
sync::atomic::{compiler_fence, Ordering},
time::Duration,
};
@ -42,7 +40,7 @@ pub(crate) type ForkHandlerFuncPtr = unsafe fn(
Signal,
&mut siginfo_t,
Option<&mut ucontext_t>,
data: &mut InProcessForkExecutorGlobalData,
data: *mut InProcessForkExecutorGlobalData,
);
#[cfg(all(unix, not(target_os = "linux")))]
@ -277,13 +275,19 @@ where
input: &<Self as UsesInput>::Input,
) {
unsafe {
let data = &mut FORK_EXECUTOR_GLOBAL_DATA;
write_volatile(&mut data.executor_ptr, self as *const _ as *const c_void);
let data = addr_of_mut!(FORK_EXECUTOR_GLOBAL_DATA);
write_volatile(
&mut data.current_input_ptr,
addr_of_mut!((*data).executor_ptr),
self as *const _ as *const c_void,
);
write_volatile(
addr_of_mut!((*data).current_input_ptr),
input as *const _ as *const c_void,
);
write_volatile(&mut data.state_ptr, state as *mut _ as *mut c_void);
write_volatile(
addr_of_mut!((*data).state_ptr),
state as *mut _ as *mut c_void,
);
compiler_fence(Ordering::SeqCst);
}
}
@ -440,6 +444,7 @@ where
pub mod child_signal_handlers {
use alloc::boxed::Box;
use core::ptr::addr_of_mut;
use std::panic;
use libafl_bolts::os::unix_signals::{ucontext_t, Signal};
@ -460,21 +465,21 @@ pub mod child_signal_handlers {
E: HasObservers,
{
let old_hook = panic::take_hook();
panic::set_hook(Box::new(move |panic_info| {
panic::set_hook(Box::new(move |panic_info| unsafe {
old_hook(panic_info);
let data = unsafe { &mut FORK_EXECUTOR_GLOBAL_DATA };
if data.is_valid() {
let executor = data.executor_mut::<E>();
let data = addr_of_mut!(FORK_EXECUTOR_GLOBAL_DATA);
if !data.is_null() && (*data).is_valid() {
let executor = (*data).executor_mut::<E>();
let observers = executor.observers_mut();
let state = data.state_mut::<E::State>();
let state = (*data).state_mut::<E::State>();
// Invalidate data to not execute again the observer hooks in the crash handler
let input = data.take_current_input::<<E::State as UsesInput>::Input>();
let input = (*data).take_current_input::<<E::State as UsesInput>::Input>();
observers
.post_exec_child_all(state, input, &ExitKind::Crash)
.expect("Failed to run post_exec on observers");
// std::process::abort();
unsafe { libc::_exit(128 + 6) }; // ABORT exit code
libc::_exit(128 + 6); // ABORT exit code
}
}));
}

View File

@ -1384,7 +1384,10 @@ pub mod pybind {
#[cfg(test)]
mod tests {
use core::ptr::addr_of_mut;
use libafl_bolts::{
ownedref::OwnedMutSlice,
tuples::{tuple_list, tuple_list_type},
Named,
};
@ -1396,7 +1399,10 @@ mod tests {
#[test]
fn test_observer_serde() {
let obv = tuple_list!(TimeObserver::new("time"), unsafe {
StdMapObserver::new("map", &mut MAP)
StdMapObserver::from_ownedref(
"map",
OwnedMutSlice::from_raw_parts_mut(addr_of_mut!(MAP) as *mut u32, MAP.len()),
)
});
let vec = postcard::to_allocvec(&obv).unwrap();
log::info!("{vec:?}");

View File

@ -2267,9 +2267,7 @@ where
#[cfg(any(all(unix, not(miri)), all(windows, feature = "std")))]
fn setup_handlers() {
#[cfg(all(unix, not(miri)))]
if let Err(e) =
unsafe { setup_signal_handler(&mut *ptr::addr_of_mut!(LLMP_SIGHANDLER_STATE)) }
{
if let Err(e) = unsafe { setup_signal_handler(ptr::addr_of_mut!(LLMP_SIGHANDLER_STATE)) } {
// We can live without a proper ctrl+c signal handler - Ignore.
log::info!("Failed to setup signal handlers: {e}");
} else {

View File

@ -101,6 +101,7 @@ pub struct ucontext_t {
#[cfg(all(target_vendor = "apple", target_arch = "aarch64"))]
#[derive(Debug)]
#[repr(C)]
#[allow(clippy::pub_underscore_fields)]
pub struct arm_exception_state64 {
/// Virtual Fault Address
pub __far: u64,
@ -125,6 +126,7 @@ pub struct arm_exception_state64 {
#[cfg(all(target_vendor = "apple", target_arch = "aarch64"))]
#[derive(Debug)]
#[repr(C)]
#[allow(clippy::pub_underscore_fields)]
pub struct arm_thread_state64 {
/// General purpose registers x0-x28
pub __x: [u64; 29],
@ -170,6 +172,7 @@ pub struct arm_neon_state64 {
#[allow(non_camel_case_types)]
#[derive(Debug)]
#[repr(C)]
#[allow(clippy::pub_underscore_fields)]
pub struct mcontext64 {
/// _STRUCT_ARM_EXCEPTION_STATE64
pub __es: arm_exception_state64,
@ -427,9 +430,10 @@ unsafe fn handle_signal(sig: c_int, info: *mut siginfo_t, void: *mut c_void) {
/// # Safety
///
/// The signal handlers will be called on any signal. They should (tm) be async safe.
/// The handler pointer will be dereferenced, and the data the pointer points to may therefore not move.
/// A lot can go south in signal handling. Be sure you know what you are doing.
#[cfg(feature = "alloc")]
pub unsafe fn setup_signal_handler<T: 'static + Handler>(handler: &mut T) -> Result<(), Error> {
pub unsafe fn setup_signal_handler<T: 'static + Handler>(handler: *mut T) -> Result<(), Error> {
// First, set up our own stack to be used during segfault handling. (and specify `SA_ONSTACK` in `sigaction`)
if SIGNAL_STACK_PTR.is_null() {
SIGNAL_STACK_PTR = malloc(SIGNAL_STACK_SIZE);
@ -450,10 +454,10 @@ pub unsafe fn setup_signal_handler<T: 'static + Handler>(handler: &mut T) -> Res
sigaddset(addr_of_mut!(sa.sa_mask), SIGALRM);
sa.sa_flags = SA_NODEFER | SA_SIGINFO | SA_ONSTACK;
sa.sa_sigaction = handle_signal as usize;
let signals = handler.signals();
let signals = unsafe { (*handler).signals() };
for sig in signals {
write_volatile(
&mut SIGNAL_HANDLERS[sig as usize],
addr_of_mut!(SIGNAL_HANDLERS[sig as usize]),
Some(HandlerHolder {
handler: UnsafeCell::new(handler as *mut dyn Handler),
}),

View File

@ -5,8 +5,7 @@ use alloc::vec::Vec;
use core::{
cell::UnsafeCell,
fmt::{self, Display, Formatter},
ptr,
ptr::write_volatile,
ptr::{self, addr_of_mut, write_volatile},
sync::atomic::{compiler_fence, Ordering},
};
use std::os::raw::{c_long, c_void};
@ -384,8 +383,8 @@ unsafe extern "C" fn handle_signal(_signum: i32) {
/// # Safety
/// Exception handlers are usually ugly, handle with care!
#[cfg(feature = "alloc")]
pub unsafe fn setup_exception_handler<T: 'static + Handler>(handler: &mut T) -> Result<(), Error> {
let exceptions = handler.exceptions();
pub unsafe fn setup_exception_handler<T: 'static + Handler>(handler: *mut T) -> Result<(), Error> {
let exceptions = (*handler).exceptions();
let mut catch_assertions = false;
for exception_code in exceptions {
if exception_code == ExceptionCode::AssertionFailure {
@ -396,7 +395,7 @@ pub unsafe fn setup_exception_handler<T: 'static + Handler>(handler: &mut T) ->
.position(|x| *x == exception_code)
.unwrap();
write_volatile(
&mut EXCEPTION_HANDLERS[index],
addr_of_mut!(EXCEPTION_HANDLERS[index]),
Some(HandlerHolder {
handler: UnsafeCell::new(handler as *mut dyn Handler),
}),
@ -404,7 +403,7 @@ pub unsafe fn setup_exception_handler<T: 'static + Handler>(handler: &mut T) ->
}
write_volatile(
&mut EXCEPTION_HANDLERS[EXCEPTION_HANDLERS_SIZE - 1],
addr_of_mut!(EXCEPTION_HANDLERS[EXCEPTION_HANDLERS_SIZE - 1]),
Some(HandlerHolder {
handler: UnsafeCell::new(handler as *mut dyn Handler),
}),
@ -442,7 +441,7 @@ pub(crate) unsafe fn setup_ctrl_handler<T: 'static + CtrlHandler>(
handler: *mut T,
) -> Result<(), Error> {
write_volatile(
&mut CTRL_HANDLER,
addr_of_mut!(CTRL_HANDLER),
Some(CtrlHandlerHolder {
handler: UnsafeCell::new(handler as *mut dyn CtrlHandler),
}),

View File

@ -10,7 +10,12 @@ use core::{
fmt::{self, Debug, Formatter},
ptr::addr_of_mut,
};
use std::{ffi::c_void, num::NonZeroUsize, ptr::write_volatile, rc::Rc};
use std::{
ffi::c_void,
num::NonZeroUsize,
ptr::{addr_of, write_volatile},
rc::Rc,
};
use backtrace::Backtrace;
use dynasmrt::{dynasm, DynasmApi, DynasmLabelApi};
@ -338,7 +343,7 @@ impl AsanRuntime {
/// Returns the `AsanErrors` from the recent run
#[allow(clippy::unused_self)]
pub fn errors(&mut self) -> &Option<AsanErrors> {
unsafe { &ASAN_ERRORS }
unsafe { &*addr_of!(ASAN_ERRORS) }
}
/// Make sure the specified memory is unpoisoned

View File

@ -578,9 +578,9 @@ impl Named for AsanErrorsObserver {
impl AsanErrorsObserver {
/// Creates a new `AsanErrorsObserver`, pointing to a constant `AsanErrors` field
#[must_use]
pub fn new(errors: &'static Option<AsanErrors>) -> Self {
pub fn new(errors: *const Option<AsanErrors>) -> Self {
Self {
errors: OwnedPtr::Ptr(errors as *const Option<AsanErrors>),
errors: OwnedPtr::Ptr(errors),
}
}

View File

@ -346,7 +346,7 @@ impl Default for FridaOptions {
#[cfg(test)]
mod tests {
use std::sync::OnceLock;
use std::{ptr::addr_of, sync::OnceLock};
use clap::Parser;
use frida_gum::Gum;
@ -438,7 +438,7 @@ mod tests {
let mut fuzzer = StdFuzzer::new(StdScheduler::new(), feedback, objective);
let observers = tuple_list!(
AsanErrorsObserver::new(&ASAN_ERRORS) //,
AsanErrorsObserver::new(addr_of!(ASAN_ERRORS)) //,
);
{

View File

@ -4,7 +4,7 @@ use std::{
fs::{rename, File},
io::Write,
os::fd::{AsRawFd, FromRawFd},
time::{SystemTime, UNIX_EPOCH},
time::{SystemTime, UNIX_EPOCH}, ptr::addr_of_mut,
};
use libafl::{
@ -97,7 +97,7 @@ pub fn merge(
}
}
let edges = unsafe { core::mem::take(&mut COUNTERS_MAPS) };
let edges = unsafe { core::mem::take(&mut *addr_of_mut!(COUNTERS_MAPS)) };
let edges_observer = MultiMapObserver::new("edges", edges);
let time = TimeObserver::new("time");

View File

@ -49,12 +49,12 @@ macro_rules! extern_c_checked {
paste! {
#[allow(non_camel_case_types)]
#[allow(unused)]
struct [<__ $c_var:upper _STRUCT__>] { member: &'static $c_var_ty }
struct [<__ $c_var:upper _STRUCT__>] { member: *const $c_var_ty }
unsafe impl Sync for [<__ $c_var:upper _STRUCT__>] {}
#[cfg_attr(nightly, used(linker))]
static [<__ $c_var:upper __>]: [<__ $c_var:upper _STRUCT__>] = unsafe { [<__ $c_var:upper _STRUCT__>] { member: &$c_var } };
static [<__ $c_var:upper __>]: [<__ $c_var:upper _STRUCT__>] = unsafe { [<__ $c_var:upper _STRUCT__>] { member: core::ptr::addr_of!($c_var) } };
}
extern "C" {
@ -68,12 +68,12 @@ macro_rules! extern_c_checked {
paste! {
#[allow(non_camel_case_types)]
#[allow(unused)]
struct [<__ $c_var:upper _STRUCT__>] { member: &'static $c_var_ty }
struct [<__ $c_var:upper _STRUCT__>] { member: *const $c_var_ty }
unsafe impl Sync for [<__ $c_var:upper _STRUCT__>] {}
#[cfg_attr(nightly, used(linker))]
static mut [<__ $c_var:upper __>]: [<__ $c_var:upper _STRUCT__>] = unsafe { [<__ $c_var:upper _STRUCT__>] { member: &$c_var } };
static mut [<__ $c_var:upper __>]: [<__ $c_var:upper _STRUCT__>] = unsafe { [<__ $c_var:upper _STRUCT__>] { member: core::ptr::addr_of!($c_var) } };
}
extern "C" {

View File

@ -5,6 +5,8 @@ use core::{
time::Duration,
};
#[cfg(feature = "fork")]
use libafl::inputs::UsesInput;
#[cfg(feature = "fork")]
use libafl::{
events::EventManager,
@ -14,13 +16,12 @@ use libafl::{
use libafl::{
events::{EventFirer, EventRestarter},
executors::{
hooks::{inprocess::InProcessExecutorHandlerData, ExecutorHooksTuple},
hooks::inprocess::InProcessExecutorHandlerData,
inprocess::{HasInProcessHooks, InProcessExecutor},
Executor, ExitKind, HasObservers,
},
feedbacks::Feedback,
fuzzer::HasObjective,
inputs::UsesInput,
observers::{ObserversTuple, UsesObservers},
state::{HasCorpus, HasExecutions, HasSolutions, State, UsesState},
Error,
@ -147,12 +148,14 @@ where
let handler = |hooks: &mut QemuHooks<QT, S>, host_sig| {
eprintln!("Crashed with signal {host_sig}");
libafl::executors::inprocess::generic_inproc_crash_handler::<
InProcessExecutor<'a, H, OT, S>,
EM,
OF,
Z,
>();
unsafe {
libafl::executors::inprocess::generic_inproc_crash_handler::<
InProcessExecutor<'a, H, OT, S>,
EM,
OF,
Z,
>();
}
if let Some(cpu) = hooks.emulator().current_cpu() {
eprint!("Context:\n{}", cpu.display_context());
}

View File

@ -6,7 +6,7 @@ use core::{
fmt::{self, Debug, Formatter},
marker::PhantomData,
mem::transmute,
ptr::{self, addr_of},
ptr::{self, addr_of, addr_of_mut},
};
use libafl::{executors::hooks::inprocess::inprocess_get_state, inputs::UsesInput};
@ -317,7 +317,7 @@ where
{
unsafe {
let hooks = get_qemu_hooks::<QT, S>();
for hook in &mut CRASH_HOOKS {
for hook in &mut (*addr_of_mut!(CRASH_HOOKS)) {
match hook {
HookRepr::Function(ptr) => {
let func: fn(&mut QemuHooks<QT, S>, i32) = transmute(*ptr);
@ -334,7 +334,6 @@ where
}
static mut HOOKS_IS_INITIALIZED: bool = false;
static mut FIRST_EXEC: bool = true;
pub struct QemuHooks<QT, S>
where
@ -461,7 +460,7 @@ where
let fat: FatPtr = transmute(hook);
GENERIC_HOOKS.push((HookId(0), fat));
let id = self.emulator.set_hook(
&mut GENERIC_HOOKS.last_mut().unwrap().1,
&mut ((*addr_of_mut!(GENERIC_HOOKS)).last_mut().unwrap().1),
addr,
closure_generic_hook_wrapper::<QT, S>,
invalidate_block,
@ -662,6 +661,7 @@ where
}
}
#[allow(clippy::similar_names)]
pub fn writes(
&self,
generation_hook: Hook<
@ -728,7 +728,6 @@ where
write_3_exec_hook_wrapper::<QT, S>,
extern "C" fn(&mut HookState<5>, id: u64, addr: GuestAddr)
);
#[allow(clippy::similar_names)]
let execn = get_raw_hook!(
execution_hook_n,
write_4_exec_hook_wrapper::<QT, S>,
@ -874,7 +873,7 @@ where
let fat: FatPtr = transmute(hook);
BACKDOOR_HOOKS.push((HookId(0), fat));
let id = self.emulator.add_backdoor_hook(
&mut BACKDOOR_HOOKS.last_mut().unwrap().1,
&mut ((*addr_of_mut!(BACKDOOR_HOOKS)).last_mut().unwrap().1),
closure_backdoor_hook_wrapper::<QT, S>,
);
BACKDOOR_HOOKS.last_mut().unwrap().0 = id;
@ -988,7 +987,7 @@ where
let fat: FatPtr = transmute(hook);
PRE_SYSCALL_HOOKS.push((HookId(0), fat));
let id = self.emulator.add_pre_syscall_hook(
&mut PRE_SYSCALL_HOOKS.last_mut().unwrap().1,
&mut ((*addr_of_mut!(PRE_SYSCALL_HOOKS)).last_mut().unwrap().1),
closure_pre_syscall_hook_wrapper::<QT, S>,
);
PRE_SYSCALL_HOOKS.last_mut().unwrap().0 = id;
@ -1107,7 +1106,7 @@ where
let fat: FatPtr = transmute(hook);
POST_SYSCALL_HOOKS.push((HookId(0), fat));
let id = self.emulator.add_post_syscall_hook(
&mut POST_SYSCALL_HOOKS.last_mut().unwrap().1,
&mut ((*addr_of_mut!(POST_SYSCALL_HOOKS)).last_mut().unwrap().1),
closure_post_syscall_hook_wrapper::<QT, S>,
);
POST_SYSCALL_HOOKS.last_mut().unwrap().0 = id;
@ -1155,7 +1154,7 @@ where
let fat: FatPtr = transmute(hook);
NEW_THREAD_HOOKS.push((HookId(0), fat));
let id = self.emulator.add_new_thread_hook(
&mut NEW_THREAD_HOOKS.last_mut().unwrap().1,
&mut (*addr_of_mut!(NEW_THREAD_HOOKS)).last_mut().unwrap().1,
closure_new_thread_hook_wrapper::<QT, S>,
);
NEW_THREAD_HOOKS.last_mut().unwrap().0 = id;

View File

@ -7,6 +7,7 @@ fn main() {
let out_dir = env::var_os("OUT_DIR").unwrap();
let out_dir = out_dir.to_string_lossy().to_string();
//let out_dir_path = Path::new(&out_dir);
#[allow(unused_variables)]
let src_dir = Path::new("src");
let dest_path = Path::new(&out_dir).join("constants.rs");

View File

@ -1,5 +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 libafl_bolts::{ownedref::OwnedMutSlice, AsMutSlice, AsSlice};
@ -30,7 +31,7 @@ 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 COUNTERS_MAPS {
for existing in &mut *addr_of_mut!(COUNTERS_MAPS) {
let range = existing.as_mut_slice().as_mut_ptr()
..=existing
.as_mut_slice()
@ -66,6 +67,7 @@ mod observers {
fmt::Debug,
hash::{BuildHasher, Hasher},
iter::Flatten,
ptr::{addr_of, addr_of_mut},
slice::{from_raw_parts, Iter, IterMut},
};
@ -165,7 +167,7 @@ mod observers {
let elem = self.intervals.query(idx..=idx).next().unwrap();
let i = elem.value;
let j = idx - elem.interval.start;
unsafe { &COUNTERS_MAPS[*i].as_slice()[j] }
unsafe { &(*addr_of!(COUNTERS_MAPS[*i])).as_slice()[j] }
}
#[inline]
@ -173,7 +175,7 @@ mod observers {
let elem = self.intervals.query_mut(idx..=idx).next().unwrap();
let i = elem.value;
let j = idx - elem.interval.start;
unsafe { &mut COUNTERS_MAPS[*i].as_mut_slice()[j] }
unsafe { &mut (*addr_of_mut!(COUNTERS_MAPS[*i])).as_mut_slice()[j] }
}
#[inline]
@ -184,7 +186,7 @@ mod observers {
fn count_bytes(&self) -> u64 {
let initial = self.initial();
let mut res = 0;
for map in unsafe { &COUNTERS_MAPS } {
for map in unsafe { &*addr_of!(COUNTERS_MAPS) } {
for x in map.as_slice() {
if *x != initial {
res += 1;
@ -196,7 +198,7 @@ mod observers {
fn hash(&self) -> u64 {
let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher();
for map in unsafe { &COUNTERS_MAPS } {
for map in unsafe { &*addr_of!(COUNTERS_MAPS) } {
let slice = map.as_slice();
let ptr = slice.as_ptr();
let map_size = slice.len() / core::mem::size_of::<u8>();
@ -209,7 +211,7 @@ mod observers {
fn reset_map(&mut self) -> Result<(), Error> {
let initial = self.initial();
for map in unsafe { &mut COUNTERS_MAPS } {
for map in unsafe { &mut *addr_of_mut!(COUNTERS_MAPS) } {
for x in map.as_mut_slice() {
*x = initial;
}
@ -250,7 +252,7 @@ mod observers {
fn maybe_differential(name: &'static str) -> Self {
let mut idx = 0;
let mut intervals = IntervalTree::new();
for (v, x) in unsafe { &COUNTERS_MAPS }.iter().enumerate() {
for (v, x) in unsafe { &*addr_of!(COUNTERS_MAPS) }.iter().enumerate() {
let l = x.as_slice().len();
intervals.insert(idx..(idx + l), v);
idx += l;
@ -286,12 +288,14 @@ mod observers {
let mut idx = 0;
let mut v = 0;
let mut intervals = IntervalTree::new();
unsafe { &mut COUNTERS_MAPS }.iter_mut().for_each(|m| {
let l = m.as_mut_slice().len();
intervals.insert(idx..(idx + l), v);
idx += l;
v += 1;
});
unsafe { &mut *addr_of_mut!(COUNTERS_MAPS) }
.iter_mut()
.for_each(|m| {
let l = m.as_mut_slice().len();
intervals.insert(idx..(idx + l), v);
idx += l;
v += 1;
});
Self {
intervals,
len: idx,
@ -325,7 +329,7 @@ mod observers {
type IntoIter = Flatten<Iter<'it, OwnedMutSlice<'static, u8>>>;
fn into_iter(self) -> Self::IntoIter {
unsafe { &COUNTERS_MAPS }.iter().flatten()
unsafe { &*addr_of!(COUNTERS_MAPS) }.iter().flatten()
}
}
@ -336,7 +340,9 @@ mod observers {
type IntoIter = Flatten<IterMut<'it, OwnedMutSlice<'static, u8>>>;
fn into_iter(self) -> Self::IntoIter {
unsafe { &mut COUNTERS_MAPS }.iter_mut().flatten()
unsafe { &mut *addr_of_mut!(COUNTERS_MAPS) }
.iter_mut()
.flatten()
}
}