From 0cb7b25f39da02e8eb5e34ce071ecc4d8abcea0a Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 24 Jan 2024 17:47:55 +0100 Subject: [PATCH] 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 --- docs/src/advanced_features/frida.md | 2 +- libafl/src/events/llmp.rs | 6 +- libafl/src/events/mod.rs | 6 +- libafl/src/events/simple.rs | 6 +- libafl/src/events/tcp.rs | 6 +- libafl/src/executors/hooks/inprocess.rs | 17 ++-- libafl/src/executors/hooks/inprocess_fork.rs | 24 +++-- libafl/src/executors/hooks/timer.rs | 24 +++-- libafl/src/executors/hooks/unix.rs | 42 ++++---- libafl/src/executors/hooks/windows.rs | 98 +++++++++---------- libafl/src/executors/inprocess.rs | 53 ++++++---- libafl/src/executors/inprocess_fork.rs | 35 ++++--- libafl/src/observers/mod.rs | 8 +- libafl_bolts/src/llmp.rs | 4 +- libafl_bolts/src/os/unix_signals.rs | 10 +- libafl_bolts/src/os/windows_exceptions.rs | 13 ++- libafl_frida/src/asan/asan_rt.rs | 9 +- libafl_frida/src/asan/errors.rs | 4 +- libafl_frida/src/lib.rs | 4 +- .../libafl_libfuzzer_runtime/src/merge.rs | 4 +- libafl_qemu/src/emu.rs | 8 +- libafl_qemu/src/executor.rs | 19 ++-- libafl_qemu/src/hooks.rs | 17 ++-- libafl_targets/build.rs | 1 + libafl_targets/src/sancov_8bit.rs | 36 ++++--- 25 files changed, 263 insertions(+), 193 deletions(-) diff --git a/docs/src/advanced_features/frida.md b/docs/src/advanced_features/frida.md index 336ee3a728..b538a99b0b 100644 --- a/docs/src/advanced_features/frida.md +++ b/docs/src/advanced_features/frida.md @@ -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, diff --git a/libafl/src/events/llmp.rs b/libafl/src/events/llmp.rs index b3aa10b084..808a56e9c9 100644 --- a/libafl/src/events/llmp.rs +++ b/libafl/src/events/llmp.rs @@ -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}"); } diff --git a/libafl/src/events/mod.rs b/libafl/src/events/mod.rs index a925631d87..fbf563e9c6 100644 --- a/libafl/src/events/mod.rs +++ b/libafl/src/events/mod.rs @@ -697,6 +697,8 @@ impl HasEventManagerId for NopEventManager { #[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(); diff --git a/libafl/src/events/simple.rs b/libafl/src/events/simple.rs index 27fbc8dded..eca401d7d4 100644 --- a/libafl/src/events/simple.rs +++ b/libafl/src/events/simple.rs @@ -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}"); } diff --git a/libafl/src/events/tcp.rs b/libafl/src/events/tcp.rs index 252d493afa..6b8d336ebd 100644 --- a/libafl/src/events/tcp.rs +++ b/libafl/src/events/tcp.rs @@ -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}"); } diff --git a/libafl/src/executors/hooks/inprocess.rs b/libafl/src/executors/hooks/inprocess.rs index 98a0b125d3..30a92c233f 100644 --- a/libafl/src/executors/hooks/inprocess.rs +++ b/libafl/src/executors/hooks/inprocess.rs @@ -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(&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::(); #[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, diff --git a/libafl/src/executors/hooks/inprocess_fork.rs b/libafl/src/executors/hooks/inprocess_fork.rs index 202bff975c..48e64e3db1 100644 --- a/libafl/src/executors/hooks/inprocess_fork.rs +++ b/libafl/src/executors/hooks/inprocess_fork.rs @@ -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::(); #[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), + ); } }, } diff --git a/libafl/src/executors/hooks/timer.rs b/libafl/src/executors/hooks/timer.rs index c35722b492..e402656bee 100644 --- a/libafl/src/executors/hooks/timer.rs +++ b/libafl/src/executors/hooks/timer.rs @@ -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); diff --git a/libafl/src/executors/hooks/unix.rs b/libafl/src/executors/hooks/unix.rs index 17be77cc50..a47fde335e 100644 --- a/libafl/src/executors/hooks/unix.rs +++ b/libafl/src/executors/hooks/unix.rs @@ -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, { 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::(); - let state = data.state_mut::(); - let input = data.take_current_input::<::Input>(); - let fuzzer = data.fuzzer_mut::(); - let event_mgr = data.event_mgr_mut::(); + let executor = (*data).executor_mut::(); + let state = (*data).state_mut::(); + let input = (*data).take_current_input::<::Input>(); + let fuzzer = (*data).fuzzer_mut::(); + let event_mgr = (*data).event_mgr_mut::(); run_observers_and_save_state::( 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); })); } diff --git a/libafl/src/executors/hooks/windows.rs b/libafl/src/executors/hooks/windows.rs index 47b6ff181a..bd72fa2d19 100644 --- a/libafl/src/executors/hooks/windows.rs +++ b/libafl/src/executors/hooks/windows.rs @@ -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, { - 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::(); + let executor = (*data).executor_mut::(); // 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::(); - let fuzzer = data.fuzzer_mut::(); - let event_mgr = data.event_mgr_mut::(); + let state = (*data).state_mut::(); + let fuzzer = (*data).fuzzer_mut::(); + let event_mgr = (*data).event_mgr_mut::(); log::error!("Child crashed!"); // Make sure we don't crash in the crash handler forever. - let input = data.take_current_input::<::Input>(); + let input = (*data).take_current_input::<::Input>(); run_observers_and_save_state::( 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, { 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::(); - let state = data.state_mut::(); - let fuzzer = data.fuzzer_mut::(); - let event_mgr = data.event_mgr_mut::(); + let executor = (*data).executor_mut::(); + let state = (*data).state_mut::(); + let fuzzer = (*data).fuzzer_mut::(); + let event_mgr = (*data).event_mgr_mut::(); - let input = data.take_current_input::<::Input>(); + let input = (*data).take_current_input::<::Input>(); run_observers_and_save_state::( 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); })); } diff --git a/libafl/src/executors/inprocess.rs b/libafl/src/executors/inprocess.rs index 5fd8c19524..b28e6677dc 100644 --- a/libafl/src/executors/inprocess.rs +++ b/libafl/src/executors/inprocess.rs @@ -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: &::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: &::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( // 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() +pub unsafe fn generic_inproc_crash_handler() where E: Executor + HasObservers, EM: EventFirer + EventRestarter, @@ -568,15 +583,15 @@ where E::State: HasExecutions + HasSolutions + HasCorpus, Z: HasObjective, { - 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::(); - let state = data.state_mut::(); - let event_mgr = data.event_mgr_mut::(); - let fuzzer = data.fuzzer_mut::(); - let input = data.take_current_input::<::Input>(); + if (*data).is_valid() { + let executor = (*data).executor_mut::(); + let state = (*data).state_mut::(); + let event_mgr = (*data).event_mgr_mut::(); + let fuzzer = (*data).fuzzer_mut::(); + let input = (*data).take_current_input::<::Input>(); run_observers_and_save_state::( executor, @@ -588,7 +603,7 @@ where ); } - data.set_in_handler(in_handler); + (*data).set_in_handler(in_handler); } #[cfg(test)] diff --git a/libafl/src/executors/inprocess_fork.rs b/libafl/src/executors/inprocess_fork.rs index e48c00d3dd..289392c6a1 100644 --- a/libafl/src/executors/inprocess_fork.rs +++ b/libafl/src/executors/inprocess_fork.rs @@ -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: &::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::(); + let data = addr_of_mut!(FORK_EXECUTOR_GLOBAL_DATA); + if !data.is_null() && (*data).is_valid() { + let executor = (*data).executor_mut::(); let observers = executor.observers_mut(); - let state = data.state_mut::(); + let state = (*data).state_mut::(); // Invalidate data to not execute again the observer hooks in the crash handler - let input = data.take_current_input::<::Input>(); + let input = (*data).take_current_input::<::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 } })); } diff --git a/libafl/src/observers/mod.rs b/libafl/src/observers/mod.rs index 15b6693a35..46c0e0e46f 100644 --- a/libafl/src/observers/mod.rs +++ b/libafl/src/observers/mod.rs @@ -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:?}"); diff --git a/libafl_bolts/src/llmp.rs b/libafl_bolts/src/llmp.rs index 49a0609b9f..00d0cd8a8e 100644 --- a/libafl_bolts/src/llmp.rs +++ b/libafl_bolts/src/llmp.rs @@ -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 { diff --git a/libafl_bolts/src/os/unix_signals.rs b/libafl_bolts/src/os/unix_signals.rs index eeba71a449..a105303937 100644 --- a/libafl_bolts/src/os/unix_signals.rs +++ b/libafl_bolts/src/os/unix_signals.rs @@ -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(handler: &mut T) -> Result<(), Error> { +pub unsafe fn setup_signal_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(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), }), diff --git a/libafl_bolts/src/os/windows_exceptions.rs b/libafl_bolts/src/os/windows_exceptions.rs index ee89f19a02..78451d62b0 100644 --- a/libafl_bolts/src/os/windows_exceptions.rs +++ b/libafl_bolts/src/os/windows_exceptions.rs @@ -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(handler: &mut T) -> Result<(), Error> { - let exceptions = handler.exceptions(); +pub unsafe fn setup_exception_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(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(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( 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), }), diff --git a/libafl_frida/src/asan/asan_rt.rs b/libafl_frida/src/asan/asan_rt.rs index 699a34b536..160c6ad589 100644 --- a/libafl_frida/src/asan/asan_rt.rs +++ b/libafl_frida/src/asan/asan_rt.rs @@ -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 { - unsafe { &ASAN_ERRORS } + unsafe { &*addr_of!(ASAN_ERRORS) } } /// Make sure the specified memory is unpoisoned diff --git a/libafl_frida/src/asan/errors.rs b/libafl_frida/src/asan/errors.rs index 9cb14cab0f..4fc791b8f9 100644 --- a/libafl_frida/src/asan/errors.rs +++ b/libafl_frida/src/asan/errors.rs @@ -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) -> Self { + pub fn new(errors: *const Option) -> Self { Self { - errors: OwnedPtr::Ptr(errors as *const Option), + errors: OwnedPtr::Ptr(errors), } } diff --git a/libafl_frida/src/lib.rs b/libafl_frida/src/lib.rs index cc58092ef1..f5c929809e 100644 --- a/libafl_frida/src/lib.rs +++ b/libafl_frida/src/lib.rs @@ -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)) //, ); { diff --git a/libafl_libfuzzer/libafl_libfuzzer_runtime/src/merge.rs b/libafl_libfuzzer/libafl_libfuzzer_runtime/src/merge.rs index fdba4f9561..569255ac08 100644 --- a/libafl_libfuzzer/libafl_libfuzzer_runtime/src/merge.rs +++ b/libafl_libfuzzer/libafl_libfuzzer_runtime/src/merge.rs @@ -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"); diff --git a/libafl_qemu/src/emu.rs b/libafl_qemu/src/emu.rs index dd4d5f176e..6c5bd5bed2 100644 --- a/libafl_qemu/src/emu.rs +++ b/libafl_qemu/src/emu.rs @@ -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" { diff --git a/libafl_qemu/src/executor.rs b/libafl_qemu/src/executor.rs index 602399c303..2e4be7b7f9 100644 --- a/libafl_qemu/src/executor.rs +++ b/libafl_qemu/src/executor.rs @@ -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, 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()); } diff --git a/libafl_qemu/src/hooks.rs b/libafl_qemu/src/hooks.rs index d0284a5d89..5454431e4d 100644 --- a/libafl_qemu/src/hooks.rs +++ b/libafl_qemu/src/hooks.rs @@ -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::(); - 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, i32) = transmute(*ptr); @@ -334,7 +334,6 @@ where } static mut HOOKS_IS_INITIALIZED: bool = false; -static mut FIRST_EXEC: bool = true; pub struct QemuHooks 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::, 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::, 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::, @@ -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::, ); 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::, ); 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::, ); 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::, ); NEW_THREAD_HOOKS.last_mut().unwrap().0 = id; diff --git a/libafl_targets/build.rs b/libafl_targets/build.rs index 81ee333262..62e20bb064 100644 --- a/libafl_targets/build.rs +++ b/libafl_targets/build.rs @@ -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"); diff --git a/libafl_targets/src/sancov_8bit.rs b/libafl_targets/src/sancov_8bit.rs index 94636d9401..96751eda57 100644 --- a/libafl_targets/src/sancov_8bit.rs +++ b/libafl_targets/src/sancov_8bit.rs @@ -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> { #[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::(); @@ -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>>; 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>>; fn into_iter(self) -> Self::IntoIter { - unsafe { &mut COUNTERS_MAPS }.iter_mut().flatten() + unsafe { &mut *addr_of_mut!(COUNTERS_MAPS) } + .iter_mut() + .flatten() } }