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:
parent
bb443027f7
commit
0cb7b25f39
@ -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,
|
||||
|
@ -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}");
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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}");
|
||||
}
|
||||
|
@ -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}");
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -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)]
|
||||
|
@ -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
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
@ -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:?}");
|
||||
|
@ -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 {
|
||||
|
@ -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),
|
||||
}),
|
||||
|
@ -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),
|
||||
}),
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)) //,
|
||||
);
|
||||
|
||||
{
|
||||
|
@ -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");
|
||||
|
@ -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" {
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user