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!(
|
tuple_list!(
|
||||||
edges_observer,
|
edges_observer,
|
||||||
time_observer,
|
time_observer,
|
||||||
AsanErrorsObserver::new(&ASAN_ERRORS)
|
AsanErrorsObserver::new(addr_of!(ASAN_ERRORS))
|
||||||
),
|
),
|
||||||
&mut fuzzer,
|
&mut fuzzer,
|
||||||
&mut state,
|
&mut state,
|
||||||
|
@ -5,6 +5,8 @@ use alloc::{
|
|||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
|
#[cfg(all(unix, not(miri), feature = "std"))]
|
||||||
|
use core::ptr::addr_of_mut;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use core::sync::atomic::{compiler_fence, Ordering};
|
use core::sync::atomic::{compiler_fence, Ordering};
|
||||||
use core::{marker::PhantomData, num::NonZeroUsize, time::Duration};
|
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
|
// We setup signal handlers to clean up shmem segments used by state restorer
|
||||||
#[cfg(all(unix, not(miri)))]
|
#[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.
|
// We can live without a proper ctrl+c signal handler. Print and ignore.
|
||||||
log::error!("Failed to setup signal handlers: {_e}");
|
log::error!("Failed to setup signal handlers: {_e}");
|
||||||
}
|
}
|
||||||
|
@ -697,6 +697,8 @@ impl<S> HasEventManagerId for NopEventManager<S> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
|
use core::ptr::addr_of_mut;
|
||||||
|
|
||||||
use libafl_bolts::{current_time, tuples::tuple_list, Named};
|
use libafl_bolts::{current_time, tuples::tuple_list, Named};
|
||||||
use tuple_list::tuple_list_type;
|
use tuple_list::tuple_list_type;
|
||||||
|
|
||||||
@ -711,7 +713,9 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_event_serde() {
|
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 map = tuple_list!(obv);
|
||||||
let observers_buf = postcard::to_allocvec(&map).unwrap();
|
let observers_buf = postcard::to_allocvec(&map).unwrap();
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@ use alloc::{
|
|||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
|
#[cfg(all(unix, not(miri), feature = "std"))]
|
||||||
|
use core::ptr::addr_of_mut;
|
||||||
use core::{fmt::Debug, marker::PhantomData};
|
use core::{fmt::Debug, marker::PhantomData};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use core::{
|
use core::{
|
||||||
@ -485,7 +487,9 @@ where
|
|||||||
|
|
||||||
// We setup signal handlers to clean up shmem segments used by state restorer
|
// We setup signal handlers to clean up shmem segments used by state restorer
|
||||||
#[cfg(all(unix, not(miri)))]
|
#[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.
|
// We can live without a proper ctrl+c signal handler. Print and ignore.
|
||||||
log::error!("Failed to setup signal handlers: {_e}");
|
log::error!("Failed to setup signal handlers: {_e}");
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ use alloc::{
|
|||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
|
#[cfg(all(unix, feature = "std", not(miri)))]
|
||||||
|
use core::ptr::addr_of_mut;
|
||||||
use core::{
|
use core::{
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
num::NonZeroUsize,
|
num::NonZeroUsize,
|
||||||
@ -1143,7 +1145,9 @@ where
|
|||||||
|
|
||||||
// We setup signal handlers to clean up shmem segments used by state restorer
|
// We setup signal handlers to clean up shmem segments used by state restorer
|
||||||
#[cfg(all(unix, not(miri)))]
|
#[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.
|
// We can live without a proper ctrl+c signal handler. Print and ignore.
|
||||||
log::error!("Failed to setup signal handlers: {_e}");
|
log::error!("Failed to setup signal handlers: {_e}");
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
//! The hook for `InProcessExecutor`
|
//! The hook for `InProcessExecutor`
|
||||||
|
#[cfg(any(unix, feature = "std"))]
|
||||||
|
use core::ptr::addr_of_mut;
|
||||||
#[cfg(any(unix, all(windows, feature = "std")))]
|
#[cfg(any(unix, all(windows, feature = "std")))]
|
||||||
use core::sync::atomic::{compiler_fence, Ordering};
|
use core::sync::atomic::{compiler_fence, Ordering};
|
||||||
use core::{
|
use core::{
|
||||||
@ -123,7 +125,7 @@ impl HasTimeout for InProcessHooks {
|
|||||||
fn handle_timeout(&mut self, data: &mut InProcessExecutorHandlerData) -> bool {
|
fn handle_timeout(&mut self, data: &mut InProcessExecutorHandlerData) -> bool {
|
||||||
#[cfg(not(target_os = "linux"))]
|
#[cfg(not(target_os = "linux"))]
|
||||||
{
|
{
|
||||||
return false;
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
@ -190,10 +192,10 @@ impl ExecutorHook for InProcessHooks {
|
|||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn pre_exec<EM, I, S, Z>(&mut self, fuzzer: &mut Z, state: &mut S, mgr: &mut EM, input: &I) {
|
fn pre_exec<EM, I, S, Z>(&mut self, fuzzer: &mut Z, state: &mut S, mgr: &mut EM, input: &I) {
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
{
|
unsafe {
|
||||||
let data = unsafe { &mut GLOBAL_STATE };
|
let data = addr_of_mut!(GLOBAL_STATE);
|
||||||
data.crash_handler = self.crash_handler;
|
(*data).crash_handler = self.crash_handler;
|
||||||
data.timeout_handler = self.timeout_handler;
|
(*data).timeout_handler = self.timeout_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -209,7 +211,6 @@ impl ExecutorHook for InProcessHooks {
|
|||||||
_mgr: &mut EM,
|
_mgr: &mut EM,
|
||||||
_input: &I,
|
_input: &I,
|
||||||
) {
|
) {
|
||||||
// let _data = unsafe { &mut GLOBAL_STATE };
|
|
||||||
// timeout stuff
|
// timeout stuff
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
self.timer_mut().unset_timer();
|
self.timer_mut().unset_timer();
|
||||||
@ -230,7 +231,7 @@ impl InProcessHooks {
|
|||||||
{
|
{
|
||||||
#[cfg_attr(miri, allow(unused_variables))]
|
#[cfg_attr(miri, allow(unused_variables))]
|
||||||
unsafe {
|
unsafe {
|
||||||
let data = &mut GLOBAL_STATE;
|
let data = addr_of_mut!(GLOBAL_STATE);
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
unix_signal_handler::setup_panic_hook::<E, EM, OF, Z>();
|
unix_signal_handler::setup_panic_hook::<E, EM, OF, Z>();
|
||||||
#[cfg(all(not(miri), unix, feature = "std"))]
|
#[cfg(all(not(miri), unix, feature = "std"))]
|
||||||
@ -263,7 +264,7 @@ impl InProcessHooks {
|
|||||||
let ret;
|
let ret;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
unsafe {
|
unsafe {
|
||||||
let data = &mut GLOBAL_STATE;
|
let data = addr_of_mut!(GLOBAL_STATE);
|
||||||
crate::executors::hooks::windows::windows_exception_handler::setup_panic_hook::<
|
crate::executors::hooks::windows::windows_exception_handler::setup_panic_hook::<
|
||||||
E,
|
E,
|
||||||
EM,
|
EM,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::{
|
use core::{
|
||||||
ffi::c_void,
|
ffi::c_void,
|
||||||
ptr::null,
|
ptr::{addr_of_mut, null},
|
||||||
sync::atomic::{compiler_fence, Ordering},
|
sync::atomic::{compiler_fence, Ordering},
|
||||||
};
|
};
|
||||||
use std::intrinsics::transmute;
|
use std::intrinsics::transmute;
|
||||||
@ -44,9 +44,9 @@ impl ExecutorHook for InChildProcessHooks {
|
|||||||
_input: &I,
|
_input: &I,
|
||||||
) {
|
) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data = &mut FORK_EXECUTOR_GLOBAL_DATA;
|
let data = addr_of_mut!(FORK_EXECUTOR_GLOBAL_DATA);
|
||||||
data.crash_handler = self.crash_handler;
|
(*data).crash_handler = self.crash_handler;
|
||||||
data.timeout_handler = self.timeout_handler;
|
(*data).timeout_handler = self.timeout_handler;
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,7 +69,7 @@ impl InChildProcessHooks {
|
|||||||
{
|
{
|
||||||
#[cfg_attr(miri, allow(unused_variables))]
|
#[cfg_attr(miri, allow(unused_variables))]
|
||||||
unsafe {
|
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>();
|
// child_signal_handlers::setup_child_panic_hook::<E, I, OT, S>();
|
||||||
#[cfg(not(miri))]
|
#[cfg(not(miri))]
|
||||||
setup_signal_handler(data)?;
|
setup_signal_handler(data)?;
|
||||||
@ -153,14 +153,24 @@ impl Handler for InProcessForkExecutorGlobalData {
|
|||||||
if !FORK_EXECUTOR_GLOBAL_DATA.timeout_handler.is_null() {
|
if !FORK_EXECUTOR_GLOBAL_DATA.timeout_handler.is_null() {
|
||||||
let func: ForkHandlerFuncPtr =
|
let func: ForkHandlerFuncPtr =
|
||||||
transmute(FORK_EXECUTOR_GLOBAL_DATA.timeout_handler);
|
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 {
|
_ => unsafe {
|
||||||
if !FORK_EXECUTOR_GLOBAL_DATA.crash_handler.is_null() {
|
if !FORK_EXECUTOR_GLOBAL_DATA.crash_handler.is_null() {
|
||||||
let func: ForkHandlerFuncPtr =
|
let func: ForkHandlerFuncPtr =
|
||||||
transmute(FORK_EXECUTOR_GLOBAL_DATA.crash_handler);
|
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")))]
|
#[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)]
|
#[cfg(windows)]
|
||||||
use core::sync::atomic::{compiler_fence, Ordering};
|
use core::sync::atomic::{compiler_fence, Ordering};
|
||||||
@ -64,7 +64,7 @@ pub(crate) struct Itimerval {
|
|||||||
|
|
||||||
#[cfg(all(feature = "std", unix, not(target_os = "linux")))]
|
#[cfg(all(feature = "std", unix, not(target_os = "linux")))]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn setitimer(
|
pub(crate) fn setitimer(
|
||||||
which: libc::c_int,
|
which: libc::c_int,
|
||||||
new_value: *mut Itimerval,
|
new_value: *mut Itimerval,
|
||||||
old_value: *mut Itimerval,
|
old_value: *mut Itimerval,
|
||||||
@ -156,6 +156,7 @@ impl TimerStruct {
|
|||||||
|
|
||||||
/// Create a `TimerStruct` with the specified timeout
|
/// Create a `TimerStruct` with the specified timeout
|
||||||
#[cfg(all(unix, not(target_os = "linux")))]
|
#[cfg(all(unix, not(target_os = "linux")))]
|
||||||
|
#[must_use]
|
||||||
pub fn new(exec_tmout: Duration) -> Self {
|
pub fn new(exec_tmout: Duration) -> Self {
|
||||||
let milli_sec = exec_tmout.as_millis();
|
let milli_sec = exec_tmout.as_millis();
|
||||||
let it_value = Timeval {
|
let it_value = Timeval {
|
||||||
@ -264,11 +265,11 @@ impl TimerStruct {
|
|||||||
/// Set timer
|
/// Set timer
|
||||||
pub fn set_timer(&mut self) {
|
pub fn set_timer(&mut self) {
|
||||||
unsafe {
|
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(
|
write_volatile(
|
||||||
&mut data.critical,
|
addr_of_mut!((*data).critical),
|
||||||
addr_of_mut!(*self.critical_mut()) as *mut c_void,
|
addr_of_mut!(*self.critical_mut()) as *mut c_void,
|
||||||
);
|
);
|
||||||
let tm: i64 = -self.milli_sec() * 10 * 1000;
|
let tm: i64 = -self.milli_sec() * 10 * 1000;
|
||||||
@ -281,7 +282,7 @@ impl TimerStruct {
|
|||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
EnterCriticalSection(self.critical_mut());
|
EnterCriticalSection(self.critical_mut());
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
data.in_target = 1;
|
(*data).in_target = 1;
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
LeaveCriticalSection(self.critical_mut());
|
LeaveCriticalSection(self.critical_mut());
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
@ -295,8 +296,11 @@ impl TimerStruct {
|
|||||||
pub fn set_timer(&mut self) {
|
pub fn set_timer(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if self.batch_mode {
|
if self.batch_mode {
|
||||||
let data = &mut GLOBAL_STATE;
|
let data = addr_of_mut!(GLOBAL_STATE);
|
||||||
write_volatile(&mut data.executor_ptr, self as *mut _ as *mut c_void);
|
write_volatile(
|
||||||
|
addr_of_mut!((*data).executor_ptr),
|
||||||
|
self as *mut _ as *mut c_void,
|
||||||
|
);
|
||||||
|
|
||||||
if self.executions == 0 {
|
if self.executions == 0 {
|
||||||
libc::timer_settime(self.timerid, 0, addr_of_mut!(self.itimerspec), null_mut());
|
libc::timer_settime(self.timerid, 0, addr_of_mut!(self.itimerspec), null_mut());
|
||||||
@ -360,13 +364,13 @@ impl TimerStruct {
|
|||||||
/// Disalarm
|
/// Disalarm
|
||||||
pub fn unset_timer(&mut self) {
|
pub fn unset_timer(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data = &mut GLOBAL_STATE;
|
let data = addr_of_mut!(GLOBAL_STATE);
|
||||||
|
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
EnterCriticalSection(self.critical_mut());
|
EnterCriticalSection(self.critical_mut());
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
// Timeout handler will do nothing after we increment in_target value.
|
// Timeout handler will do nothing after we increment in_target value.
|
||||||
data.in_target = 0;
|
(*data).in_target = 0;
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
LeaveCriticalSection(self.critical_mut());
|
LeaveCriticalSection(self.critical_mut());
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub mod unix_signal_handler {
|
pub mod unix_signal_handler {
|
||||||
use alloc::{boxed::Box, string::String, vec::Vec};
|
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 std::{io::Write, panic};
|
||||||
|
|
||||||
use libafl_bolts::os::unix_signals::{ucontext_t, Handler, Signal};
|
use libafl_bolts::os::unix_signals::{ucontext_t, Handler, Signal};
|
||||||
@ -26,7 +26,7 @@ pub mod unix_signal_handler {
|
|||||||
Signal,
|
Signal,
|
||||||
&mut siginfo_t,
|
&mut siginfo_t,
|
||||||
Option<&mut ucontext_t>,
|
Option<&mut ucontext_t>,
|
||||||
data: &mut InProcessExecutorHandlerData,
|
data: *mut InProcessExecutorHandlerData,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// A handler that does nothing.
|
/// A handler that does nothing.
|
||||||
@ -47,23 +47,23 @@ pub mod unix_signal_handler {
|
|||||||
context: Option<&mut ucontext_t>,
|
context: Option<&mut ucontext_t>,
|
||||||
) {
|
) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data = &mut GLOBAL_STATE;
|
let data = addr_of_mut!(GLOBAL_STATE);
|
||||||
let in_handler = data.set_in_handler(true);
|
let in_handler = (*data).set_in_handler(true);
|
||||||
match signal {
|
match signal {
|
||||||
Signal::SigUser2 | Signal::SigAlarm => {
|
Signal::SigUser2 | Signal::SigAlarm => {
|
||||||
if !data.timeout_handler.is_null() {
|
if !(*data).timeout_handler.is_null() {
|
||||||
let func: HandlerFuncPtr = transmute(data.timeout_handler);
|
let func: HandlerFuncPtr = transmute((*data).timeout_handler);
|
||||||
(func)(signal, info, context, data);
|
(func)(signal, info, context, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if !data.crash_handler.is_null() {
|
if !(*data).crash_handler.is_null() {
|
||||||
let func: HandlerFuncPtr = transmute(data.crash_handler);
|
let func: HandlerFuncPtr = transmute((*data).crash_handler);
|
||||||
(func)(signal, info, context, data);
|
(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>,
|
Z: HasObjective<Objective = OF, State = E::State>,
|
||||||
{
|
{
|
||||||
let old_hook = panic::take_hook();
|
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);
|
old_hook(panic_info);
|
||||||
let data = unsafe { &mut GLOBAL_STATE };
|
let data = addr_of_mut!(GLOBAL_STATE);
|
||||||
let in_handler = data.set_in_handler(true);
|
let in_handler = (*data).set_in_handler(true);
|
||||||
if data.is_valid() {
|
if (*data).is_valid() {
|
||||||
// We are fuzzing!
|
// We are fuzzing!
|
||||||
let executor = data.executor_mut::<E>();
|
let executor = (*data).executor_mut::<E>();
|
||||||
let state = data.state_mut::<E::State>();
|
let state = (*data).state_mut::<E::State>();
|
||||||
let input = data.take_current_input::<<E::State as UsesInput>::Input>();
|
let input = (*data).take_current_input::<<E::State as UsesInput>::Input>();
|
||||||
let fuzzer = data.fuzzer_mut::<Z>();
|
let fuzzer = (*data).fuzzer_mut::<Z>();
|
||||||
let event_mgr = data.event_mgr_mut::<EM>();
|
let event_mgr = (*data).event_mgr_mut::<EM>();
|
||||||
|
|
||||||
run_observers_and_save_state::<E, EM, OF, Z>(
|
run_observers_and_save_state::<E, EM, OF, Z>(
|
||||||
executor,
|
executor,
|
||||||
@ -103,11 +103,9 @@ pub mod unix_signal_handler {
|
|||||||
ExitKind::Crash,
|
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"))]
|
#[cfg(all(windows, feature = "std"))]
|
||||||
pub mod windows_asan_handler {
|
pub mod windows_asan_handler {
|
||||||
use alloc::string::String;
|
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::{
|
use windows::Win32::System::Threading::{
|
||||||
EnterCriticalSection, LeaveCriticalSection, CRITICAL_SECTION,
|
EnterCriticalSection, LeaveCriticalSection, CRITICAL_SECTION,
|
||||||
@ -30,26 +33,26 @@ pub mod windows_asan_handler {
|
|||||||
E::State: HasExecutions + HasSolutions + HasCorpus,
|
E::State: HasExecutions + HasSolutions + HasCorpus,
|
||||||
Z: HasObjective<Objective = OF, State = E::State>,
|
Z: HasObjective<Objective = OF, State = E::State>,
|
||||||
{
|
{
|
||||||
let data = &mut GLOBAL_STATE;
|
let data = addr_of_mut!(GLOBAL_STATE);
|
||||||
data.set_in_handler(true);
|
(*data).set_in_handler(true);
|
||||||
// Have we set a timer_before?
|
// 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
|
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
|
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.
|
Writing 0 to the data.in_target makes the timeout handler makes the timeout handler invalid.
|
||||||
*/
|
*/
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
EnterCriticalSection(data.critical as *mut CRITICAL_SECTION);
|
EnterCriticalSection((*data).critical as *mut CRITICAL_SECTION);
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
data.in_target = 0;
|
(*data).in_target = 0;
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
LeaveCriticalSection(data.critical as *mut CRITICAL_SECTION);
|
LeaveCriticalSection((*data).critical as *mut CRITICAL_SECTION);
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
log::error!("ASAN detected crash!");
|
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!("Double crash\n");
|
||||||
log::error!(
|
log::error!(
|
||||||
@ -67,20 +70,20 @@ pub mod windows_asan_handler {
|
|||||||
|
|
||||||
// TODO tell the parent to not restart
|
// TODO tell the parent to not restart
|
||||||
} else {
|
} else {
|
||||||
let executor = data.executor_mut::<E>();
|
let executor = (*data).executor_mut::<E>();
|
||||||
// reset timer
|
// reset timer
|
||||||
if data.ptp_timer.is_some() {
|
if (*data).ptp_timer.is_some() {
|
||||||
data.ptp_timer = None;
|
(*data).ptp_timer = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let state = data.state_mut::<E::State>();
|
let state = (*data).state_mut::<E::State>();
|
||||||
let fuzzer = data.fuzzer_mut::<Z>();
|
let fuzzer = (*data).fuzzer_mut::<Z>();
|
||||||
let event_mgr = data.event_mgr_mut::<EM>();
|
let event_mgr = (*data).event_mgr_mut::<EM>();
|
||||||
|
|
||||||
log::error!("Child crashed!");
|
log::error!("Child crashed!");
|
||||||
|
|
||||||
// Make sure we don't crash in the crash handler forever.
|
// 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>(
|
run_observers_and_save_state::<E, EM, OF, Z>(
|
||||||
executor,
|
executor,
|
||||||
@ -106,6 +109,7 @@ pub mod windows_exception_handler {
|
|||||||
ffi::c_void,
|
ffi::c_void,
|
||||||
mem::transmute,
|
mem::transmute,
|
||||||
ptr,
|
ptr,
|
||||||
|
ptr::addr_of_mut,
|
||||||
sync::atomic::{compiler_fence, Ordering},
|
sync::atomic::{compiler_fence, Ordering},
|
||||||
};
|
};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -132,7 +136,7 @@ pub mod windows_exception_handler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) type HandlerFuncPtr =
|
pub(crate) type HandlerFuncPtr =
|
||||||
unsafe fn(*mut EXCEPTION_POINTERS, &mut InProcessExecutorHandlerData);
|
unsafe fn(*mut EXCEPTION_POINTERS, *mut InProcessExecutorHandlerData);
|
||||||
|
|
||||||
/*pub unsafe fn nop_handler(
|
/*pub unsafe fn nop_handler(
|
||||||
_code: ExceptionCode,
|
_code: ExceptionCode,
|
||||||
@ -145,13 +149,13 @@ pub mod windows_exception_handler {
|
|||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
fn handle(&mut self, _code: ExceptionCode, exception_pointers: *mut EXCEPTION_POINTERS) {
|
fn handle(&mut self, _code: ExceptionCode, exception_pointers: *mut EXCEPTION_POINTERS) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data = &mut GLOBAL_STATE;
|
let data = addr_of_mut!(GLOBAL_STATE);
|
||||||
let in_handler = data.set_in_handler(true);
|
let in_handler = (*data).set_in_handler(true);
|
||||||
if !data.crash_handler.is_null() {
|
if !(*data).crash_handler.is_null() {
|
||||||
let func: HandlerFuncPtr = transmute(data.crash_handler);
|
let func: HandlerFuncPtr = transmute((*data).crash_handler);
|
||||||
(func)(exception_pointers, data);
|
(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>,
|
Z: HasObjective<Objective = OF, State = E::State>,
|
||||||
{
|
{
|
||||||
let old_hook = panic::take_hook();
|
let old_hook = panic::take_hook();
|
||||||
panic::set_hook(Box::new(move |panic_info| {
|
panic::set_hook(Box::new(move |panic_info| unsafe {
|
||||||
let data = unsafe { &mut GLOBAL_STATE };
|
let data = addr_of_mut!(GLOBAL_STATE);
|
||||||
let in_handler = data.set_in_handler(true);
|
let in_handler = (*data).set_in_handler(true);
|
||||||
// Have we set a timer_before?
|
// Have we set a timer_before?
|
||||||
unsafe {
|
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
|
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
|
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.
|
Writing 0 to the data.in_target makes the timeout handler makes the timeout handler invalid.
|
||||||
*/
|
*/
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
EnterCriticalSection(data.critical as *mut CRITICAL_SECTION);
|
EnterCriticalSection((*data).critical as *mut CRITICAL_SECTION);
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
data.in_target = 0;
|
(*data).in_target = 0;
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
LeaveCriticalSection(data.critical as *mut CRITICAL_SECTION);
|
LeaveCriticalSection((*data).critical as *mut CRITICAL_SECTION);
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if data.is_valid() {
|
if (*data).is_valid() {
|
||||||
// We are fuzzing!
|
// We are fuzzing!
|
||||||
let executor = data.executor_mut::<E>();
|
let executor = (*data).executor_mut::<E>();
|
||||||
let state = data.state_mut::<E::State>();
|
let state = (*data).state_mut::<E::State>();
|
||||||
let fuzzer = data.fuzzer_mut::<Z>();
|
let fuzzer = (*data).fuzzer_mut::<Z>();
|
||||||
let event_mgr = data.event_mgr_mut::<EM>();
|
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>(
|
run_observers_and_save_state::<E, EM, OF, Z>(
|
||||||
executor,
|
executor,
|
||||||
@ -215,12 +217,10 @@ pub mod windows_exception_handler {
|
|||||||
ExitKind::Crash,
|
ExitKind::Crash,
|
||||||
);
|
);
|
||||||
|
|
||||||
unsafe {
|
|
||||||
ExitProcess(1);
|
ExitProcess(1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
old_hook(panic_info);
|
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,
|
ffi::c_void,
|
||||||
fmt::{self, Debug, Formatter},
|
fmt::{self, Debug, Formatter},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
ptr::{null, write_volatile},
|
ptr::{addr_of_mut, null, write_volatile},
|
||||||
sync::atomic::{compiler_fence, Ordering},
|
sync::atomic::{compiler_fence, Ordering},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
@ -175,17 +175,29 @@ where
|
|||||||
input: &<Self as UsesInput>::Input,
|
input: &<Self as UsesInput>::Input,
|
||||||
) {
|
) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data = &mut GLOBAL_STATE;
|
let data = addr_of_mut!(GLOBAL_STATE);
|
||||||
write_volatile(
|
write_volatile(
|
||||||
&mut data.current_input_ptr,
|
addr_of_mut!((*data).current_input_ptr),
|
||||||
input as *const _ as *const c_void,
|
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.
|
// 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
|
// 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(
|
||||||
write_volatile(&mut data.event_mgr_ptr, mgr as *mut _ as *mut c_void);
|
addr_of_mut!((*data).state_ptr),
|
||||||
write_volatile(&mut data.fuzzer_ptr, fuzzer as *mut _ as *mut c_void);
|
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);
|
compiler_fence(Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -200,9 +212,9 @@ where
|
|||||||
_input: &<Self as UsesInput>::Input,
|
_input: &<Self as UsesInput>::Input,
|
||||||
) {
|
) {
|
||||||
unsafe {
|
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);
|
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
|
// 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
|
/// 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"))]
|
#[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
|
where
|
||||||
E: Executor<EM, Z> + HasObservers,
|
E: Executor<EM, Z> + HasObservers,
|
||||||
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
||||||
@ -568,15 +583,15 @@ where
|
|||||||
E::State: HasExecutions + HasSolutions + HasCorpus,
|
E::State: HasExecutions + HasSolutions + HasCorpus,
|
||||||
Z: HasObjective<Objective = OF, State = E::State>,
|
Z: HasObjective<Objective = OF, State = E::State>,
|
||||||
{
|
{
|
||||||
let data = unsafe { &mut GLOBAL_STATE };
|
let data = addr_of_mut!(GLOBAL_STATE);
|
||||||
let in_handler = data.set_in_handler(true);
|
let in_handler = (*data).set_in_handler(true);
|
||||||
|
|
||||||
if data.is_valid() {
|
if (*data).is_valid() {
|
||||||
let executor = data.executor_mut::<E>();
|
let executor = (*data).executor_mut::<E>();
|
||||||
let state = data.state_mut::<E::State>();
|
let state = (*data).state_mut::<E::State>();
|
||||||
let event_mgr = data.event_mgr_mut::<EM>();
|
let event_mgr = (*data).event_mgr_mut::<EM>();
|
||||||
let fuzzer = data.fuzzer_mut::<Z>();
|
let fuzzer = (*data).fuzzer_mut::<Z>();
|
||||||
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>(
|
run_observers_and_save_state::<E, EM, OF, Z>(
|
||||||
executor,
|
executor,
|
||||||
@ -588,7 +603,7 @@ where
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
data.set_in_handler(in_handler);
|
(*data).set_in_handler(in_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
//! The `GenericInProcessForkExecutor` to do forking before executing the harness in-processly
|
//! The `GenericInProcessForkExecutor` to do forking before executing the harness in-processly
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
use core::ptr::addr_of_mut;
|
|
||||||
use core::{
|
use core::{
|
||||||
ffi::c_void,
|
ffi::c_void,
|
||||||
fmt::{self, Debug, Formatter},
|
fmt::{self, Debug, Formatter},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
ptr::{null_mut, write_volatile},
|
ptr::{addr_of_mut, null_mut, write_volatile},
|
||||||
sync::atomic::{compiler_fence, Ordering},
|
sync::atomic::{compiler_fence, Ordering},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
@ -42,7 +40,7 @@ pub(crate) type ForkHandlerFuncPtr = unsafe fn(
|
|||||||
Signal,
|
Signal,
|
||||||
&mut siginfo_t,
|
&mut siginfo_t,
|
||||||
Option<&mut ucontext_t>,
|
Option<&mut ucontext_t>,
|
||||||
data: &mut InProcessForkExecutorGlobalData,
|
data: *mut InProcessForkExecutorGlobalData,
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(all(unix, not(target_os = "linux")))]
|
#[cfg(all(unix, not(target_os = "linux")))]
|
||||||
@ -277,13 +275,19 @@ where
|
|||||||
input: &<Self as UsesInput>::Input,
|
input: &<Self as UsesInput>::Input,
|
||||||
) {
|
) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data = &mut FORK_EXECUTOR_GLOBAL_DATA;
|
let data = addr_of_mut!(FORK_EXECUTOR_GLOBAL_DATA);
|
||||||
write_volatile(&mut data.executor_ptr, self as *const _ as *const c_void);
|
|
||||||
write_volatile(
|
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,
|
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);
|
compiler_fence(Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -440,6 +444,7 @@ where
|
|||||||
|
|
||||||
pub mod child_signal_handlers {
|
pub mod child_signal_handlers {
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
|
use core::ptr::addr_of_mut;
|
||||||
use std::panic;
|
use std::panic;
|
||||||
|
|
||||||
use libafl_bolts::os::unix_signals::{ucontext_t, Signal};
|
use libafl_bolts::os::unix_signals::{ucontext_t, Signal};
|
||||||
@ -460,21 +465,21 @@ pub mod child_signal_handlers {
|
|||||||
E: HasObservers,
|
E: HasObservers,
|
||||||
{
|
{
|
||||||
let old_hook = panic::take_hook();
|
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);
|
old_hook(panic_info);
|
||||||
let data = unsafe { &mut FORK_EXECUTOR_GLOBAL_DATA };
|
let data = addr_of_mut!(FORK_EXECUTOR_GLOBAL_DATA);
|
||||||
if data.is_valid() {
|
if !data.is_null() && (*data).is_valid() {
|
||||||
let executor = data.executor_mut::<E>();
|
let executor = (*data).executor_mut::<E>();
|
||||||
let observers = executor.observers_mut();
|
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
|
// 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
|
observers
|
||||||
.post_exec_child_all(state, input, &ExitKind::Crash)
|
.post_exec_child_all(state, input, &ExitKind::Crash)
|
||||||
.expect("Failed to run post_exec on observers");
|
.expect("Failed to run post_exec on observers");
|
||||||
|
|
||||||
// std::process::abort();
|
// 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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
|
use core::ptr::addr_of_mut;
|
||||||
|
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
|
ownedref::OwnedMutSlice,
|
||||||
tuples::{tuple_list, tuple_list_type},
|
tuples::{tuple_list, tuple_list_type},
|
||||||
Named,
|
Named,
|
||||||
};
|
};
|
||||||
@ -1396,7 +1399,10 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_observer_serde() {
|
fn test_observer_serde() {
|
||||||
let obv = tuple_list!(TimeObserver::new("time"), unsafe {
|
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();
|
let vec = postcard::to_allocvec(&obv).unwrap();
|
||||||
log::info!("{vec:?}");
|
log::info!("{vec:?}");
|
||||||
|
@ -2267,9 +2267,7 @@ where
|
|||||||
#[cfg(any(all(unix, not(miri)), all(windows, feature = "std")))]
|
#[cfg(any(all(unix, not(miri)), all(windows, feature = "std")))]
|
||||||
fn setup_handlers() {
|
fn setup_handlers() {
|
||||||
#[cfg(all(unix, not(miri)))]
|
#[cfg(all(unix, not(miri)))]
|
||||||
if let Err(e) =
|
if let Err(e) = unsafe { setup_signal_handler(ptr::addr_of_mut!(LLMP_SIGHANDLER_STATE)) } {
|
||||||
unsafe { setup_signal_handler(&mut *ptr::addr_of_mut!(LLMP_SIGHANDLER_STATE)) }
|
|
||||||
{
|
|
||||||
// We can live without a proper ctrl+c signal handler - Ignore.
|
// We can live without a proper ctrl+c signal handler - Ignore.
|
||||||
log::info!("Failed to setup signal handlers: {e}");
|
log::info!("Failed to setup signal handlers: {e}");
|
||||||
} else {
|
} else {
|
||||||
|
@ -101,6 +101,7 @@ pub struct ucontext_t {
|
|||||||
#[cfg(all(target_vendor = "apple", target_arch = "aarch64"))]
|
#[cfg(all(target_vendor = "apple", target_arch = "aarch64"))]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
#[allow(clippy::pub_underscore_fields)]
|
||||||
pub struct arm_exception_state64 {
|
pub struct arm_exception_state64 {
|
||||||
/// Virtual Fault Address
|
/// Virtual Fault Address
|
||||||
pub __far: u64,
|
pub __far: u64,
|
||||||
@ -125,6 +126,7 @@ pub struct arm_exception_state64 {
|
|||||||
#[cfg(all(target_vendor = "apple", target_arch = "aarch64"))]
|
#[cfg(all(target_vendor = "apple", target_arch = "aarch64"))]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
#[allow(clippy::pub_underscore_fields)]
|
||||||
pub struct arm_thread_state64 {
|
pub struct arm_thread_state64 {
|
||||||
/// General purpose registers x0-x28
|
/// General purpose registers x0-x28
|
||||||
pub __x: [u64; 29],
|
pub __x: [u64; 29],
|
||||||
@ -170,6 +172,7 @@ pub struct arm_neon_state64 {
|
|||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
#[allow(clippy::pub_underscore_fields)]
|
||||||
pub struct mcontext64 {
|
pub struct mcontext64 {
|
||||||
/// _STRUCT_ARM_EXCEPTION_STATE64
|
/// _STRUCT_ARM_EXCEPTION_STATE64
|
||||||
pub __es: 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
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// The signal handlers will be called on any signal. They should (tm) be async safe.
|
/// 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.
|
/// A lot can go south in signal handling. Be sure you know what you are doing.
|
||||||
#[cfg(feature = "alloc")]
|
#[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`)
|
// First, set up our own stack to be used during segfault handling. (and specify `SA_ONSTACK` in `sigaction`)
|
||||||
if SIGNAL_STACK_PTR.is_null() {
|
if SIGNAL_STACK_PTR.is_null() {
|
||||||
SIGNAL_STACK_PTR = malloc(SIGNAL_STACK_SIZE);
|
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);
|
sigaddset(addr_of_mut!(sa.sa_mask), SIGALRM);
|
||||||
sa.sa_flags = SA_NODEFER | SA_SIGINFO | SA_ONSTACK;
|
sa.sa_flags = SA_NODEFER | SA_SIGINFO | SA_ONSTACK;
|
||||||
sa.sa_sigaction = handle_signal as usize;
|
sa.sa_sigaction = handle_signal as usize;
|
||||||
let signals = handler.signals();
|
let signals = unsafe { (*handler).signals() };
|
||||||
for sig in signals {
|
for sig in signals {
|
||||||
write_volatile(
|
write_volatile(
|
||||||
&mut SIGNAL_HANDLERS[sig as usize],
|
addr_of_mut!(SIGNAL_HANDLERS[sig as usize]),
|
||||||
Some(HandlerHolder {
|
Some(HandlerHolder {
|
||||||
handler: UnsafeCell::new(handler as *mut dyn Handler),
|
handler: UnsafeCell::new(handler as *mut dyn Handler),
|
||||||
}),
|
}),
|
||||||
|
@ -5,8 +5,7 @@ use alloc::vec::Vec;
|
|||||||
use core::{
|
use core::{
|
||||||
cell::UnsafeCell,
|
cell::UnsafeCell,
|
||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
ptr,
|
ptr::{self, addr_of_mut, write_volatile},
|
||||||
ptr::write_volatile,
|
|
||||||
sync::atomic::{compiler_fence, Ordering},
|
sync::atomic::{compiler_fence, Ordering},
|
||||||
};
|
};
|
||||||
use std::os::raw::{c_long, c_void};
|
use std::os::raw::{c_long, c_void};
|
||||||
@ -384,8 +383,8 @@ unsafe extern "C" fn handle_signal(_signum: i32) {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
/// Exception handlers are usually ugly, handle with care!
|
/// Exception handlers are usually ugly, handle with care!
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
pub unsafe fn setup_exception_handler<T: 'static + Handler>(handler: &mut T) -> Result<(), Error> {
|
pub unsafe fn setup_exception_handler<T: 'static + Handler>(handler: *mut T) -> Result<(), Error> {
|
||||||
let exceptions = handler.exceptions();
|
let exceptions = (*handler).exceptions();
|
||||||
let mut catch_assertions = false;
|
let mut catch_assertions = false;
|
||||||
for exception_code in exceptions {
|
for exception_code in exceptions {
|
||||||
if exception_code == ExceptionCode::AssertionFailure {
|
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)
|
.position(|x| *x == exception_code)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
write_volatile(
|
write_volatile(
|
||||||
&mut EXCEPTION_HANDLERS[index],
|
addr_of_mut!(EXCEPTION_HANDLERS[index]),
|
||||||
Some(HandlerHolder {
|
Some(HandlerHolder {
|
||||||
handler: UnsafeCell::new(handler as *mut dyn Handler),
|
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(
|
write_volatile(
|
||||||
&mut EXCEPTION_HANDLERS[EXCEPTION_HANDLERS_SIZE - 1],
|
addr_of_mut!(EXCEPTION_HANDLERS[EXCEPTION_HANDLERS_SIZE - 1]),
|
||||||
Some(HandlerHolder {
|
Some(HandlerHolder {
|
||||||
handler: UnsafeCell::new(handler as *mut dyn Handler),
|
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,
|
handler: *mut T,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
write_volatile(
|
write_volatile(
|
||||||
&mut CTRL_HANDLER,
|
addr_of_mut!(CTRL_HANDLER),
|
||||||
Some(CtrlHandlerHolder {
|
Some(CtrlHandlerHolder {
|
||||||
handler: UnsafeCell::new(handler as *mut dyn CtrlHandler),
|
handler: UnsafeCell::new(handler as *mut dyn CtrlHandler),
|
||||||
}),
|
}),
|
||||||
|
@ -10,7 +10,12 @@ use core::{
|
|||||||
fmt::{self, Debug, Formatter},
|
fmt::{self, Debug, Formatter},
|
||||||
ptr::addr_of_mut,
|
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 backtrace::Backtrace;
|
||||||
use dynasmrt::{dynasm, DynasmApi, DynasmLabelApi};
|
use dynasmrt::{dynasm, DynasmApi, DynasmLabelApi};
|
||||||
@ -338,7 +343,7 @@ impl AsanRuntime {
|
|||||||
/// Returns the `AsanErrors` from the recent run
|
/// Returns the `AsanErrors` from the recent run
|
||||||
#[allow(clippy::unused_self)]
|
#[allow(clippy::unused_self)]
|
||||||
pub fn errors(&mut self) -> &Option<AsanErrors> {
|
pub fn errors(&mut self) -> &Option<AsanErrors> {
|
||||||
unsafe { &ASAN_ERRORS }
|
unsafe { &*addr_of!(ASAN_ERRORS) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make sure the specified memory is unpoisoned
|
/// Make sure the specified memory is unpoisoned
|
||||||
|
@ -578,9 +578,9 @@ impl Named for AsanErrorsObserver {
|
|||||||
impl AsanErrorsObserver {
|
impl AsanErrorsObserver {
|
||||||
/// Creates a new `AsanErrorsObserver`, pointing to a constant `AsanErrors` field
|
/// Creates a new `AsanErrorsObserver`, pointing to a constant `AsanErrors` field
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(errors: &'static Option<AsanErrors>) -> Self {
|
pub fn new(errors: *const Option<AsanErrors>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
errors: OwnedPtr::Ptr(errors as *const Option<AsanErrors>),
|
errors: OwnedPtr::Ptr(errors),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,7 +346,7 @@ impl Default for FridaOptions {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::sync::OnceLock;
|
use std::{ptr::addr_of, sync::OnceLock};
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use frida_gum::Gum;
|
use frida_gum::Gum;
|
||||||
@ -438,7 +438,7 @@ mod tests {
|
|||||||
let mut fuzzer = StdFuzzer::new(StdScheduler::new(), feedback, objective);
|
let mut fuzzer = StdFuzzer::new(StdScheduler::new(), feedback, objective);
|
||||||
|
|
||||||
let observers = tuple_list!(
|
let observers = tuple_list!(
|
||||||
AsanErrorsObserver::new(&ASAN_ERRORS) //,
|
AsanErrorsObserver::new(addr_of!(ASAN_ERRORS)) //,
|
||||||
);
|
);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -4,7 +4,7 @@ use std::{
|
|||||||
fs::{rename, File},
|
fs::{rename, File},
|
||||||
io::Write,
|
io::Write,
|
||||||
os::fd::{AsRawFd, FromRawFd},
|
os::fd::{AsRawFd, FromRawFd},
|
||||||
time::{SystemTime, UNIX_EPOCH},
|
time::{SystemTime, UNIX_EPOCH}, ptr::addr_of_mut,
|
||||||
};
|
};
|
||||||
|
|
||||||
use libafl::{
|
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 edges_observer = MultiMapObserver::new("edges", edges);
|
||||||
|
|
||||||
let time = TimeObserver::new("time");
|
let time = TimeObserver::new("time");
|
||||||
|
@ -49,12 +49,12 @@ macro_rules! extern_c_checked {
|
|||||||
paste! {
|
paste! {
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[allow(unused)]
|
#[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__>] {}
|
unsafe impl Sync for [<__ $c_var:upper _STRUCT__>] {}
|
||||||
|
|
||||||
#[cfg_attr(nightly, used(linker))]
|
#[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" {
|
extern "C" {
|
||||||
@ -68,12 +68,12 @@ macro_rules! extern_c_checked {
|
|||||||
paste! {
|
paste! {
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[allow(unused)]
|
#[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__>] {}
|
unsafe impl Sync for [<__ $c_var:upper _STRUCT__>] {}
|
||||||
|
|
||||||
#[cfg_attr(nightly, used(linker))]
|
#[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" {
|
extern "C" {
|
||||||
|
@ -5,6 +5,8 @@ use core::{
|
|||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "fork")]
|
||||||
|
use libafl::inputs::UsesInput;
|
||||||
#[cfg(feature = "fork")]
|
#[cfg(feature = "fork")]
|
||||||
use libafl::{
|
use libafl::{
|
||||||
events::EventManager,
|
events::EventManager,
|
||||||
@ -14,13 +16,12 @@ use libafl::{
|
|||||||
use libafl::{
|
use libafl::{
|
||||||
events::{EventFirer, EventRestarter},
|
events::{EventFirer, EventRestarter},
|
||||||
executors::{
|
executors::{
|
||||||
hooks::{inprocess::InProcessExecutorHandlerData, ExecutorHooksTuple},
|
hooks::inprocess::InProcessExecutorHandlerData,
|
||||||
inprocess::{HasInProcessHooks, InProcessExecutor},
|
inprocess::{HasInProcessHooks, InProcessExecutor},
|
||||||
Executor, ExitKind, HasObservers,
|
Executor, ExitKind, HasObservers,
|
||||||
},
|
},
|
||||||
feedbacks::Feedback,
|
feedbacks::Feedback,
|
||||||
fuzzer::HasObjective,
|
fuzzer::HasObjective,
|
||||||
inputs::UsesInput,
|
|
||||||
observers::{ObserversTuple, UsesObservers},
|
observers::{ObserversTuple, UsesObservers},
|
||||||
state::{HasCorpus, HasExecutions, HasSolutions, State, UsesState},
|
state::{HasCorpus, HasExecutions, HasSolutions, State, UsesState},
|
||||||
Error,
|
Error,
|
||||||
@ -147,12 +148,14 @@ where
|
|||||||
|
|
||||||
let handler = |hooks: &mut QemuHooks<QT, S>, host_sig| {
|
let handler = |hooks: &mut QemuHooks<QT, S>, host_sig| {
|
||||||
eprintln!("Crashed with signal {host_sig}");
|
eprintln!("Crashed with signal {host_sig}");
|
||||||
|
unsafe {
|
||||||
libafl::executors::inprocess::generic_inproc_crash_handler::<
|
libafl::executors::inprocess::generic_inproc_crash_handler::<
|
||||||
InProcessExecutor<'a, H, OT, S>,
|
InProcessExecutor<'a, H, OT, S>,
|
||||||
EM,
|
EM,
|
||||||
OF,
|
OF,
|
||||||
Z,
|
Z,
|
||||||
>();
|
>();
|
||||||
|
}
|
||||||
if let Some(cpu) = hooks.emulator().current_cpu() {
|
if let Some(cpu) = hooks.emulator().current_cpu() {
|
||||||
eprint!("Context:\n{}", cpu.display_context());
|
eprint!("Context:\n{}", cpu.display_context());
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use core::{
|
|||||||
fmt::{self, Debug, Formatter},
|
fmt::{self, Debug, Formatter},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
mem::transmute,
|
mem::transmute,
|
||||||
ptr::{self, addr_of},
|
ptr::{self, addr_of, addr_of_mut},
|
||||||
};
|
};
|
||||||
|
|
||||||
use libafl::{executors::hooks::inprocess::inprocess_get_state, inputs::UsesInput};
|
use libafl::{executors::hooks::inprocess::inprocess_get_state, inputs::UsesInput};
|
||||||
@ -317,7 +317,7 @@ where
|
|||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let hooks = get_qemu_hooks::<QT, S>();
|
let hooks = get_qemu_hooks::<QT, S>();
|
||||||
for hook in &mut CRASH_HOOKS {
|
for hook in &mut (*addr_of_mut!(CRASH_HOOKS)) {
|
||||||
match hook {
|
match hook {
|
||||||
HookRepr::Function(ptr) => {
|
HookRepr::Function(ptr) => {
|
||||||
let func: fn(&mut QemuHooks<QT, S>, i32) = transmute(*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 HOOKS_IS_INITIALIZED: bool = false;
|
||||||
static mut FIRST_EXEC: bool = true;
|
|
||||||
|
|
||||||
pub struct QemuHooks<QT, S>
|
pub struct QemuHooks<QT, S>
|
||||||
where
|
where
|
||||||
@ -461,7 +460,7 @@ where
|
|||||||
let fat: FatPtr = transmute(hook);
|
let fat: FatPtr = transmute(hook);
|
||||||
GENERIC_HOOKS.push((HookId(0), fat));
|
GENERIC_HOOKS.push((HookId(0), fat));
|
||||||
let id = self.emulator.set_hook(
|
let id = self.emulator.set_hook(
|
||||||
&mut GENERIC_HOOKS.last_mut().unwrap().1,
|
&mut ((*addr_of_mut!(GENERIC_HOOKS)).last_mut().unwrap().1),
|
||||||
addr,
|
addr,
|
||||||
closure_generic_hook_wrapper::<QT, S>,
|
closure_generic_hook_wrapper::<QT, S>,
|
||||||
invalidate_block,
|
invalidate_block,
|
||||||
@ -662,6 +661,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::similar_names)]
|
||||||
pub fn writes(
|
pub fn writes(
|
||||||
&self,
|
&self,
|
||||||
generation_hook: Hook<
|
generation_hook: Hook<
|
||||||
@ -728,7 +728,6 @@ where
|
|||||||
write_3_exec_hook_wrapper::<QT, S>,
|
write_3_exec_hook_wrapper::<QT, S>,
|
||||||
extern "C" fn(&mut HookState<5>, id: u64, addr: GuestAddr)
|
extern "C" fn(&mut HookState<5>, id: u64, addr: GuestAddr)
|
||||||
);
|
);
|
||||||
#[allow(clippy::similar_names)]
|
|
||||||
let execn = get_raw_hook!(
|
let execn = get_raw_hook!(
|
||||||
execution_hook_n,
|
execution_hook_n,
|
||||||
write_4_exec_hook_wrapper::<QT, S>,
|
write_4_exec_hook_wrapper::<QT, S>,
|
||||||
@ -874,7 +873,7 @@ where
|
|||||||
let fat: FatPtr = transmute(hook);
|
let fat: FatPtr = transmute(hook);
|
||||||
BACKDOOR_HOOKS.push((HookId(0), fat));
|
BACKDOOR_HOOKS.push((HookId(0), fat));
|
||||||
let id = self.emulator.add_backdoor_hook(
|
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>,
|
closure_backdoor_hook_wrapper::<QT, S>,
|
||||||
);
|
);
|
||||||
BACKDOOR_HOOKS.last_mut().unwrap().0 = id;
|
BACKDOOR_HOOKS.last_mut().unwrap().0 = id;
|
||||||
@ -988,7 +987,7 @@ where
|
|||||||
let fat: FatPtr = transmute(hook);
|
let fat: FatPtr = transmute(hook);
|
||||||
PRE_SYSCALL_HOOKS.push((HookId(0), fat));
|
PRE_SYSCALL_HOOKS.push((HookId(0), fat));
|
||||||
let id = self.emulator.add_pre_syscall_hook(
|
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>,
|
closure_pre_syscall_hook_wrapper::<QT, S>,
|
||||||
);
|
);
|
||||||
PRE_SYSCALL_HOOKS.last_mut().unwrap().0 = id;
|
PRE_SYSCALL_HOOKS.last_mut().unwrap().0 = id;
|
||||||
@ -1107,7 +1106,7 @@ where
|
|||||||
let fat: FatPtr = transmute(hook);
|
let fat: FatPtr = transmute(hook);
|
||||||
POST_SYSCALL_HOOKS.push((HookId(0), fat));
|
POST_SYSCALL_HOOKS.push((HookId(0), fat));
|
||||||
let id = self.emulator.add_post_syscall_hook(
|
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>,
|
closure_post_syscall_hook_wrapper::<QT, S>,
|
||||||
);
|
);
|
||||||
POST_SYSCALL_HOOKS.last_mut().unwrap().0 = id;
|
POST_SYSCALL_HOOKS.last_mut().unwrap().0 = id;
|
||||||
@ -1155,7 +1154,7 @@ where
|
|||||||
let fat: FatPtr = transmute(hook);
|
let fat: FatPtr = transmute(hook);
|
||||||
NEW_THREAD_HOOKS.push((HookId(0), fat));
|
NEW_THREAD_HOOKS.push((HookId(0), fat));
|
||||||
let id = self.emulator.add_new_thread_hook(
|
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>,
|
closure_new_thread_hook_wrapper::<QT, S>,
|
||||||
);
|
);
|
||||||
NEW_THREAD_HOOKS.last_mut().unwrap().0 = id;
|
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 = env::var_os("OUT_DIR").unwrap();
|
||||||
let out_dir = out_dir.to_string_lossy().to_string();
|
let out_dir = out_dir.to_string_lossy().to_string();
|
||||||
//let out_dir_path = Path::new(&out_dir);
|
//let out_dir_path = Path::new(&out_dir);
|
||||||
|
#[allow(unused_variables)]
|
||||||
let src_dir = Path::new("src");
|
let src_dir = Path::new("src");
|
||||||
|
|
||||||
let dest_path = Path::new(&out_dir).join("constants.rs");
|
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`.
|
//! [`LLVM` `8-bit-counters`](https://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs-with-guards) runtime for `LibAFL`.
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
use core::ptr::addr_of_mut;
|
||||||
|
|
||||||
use libafl_bolts::{ownedref::OwnedMutSlice, AsMutSlice, AsSlice};
|
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)]
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
pub extern "C" fn __sanitizer_cov_8bit_counters_init(start: *mut u8, stop: *mut u8) {
|
pub extern "C" fn __sanitizer_cov_8bit_counters_init(start: *mut u8, stop: *mut u8) {
|
||||||
unsafe {
|
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()
|
let range = existing.as_mut_slice().as_mut_ptr()
|
||||||
..=existing
|
..=existing
|
||||||
.as_mut_slice()
|
.as_mut_slice()
|
||||||
@ -66,6 +67,7 @@ mod observers {
|
|||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
hash::{BuildHasher, Hasher},
|
hash::{BuildHasher, Hasher},
|
||||||
iter::Flatten,
|
iter::Flatten,
|
||||||
|
ptr::{addr_of, addr_of_mut},
|
||||||
slice::{from_raw_parts, Iter, IterMut},
|
slice::{from_raw_parts, Iter, IterMut},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -165,7 +167,7 @@ mod observers {
|
|||||||
let elem = self.intervals.query(idx..=idx).next().unwrap();
|
let elem = self.intervals.query(idx..=idx).next().unwrap();
|
||||||
let i = elem.value;
|
let i = elem.value;
|
||||||
let j = idx - elem.interval.start;
|
let j = idx - elem.interval.start;
|
||||||
unsafe { &COUNTERS_MAPS[*i].as_slice()[j] }
|
unsafe { &(*addr_of!(COUNTERS_MAPS[*i])).as_slice()[j] }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -173,7 +175,7 @@ mod observers {
|
|||||||
let elem = self.intervals.query_mut(idx..=idx).next().unwrap();
|
let elem = self.intervals.query_mut(idx..=idx).next().unwrap();
|
||||||
let i = elem.value;
|
let i = elem.value;
|
||||||
let j = idx - elem.interval.start;
|
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]
|
#[inline]
|
||||||
@ -184,7 +186,7 @@ mod observers {
|
|||||||
fn count_bytes(&self) -> u64 {
|
fn count_bytes(&self) -> u64 {
|
||||||
let initial = self.initial();
|
let initial = self.initial();
|
||||||
let mut res = 0;
|
let mut res = 0;
|
||||||
for map in unsafe { &COUNTERS_MAPS } {
|
for map in unsafe { &*addr_of!(COUNTERS_MAPS) } {
|
||||||
for x in map.as_slice() {
|
for x in map.as_slice() {
|
||||||
if *x != initial {
|
if *x != initial {
|
||||||
res += 1;
|
res += 1;
|
||||||
@ -196,7 +198,7 @@ mod observers {
|
|||||||
|
|
||||||
fn hash(&self) -> u64 {
|
fn hash(&self) -> u64 {
|
||||||
let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher();
|
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 slice = map.as_slice();
|
||||||
let ptr = slice.as_ptr();
|
let ptr = slice.as_ptr();
|
||||||
let map_size = slice.len() / core::mem::size_of::<u8>();
|
let map_size = slice.len() / core::mem::size_of::<u8>();
|
||||||
@ -209,7 +211,7 @@ mod observers {
|
|||||||
|
|
||||||
fn reset_map(&mut self) -> Result<(), Error> {
|
fn reset_map(&mut self) -> Result<(), Error> {
|
||||||
let initial = self.initial();
|
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() {
|
for x in map.as_mut_slice() {
|
||||||
*x = initial;
|
*x = initial;
|
||||||
}
|
}
|
||||||
@ -250,7 +252,7 @@ mod observers {
|
|||||||
fn maybe_differential(name: &'static str) -> Self {
|
fn maybe_differential(name: &'static str) -> Self {
|
||||||
let mut idx = 0;
|
let mut idx = 0;
|
||||||
let mut intervals = IntervalTree::new();
|
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();
|
let l = x.as_slice().len();
|
||||||
intervals.insert(idx..(idx + l), v);
|
intervals.insert(idx..(idx + l), v);
|
||||||
idx += l;
|
idx += l;
|
||||||
@ -286,7 +288,9 @@ mod observers {
|
|||||||
let mut idx = 0;
|
let mut idx = 0;
|
||||||
let mut v = 0;
|
let mut v = 0;
|
||||||
let mut intervals = IntervalTree::new();
|
let mut intervals = IntervalTree::new();
|
||||||
unsafe { &mut COUNTERS_MAPS }.iter_mut().for_each(|m| {
|
unsafe { &mut *addr_of_mut!(COUNTERS_MAPS) }
|
||||||
|
.iter_mut()
|
||||||
|
.for_each(|m| {
|
||||||
let l = m.as_mut_slice().len();
|
let l = m.as_mut_slice().len();
|
||||||
intervals.insert(idx..(idx + l), v);
|
intervals.insert(idx..(idx + l), v);
|
||||||
idx += l;
|
idx += l;
|
||||||
@ -325,7 +329,7 @@ mod observers {
|
|||||||
type IntoIter = Flatten<Iter<'it, OwnedMutSlice<'static, u8>>>;
|
type IntoIter = Flatten<Iter<'it, OwnedMutSlice<'static, u8>>>;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
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>>>;
|
type IntoIter = Flatten<IterMut<'it, OwnedMutSlice<'static, u8>>>;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
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