Don't write pointers to the crash handlers at every execution (#2935)
* make it safe * aa * forgot to put it back * stateful * comment * lol * aa * aa * aa * win * lol * lol * a * a * i hate rust --------- Co-authored-by: Your Name <you@example.com>
This commit is contained in:
parent
8398f8f99a
commit
c09feeba4e
@ -43,12 +43,6 @@ use crate::{inputs::Input, observers::ObserversTuple, state::HasCurrentTestcase}
|
||||
/// The inmem executor's handlers.
|
||||
#[expect(missing_debug_implementations)]
|
||||
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
|
||||
#[cfg(feature = "std")]
|
||||
pub timer: TimerStruct,
|
||||
@ -196,20 +190,12 @@ impl<I, S> ExecutorHook<I, S> for InProcessHooks<I, S> {
|
||||
fn init(&mut self, _state: &mut S) {}
|
||||
/// Call before running a target.
|
||||
fn pre_exec(&mut self, _state: &mut S, _input: &I) {
|
||||
#[cfg(feature = "std")]
|
||||
unsafe {
|
||||
let data = &raw mut GLOBAL_STATE;
|
||||
(*data).crash_handler = self.crash_handler;
|
||||
(*data).timeout_handler = self.timeout_handler;
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "std", not(all(miri, target_vendor = "apple"))))]
|
||||
self.timer_mut().set_timer();
|
||||
}
|
||||
|
||||
/// Call after running a target.
|
||||
fn post_exec(&mut self, _state: &mut S, _input: &I) {
|
||||
// timeout stuff
|
||||
// # Safety
|
||||
// We're calling this only once per execution, in a single thread.
|
||||
#[cfg(all(feature = "std", not(all(miri, target_vendor = "apple"))))]
|
||||
@ -247,15 +233,19 @@ impl<I, S> InProcessHooks<I, S> {
|
||||
unsafe {
|
||||
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);
|
||||
Ok(Self {
|
||||
#[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),
|
||||
phantom: PhantomData,
|
||||
})
|
||||
@ -288,7 +278,7 @@ impl<I, S> InProcessHooks<I, S> {
|
||||
>();
|
||||
setup_exception_handler(data)?;
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
let crash_handler =
|
||||
(*data).crash_handler =
|
||||
crate::executors::hooks::windows::windows_exception_handler::inproc_crash_handler::<
|
||||
E,
|
||||
EM,
|
||||
@ -306,10 +296,9 @@ impl<I, S> InProcessHooks<I, S> {
|
||||
S,
|
||||
Z,
|
||||
> as *const c_void;
|
||||
(*data).timeout_handler = timeout_handler;
|
||||
let timer = TimerStruct::new(exec_tmout, timeout_handler);
|
||||
ret = Ok(Self {
|
||||
crash_handler,
|
||||
timeout_handler,
|
||||
timer,
|
||||
phantom: PhantomData,
|
||||
});
|
||||
@ -347,10 +336,6 @@ impl<I, S> InProcessHooks<I, S> {
|
||||
#[cfg(not(windows))]
|
||||
pub fn nop() -> Self {
|
||||
Self {
|
||||
#[cfg(feature = "std")]
|
||||
crash_handler: ptr::null(),
|
||||
#[cfg(feature = "std")]
|
||||
timeout_handler: ptr::null(),
|
||||
#[cfg(feature = "std")]
|
||||
timer: TimerStruct::new(Duration::from_millis(5000)),
|
||||
phantom: PhantomData,
|
||||
@ -374,10 +359,10 @@ pub struct InProcessExecutorHandlerData {
|
||||
|
||||
/// The timeout handler
|
||||
#[cfg(feature = "std")]
|
||||
pub(crate) crash_handler: *const c_void,
|
||||
pub crash_handler: *const c_void,
|
||||
/// The timeout handler
|
||||
#[cfg(feature = "std")]
|
||||
pub(crate) timeout_handler: *const c_void,
|
||||
pub timeout_handler: *const c_void,
|
||||
|
||||
#[cfg(all(windows, feature = "std"))]
|
||||
pub(crate) ptp_timer: Option<PTP_TIMER>,
|
||||
@ -501,7 +486,7 @@ impl InProcessExecutorHandlerData {
|
||||
}
|
||||
|
||||
/// Exception handling needs some nasty unsafe.
|
||||
pub(crate) static mut GLOBAL_STATE: InProcessExecutorHandlerData = InProcessExecutorHandlerData {
|
||||
pub static mut GLOBAL_STATE: InProcessExecutorHandlerData = InProcessExecutorHandlerData {
|
||||
// The state ptr for signal handling
|
||||
state_ptr: null_mut(),
|
||||
// The event manager ptr for signal handling
|
||||
|
@ -27,10 +27,6 @@ use crate::{
|
||||
/// The inmem fork executor's hooks.
|
||||
#[derive(Debug)]
|
||||
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)>,
|
||||
}
|
||||
|
||||
@ -39,14 +35,7 @@ impl<I, S> ExecutorHook<I, S> for InChildProcessHooks<I, S> {
|
||||
fn init(&mut self, _state: &mut S) {}
|
||||
|
||||
/// Call before running a target.
|
||||
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 pre_exec(&mut self, _state: &mut S, _input: &I) {}
|
||||
|
||||
fn post_exec(&mut self, _state: &mut S, _input: &I) {}
|
||||
}
|
||||
@ -65,11 +54,11 @@ impl<I, S> InChildProcessHooks<I, S> {
|
||||
#[cfg(not(miri))]
|
||||
setup_signal_handler(data)?;
|
||||
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 {
|
||||
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,
|
||||
})
|
||||
}
|
||||
@ -79,8 +68,6 @@ impl<I, S> InChildProcessHooks<I, S> {
|
||||
#[must_use]
|
||||
pub fn nop() -> Self {
|
||||
Self {
|
||||
crash_handler: null(),
|
||||
timeout_handler: null(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
@ -90,16 +90,19 @@ where
|
||||
input: &I,
|
||||
) -> Result<ExitKind, Error> {
|
||||
*state.executions_mut() += 1;
|
||||
|
||||
unsafe {
|
||||
let executor_ptr = ptr::from_ref(self) as *const c_void;
|
||||
self.inner
|
||||
.enter_target(fuzzer, state, mgr, input, executor_ptr);
|
||||
}
|
||||
|
||||
self.inner.hooks.pre_exec_all(state, input);
|
||||
|
||||
let ret = self.harness_fn.borrow_mut()(input);
|
||||
|
||||
self.inner.hooks.post_exec_all(state, input);
|
||||
|
||||
self.inner.leave_target(fuzzer, state, mgr, input);
|
||||
Ok(ret)
|
||||
}
|
||||
|
@ -86,6 +86,7 @@ where
|
||||
input: &I,
|
||||
) -> Result<ExitKind, Error> {
|
||||
*state.executions_mut() += 1;
|
||||
|
||||
unsafe {
|
||||
let executor_ptr = ptr::from_ref(self) as *const c_void;
|
||||
self.inner
|
||||
@ -96,6 +97,7 @@ where
|
||||
let ret = self.harness_fn.borrow_mut()(&mut self.exposed_executor_state, state, input);
|
||||
|
||||
self.inner.hooks.post_exec_all(state, input);
|
||||
|
||||
self.inner.leave_target(fuzzer, state, mgr, input);
|
||||
Ok(ret)
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ use libafl::state::HasCorpus;
|
||||
use libafl::{
|
||||
events::{EventFirer, EventRestarter},
|
||||
executors::{
|
||||
hooks::inprocess::InProcessExecutorHandlerData,
|
||||
hooks::inprocess::{InProcessExecutorHandlerData, GLOBAL_STATE},
|
||||
inprocess::{stateful::StatefulInProcessExecutor, HasInProcessHooks},
|
||||
inprocess_fork::stateful::StatefulInProcessForkExecutor,
|
||||
Executor, ExitKind, HasObservers,
|
||||
@ -243,18 +243,31 @@ where
|
||||
OF: Feedback<EM, I, OT, S>,
|
||||
Z: HasObjective<Objective = OF> + HasScheduler<I, S> + ExecutionProcessor<EM, I, OT, S>,
|
||||
{
|
||||
let mut inner = StatefulInProcessExecutor::with_timeout(
|
||||
let inner = StatefulInProcessExecutor::with_timeout(
|
||||
harness_fn, emulator, observers, fuzzer, state, event_mgr, timeout,
|
||||
)?;
|
||||
|
||||
let data = &raw mut GLOBAL_STATE;
|
||||
#[cfg(feature = "usermode")]
|
||||
{
|
||||
inner.inprocess_hooks_mut().crash_handler =
|
||||
unsafe {
|
||||
// rewrite the crash handler pointer
|
||||
(*data).crash_handler =
|
||||
inproc_qemu_crash_handler::<Self, EM, ET, I, OF, S, Z> as *const c_void;
|
||||
}
|
||||
|
||||
inner.inprocess_hooks_mut().timeout_handler = inproc_qemu_timeout_handler::<
|
||||
StatefulInProcessExecutor<'a, EM, Emulator<C, CM, ED, ET, I, S, SM>, H, I, OT, S, Z>,
|
||||
unsafe {
|
||||
// rewrite the timeout handler pointer
|
||||
(*data).timeout_handler = inproc_qemu_timeout_handler::<
|
||||
StatefulInProcessExecutor<
|
||||
'a,
|
||||
EM,
|
||||
Emulator<C, CM, ED, ET, I, S, SM>,
|
||||
H,
|
||||
I,
|
||||
OT,
|
||||
S,
|
||||
Z,
|
||||
>,
|
||||
EM,
|
||||
ET,
|
||||
I,
|
||||
@ -262,6 +275,7 @@ where
|
||||
S,
|
||||
Z,
|
||||
> as *const c_void;
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
inner,
|
||||
|
Loading…
x
Reference in New Issue
Block a user