* revert

* null check

* no std
This commit is contained in:
Dongjia "toka" Zhang 2025-02-28 20:09:01 +01:00 committed by GitHub
parent 86d6fa005e
commit 89342b22c2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 84 additions and 50 deletions

View File

@ -6,7 +6,7 @@ use core::sync::atomic::{Ordering, compiler_fence};
use core::{ use core::{
ffi::c_void, ffi::c_void,
marker::PhantomData, marker::PhantomData,
ptr::{self, null_mut}, ptr::{null, null_mut},
time::Duration, time::Duration,
}; };
@ -43,6 +43,12 @@ use crate::{inputs::Input, observers::ObserversTuple, state::HasCurrentTestcase}
/// The inmem executor's handlers. /// The inmem executor's handlers.
#[expect(missing_debug_implementations)] #[expect(missing_debug_implementations)]
pub struct InProcessHooks<I, S> { pub struct InProcessHooks<I, S> {
/// On crash C function pointer
#[cfg(feature = "std")]
pub crash_handler: *const c_void,
/// On timeout C function pointer
#[cfg(feature = "std")]
pub timeout_handler: *const c_void,
/// `TImer` struct /// `TImer` struct
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub timer: TimerStruct, pub timer: TimerStruct,
@ -190,6 +196,19 @@ impl<I, S> ExecutorHook<I, S> for InProcessHooks<I, S> {
fn init(&mut self, _state: &mut S) {} fn init(&mut self, _state: &mut S) {}
/// Call before running a target. /// Call before running a target.
fn pre_exec(&mut self, _state: &mut S, _input: &I) { fn pre_exec(&mut self, _state: &mut S, _input: &I) {
#[cfg(feature = "std")]
// This is very important!!!!!
// Don't remove these pointer settings.
// Imagine there are two executors, you have to set the correct crash handlers for each of the executor.
unsafe {
let data = &raw mut GLOBAL_STATE;
assert!((*data).crash_handler == null());
// usually timeout handler and crash handler is set together
// so no check for timeout handler is null or not
(*data).crash_handler = self.crash_handler;
(*data).timeout_handler = self.timeout_handler;
}
#[cfg(all(feature = "std", not(all(miri, target_vendor = "apple"))))] #[cfg(all(feature = "std", not(all(miri, target_vendor = "apple"))))]
self.timer_mut().set_timer(); self.timer_mut().set_timer();
} }
@ -200,6 +219,12 @@ impl<I, S> ExecutorHook<I, S> for InProcessHooks<I, S> {
// We're calling this only once per execution, in a single thread. // We're calling this only once per execution, in a single thread.
#[cfg(all(feature = "std", not(all(miri, target_vendor = "apple"))))] #[cfg(all(feature = "std", not(all(miri, target_vendor = "apple"))))]
self.timer_mut().unset_timer(); self.timer_mut().unset_timer();
#[cfg(feature = "std")]
unsafe {
let data = &raw mut GLOBAL_STATE;
(*data).crash_handler = null();
(*data).timeout_handler = null();
}
} }
} }
@ -234,18 +259,15 @@ impl<I, S> InProcessHooks<I, S> {
setup_signal_handler(data)?; setup_signal_handler(data)?;
} }
#[cfg(feature = "std")]
unsafe {
let data = &raw mut GLOBAL_STATE;
(*data).crash_handler =
unix_signal_handler::inproc_crash_handler::<E, EM, I, OF, S, Z> as *const c_void;
(*data).timeout_handler =
unix_signal_handler::inproc_timeout_handler::<E, EM, I, OF, S, Z> as *const _;
}
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
Ok(Self { Ok(Self {
#[cfg(feature = "std")] #[cfg(feature = "std")]
crash_handler: unix_signal_handler::inproc_crash_handler::<E, EM, I, OF, S, Z>
as *const c_void,
#[cfg(feature = "std")]
timeout_handler: unix_signal_handler::inproc_timeout_handler::<E, EM, I, OF, S, Z>
as *const _,
#[cfg(feature = "std")]
timer: TimerStruct::new(exec_tmout), timer: TimerStruct::new(exec_tmout),
phantom: PhantomData, phantom: PhantomData,
}) })
@ -278,7 +300,7 @@ impl<I, S> InProcessHooks<I, S> {
>(); >();
setup_exception_handler(data)?; setup_exception_handler(data)?;
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
(*data).crash_handler = let crash_handler =
crate::executors::hooks::windows::windows_exception_handler::inproc_crash_handler::< crate::executors::hooks::windows::windows_exception_handler::inproc_crash_handler::<
E, E,
EM, EM,
@ -296,9 +318,10 @@ impl<I, S> InProcessHooks<I, S> {
S, S,
Z, Z,
> as *const c_void; > as *const c_void;
(*data).timeout_handler = timeout_handler;
let timer = TimerStruct::new(exec_tmout, timeout_handler); let timer = TimerStruct::new(exec_tmout, timeout_handler);
ret = Ok(Self { ret = Ok(Self {
crash_handler,
timeout_handler,
timer, timer,
phantom: PhantomData, phantom: PhantomData,
}); });
@ -336,6 +359,10 @@ impl<I, S> InProcessHooks<I, S> {
#[cfg(not(windows))] #[cfg(not(windows))]
pub fn nop() -> Self { pub fn nop() -> Self {
Self { Self {
#[cfg(feature = "std")]
crash_handler: null(),
#[cfg(feature = "std")]
timeout_handler: null(),
#[cfg(feature = "std")] #[cfg(feature = "std")]
timer: TimerStruct::new(Duration::from_millis(5000)), timer: TimerStruct::new(Duration::from_millis(5000)),
phantom: PhantomData, phantom: PhantomData,
@ -414,7 +441,7 @@ impl InProcessExecutorHandlerData {
#[cfg(all(feature = "std", any(unix, windows)))] #[cfg(all(feature = "std", any(unix, windows)))]
pub(crate) unsafe fn take_current_input<'a, I>(&mut self) -> &'a I { pub(crate) unsafe fn take_current_input<'a, I>(&mut self) -> &'a I {
let r = unsafe { (self.current_input_ptr as *const I).as_ref().unwrap() }; let r = unsafe { (self.current_input_ptr as *const I).as_ref().unwrap() };
self.current_input_ptr = ptr::null(); self.current_input_ptr = null();
r r
} }
@ -509,19 +536,19 @@ pub static mut GLOBAL_STATE: InProcessExecutorHandlerData = InProcessExecutorHan
// The fuzzer ptr for signal handling // The fuzzer ptr for signal handling
fuzzer_ptr: null_mut(), fuzzer_ptr: null_mut(),
// The executor ptr for signal handling // The executor ptr for signal handling
executor_ptr: ptr::null(), executor_ptr: null(),
// The current input for signal handling // The current input for signal handling
current_input_ptr: ptr::null(), current_input_ptr: null(),
#[cfg(feature = "std")] #[cfg(feature = "std")]
signal_handler_depth: 0, signal_handler_depth: 0,
// The crash handler fn // The crash handler fn
#[cfg(feature = "std")] #[cfg(feature = "std")]
crash_handler: ptr::null(), crash_handler: null(),
// The timeout handler fn // The timeout handler fn
#[cfg(feature = "std")] #[cfg(feature = "std")]
timeout_handler: ptr::null(), timeout_handler: null(),
#[cfg(all(windows, feature = "std"))] #[cfg(all(windows, feature = "std"))]
ptp_timer: None, ptp_timer: None,
#[cfg(all(windows, feature = "std"))] #[cfg(all(windows, feature = "std"))]

View File

@ -26,6 +26,10 @@ use crate::{
/// The inmem fork executor's hooks. /// The inmem fork executor's hooks.
#[derive(Debug)] #[derive(Debug)]
pub struct InChildProcessHooks<I, S> { pub struct InChildProcessHooks<I, S> {
/// On crash C function pointer
pub crash_handler: *const c_void,
/// On timeout C function pointer
pub timeout_handler: *const c_void,
phantom: PhantomData<(I, S)>, phantom: PhantomData<(I, S)>,
} }
@ -34,9 +38,22 @@ impl<I, S> ExecutorHook<I, S> for InChildProcessHooks<I, S> {
fn init(&mut self, _state: &mut S) {} fn init(&mut self, _state: &mut S) {}
/// Call before running a target. /// Call before running a target.
fn pre_exec(&mut self, _state: &mut S, _input: &I) {} fn pre_exec(&mut self, _state: &mut S, _input: &I) {
unsafe {
let data = &raw mut FORK_EXECUTOR_GLOBAL_DATA;
(*data).crash_handler = self.crash_handler;
(*data).timeout_handler = self.timeout_handler;
compiler_fence(Ordering::SeqCst);
}
}
fn post_exec(&mut self, _state: &mut S, _input: &I) {} fn post_exec(&mut self, _state: &mut S, _input: &I) {
unsafe {
let data = &raw mut FORK_EXECUTOR_GLOBAL_DATA;
(*data).crash_handler = null();
(*data).timeout_handler = null();
}
}
} }
impl<I, S> InChildProcessHooks<I, S> { impl<I, S> InChildProcessHooks<I, S> {
@ -53,11 +70,11 @@ impl<I, S> InChildProcessHooks<I, S> {
#[cfg(not(miri))] #[cfg(not(miri))]
setup_signal_handler(data)?; setup_signal_handler(data)?;
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
(*data).crash_handler =
child_signal_handlers::child_crash_handler::<E, I, S> as *const c_void;
(*data).timeout_handler =
child_signal_handlers::child_timeout_handler::<E, I, S> as *const c_void;
Ok(Self { Ok(Self {
crash_handler: child_signal_handlers::child_crash_handler::<E, I, S>
as *const c_void,
timeout_handler: child_signal_handlers::child_timeout_handler::<E, I, S>
as *const c_void,
phantom: PhantomData, phantom: PhantomData,
}) })
} }
@ -67,6 +84,8 @@ impl<I, S> InChildProcessHooks<I, S> {
#[must_use] #[must_use]
pub fn nop() -> Self { pub fn nop() -> Self {
Self { Self {
crash_handler: null(),
timeout_handler: null(),
phantom: PhantomData, phantom: PhantomData,
} }
} }

View File

@ -16,7 +16,7 @@ use libafl::{
events::{EventFirer, EventRestarter}, events::{EventFirer, EventRestarter},
executors::{ executors::{
Executor, ExitKind, HasObservers, Executor, ExitKind, HasObservers,
hooks::inprocess::{GLOBAL_STATE, InProcessExecutorHandlerData}, hooks::inprocess::InProcessExecutorHandlerData,
inprocess::{HasInProcessHooks, stateful::StatefulInProcessExecutor}, inprocess::{HasInProcessHooks, stateful::StatefulInProcessExecutor},
inprocess_fork::stateful::StatefulInProcessForkExecutor, inprocess_fork::stateful::StatefulInProcessForkExecutor,
}, },
@ -251,31 +251,20 @@ where
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF> + HasScheduler<I, S> + ExecutionProcessor<EM, I, OT, S>, Z: HasObjective<Objective = OF> + HasScheduler<I, S> + ExecutionProcessor<EM, I, OT, S>,
{ {
let inner = StatefulInProcessExecutor::with_timeout( let mut inner = StatefulInProcessExecutor::with_timeout(
harness_fn, emulator, observers, fuzzer, state, event_mgr, timeout, harness_fn, emulator, observers, fuzzer, state, event_mgr, timeout,
)?; )?;
let data = &raw mut GLOBAL_STATE;
#[cfg(feature = "usermode")]
unsafe {
// rewrite the crash handler pointer // rewrite the crash handler pointer
(*data).crash_handler = #[cfg(feature = "usermode")]
{
inner.inprocess_hooks_mut().crash_handler =
inproc_qemu_crash_handler::<Self, EM, ET, I, OF, S, Z> as *const c_void; inproc_qemu_crash_handler::<Self, EM, ET, I, OF, S, Z> as *const c_void;
} }
unsafe {
// rewrite the timeout handler pointer // rewrite the timeout handler pointer
(*data).timeout_handler = inproc_qemu_timeout_handler::< inner.inprocess_hooks_mut().timeout_handler = inproc_qemu_timeout_handler::<
StatefulInProcessExecutor< StatefulInProcessExecutor<'a, EM, Emulator<C, CM, ED, ET, I, S, SM>, H, I, OT, S, Z>,
'a,
EM,
Emulator<C, CM, ED, ET, I, S, SM>,
H,
I,
OT,
S,
Z,
>,
EM, EM,
ET, ET,
I, I,
@ -283,7 +272,6 @@ where
S, S,
Z, Z,
> as *const c_void; > as *const c_void;
}
Ok(Self { Ok(Self {
inner, inner,