Skip to content

Commit c09feeb

Browse files
tokatokaYour Name
andauthored
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>
1 parent 8398f8f commit c09feeb

File tree

5 files changed

+52
-61
lines changed

5 files changed

+52
-61
lines changed

libafl/src/executors/hooks/inprocess.rs

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,6 @@ use crate::{inputs::Input, observers::ObserversTuple, state::HasCurrentTestcase}
4343
/// The inmem executor's handlers.
4444
#[expect(missing_debug_implementations)]
4545
pub struct InProcessHooks<I, S> {
46-
/// On crash C function pointer
47-
#[cfg(feature = "std")]
48-
pub crash_handler: *const c_void,
49-
/// On timeout C function pointer
50-
#[cfg(feature = "std")]
51-
pub timeout_handler: *const c_void,
5246
/// `TImer` struct
5347
#[cfg(feature = "std")]
5448
pub timer: TimerStruct,
@@ -196,20 +190,12 @@ impl<I, S> ExecutorHook<I, S> for InProcessHooks<I, S> {
196190
fn init(&mut self, _state: &mut S) {}
197191
/// Call before running a target.
198192
fn pre_exec(&mut self, _state: &mut S, _input: &I) {
199-
#[cfg(feature = "std")]
200-
unsafe {
201-
let data = &raw mut GLOBAL_STATE;
202-
(*data).crash_handler = self.crash_handler;
203-
(*data).timeout_handler = self.timeout_handler;
204-
}
205-
206193
#[cfg(all(feature = "std", not(all(miri, target_vendor = "apple"))))]
207194
self.timer_mut().set_timer();
208195
}
209196

210197
/// Call after running a target.
211198
fn post_exec(&mut self, _state: &mut S, _input: &I) {
212-
// timeout stuff
213199
// # Safety
214200
// We're calling this only once per execution, in a single thread.
215201
#[cfg(all(feature = "std", not(all(miri, target_vendor = "apple"))))]
@@ -247,15 +233,19 @@ impl<I, S> InProcessHooks<I, S> {
247233
unsafe {
248234
setup_signal_handler(data)?;
249235
}
236+
237+
#[cfg(feature = "std")]
238+
unsafe {
239+
let data = &raw mut GLOBAL_STATE;
240+
(*data).crash_handler =
241+
unix_signal_handler::inproc_crash_handler::<E, EM, I, OF, S, Z> as *const c_void;
242+
(*data).timeout_handler =
243+
unix_signal_handler::inproc_timeout_handler::<E, EM, I, OF, S, Z> as *const _;
244+
}
245+
250246
compiler_fence(Ordering::SeqCst);
251247
Ok(Self {
252248
#[cfg(feature = "std")]
253-
crash_handler: unix_signal_handler::inproc_crash_handler::<E, EM, I, OF, S, Z>
254-
as *const c_void,
255-
#[cfg(feature = "std")]
256-
timeout_handler: unix_signal_handler::inproc_timeout_handler::<E, EM, I, OF, S, Z>
257-
as *const _,
258-
#[cfg(feature = "std")]
259249
timer: TimerStruct::new(exec_tmout),
260250
phantom: PhantomData,
261251
})
@@ -288,7 +278,7 @@ impl<I, S> InProcessHooks<I, S> {
288278
>();
289279
setup_exception_handler(data)?;
290280
compiler_fence(Ordering::SeqCst);
291-
let crash_handler =
281+
(*data).crash_handler =
292282
crate::executors::hooks::windows::windows_exception_handler::inproc_crash_handler::<
293283
E,
294284
EM,
@@ -306,10 +296,9 @@ impl<I, S> InProcessHooks<I, S> {
306296
S,
307297
Z,
308298
> as *const c_void;
299+
(*data).timeout_handler = timeout_handler;
309300
let timer = TimerStruct::new(exec_tmout, timeout_handler);
310301
ret = Ok(Self {
311-
crash_handler,
312-
timeout_handler,
313302
timer,
314303
phantom: PhantomData,
315304
});
@@ -347,10 +336,6 @@ impl<I, S> InProcessHooks<I, S> {
347336
#[cfg(not(windows))]
348337
pub fn nop() -> Self {
349338
Self {
350-
#[cfg(feature = "std")]
351-
crash_handler: ptr::null(),
352-
#[cfg(feature = "std")]
353-
timeout_handler: ptr::null(),
354339
#[cfg(feature = "std")]
355340
timer: TimerStruct::new(Duration::from_millis(5000)),
356341
phantom: PhantomData,
@@ -374,10 +359,10 @@ pub struct InProcessExecutorHandlerData {
374359

375360
/// The timeout handler
376361
#[cfg(feature = "std")]
377-
pub(crate) crash_handler: *const c_void,
362+
pub crash_handler: *const c_void,
378363
/// The timeout handler
379364
#[cfg(feature = "std")]
380-
pub(crate) timeout_handler: *const c_void,
365+
pub timeout_handler: *const c_void,
381366

382367
#[cfg(all(windows, feature = "std"))]
383368
pub(crate) ptp_timer: Option<PTP_TIMER>,
@@ -501,7 +486,7 @@ impl InProcessExecutorHandlerData {
501486
}
502487

503488
/// Exception handling needs some nasty unsafe.
504-
pub(crate) static mut GLOBAL_STATE: InProcessExecutorHandlerData = InProcessExecutorHandlerData {
489+
pub static mut GLOBAL_STATE: InProcessExecutorHandlerData = InProcessExecutorHandlerData {
505490
// The state ptr for signal handling
506491
state_ptr: null_mut(),
507492
// The event manager ptr for signal handling

libafl/src/executors/hooks/inprocess_fork.rs

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ use crate::{
2727
/// The inmem fork executor's hooks.
2828
#[derive(Debug)]
2929
pub struct InChildProcessHooks<I, S> {
30-
/// On crash C function pointer
31-
pub crash_handler: *const c_void,
32-
/// On timeout C function pointer
33-
pub timeout_handler: *const c_void,
3430
phantom: PhantomData<(I, S)>,
3531
}
3632

@@ -39,14 +35,7 @@ impl<I, S> ExecutorHook<I, S> for InChildProcessHooks<I, S> {
3935
fn init(&mut self, _state: &mut S) {}
4036

4137
/// Call before running a target.
42-
fn pre_exec(&mut self, _state: &mut S, _input: &I) {
43-
unsafe {
44-
let data = &raw mut FORK_EXECUTOR_GLOBAL_DATA;
45-
(*data).crash_handler = self.crash_handler;
46-
(*data).timeout_handler = self.timeout_handler;
47-
compiler_fence(Ordering::SeqCst);
48-
}
49-
}
38+
fn pre_exec(&mut self, _state: &mut S, _input: &I) {}
5039

5140
fn post_exec(&mut self, _state: &mut S, _input: &I) {}
5241
}
@@ -65,11 +54,11 @@ impl<I, S> InChildProcessHooks<I, S> {
6554
#[cfg(not(miri))]
6655
setup_signal_handler(data)?;
6756
compiler_fence(Ordering::SeqCst);
57+
(*data).crash_handler =
58+
child_signal_handlers::child_crash_handler::<E, I, S> as *const c_void;
59+
(*data).timeout_handler =
60+
child_signal_handlers::child_timeout_handler::<E, I, S> as *const c_void;
6861
Ok(Self {
69-
crash_handler: child_signal_handlers::child_crash_handler::<E, I, S>
70-
as *const c_void,
71-
timeout_handler: child_signal_handlers::child_timeout_handler::<E, I, S>
72-
as *const c_void,
7362
phantom: PhantomData,
7463
})
7564
}
@@ -79,8 +68,6 @@ impl<I, S> InChildProcessHooks<I, S> {
7968
#[must_use]
8069
pub fn nop() -> Self {
8170
Self {
82-
crash_handler: null(),
83-
timeout_handler: null(),
8471
phantom: PhantomData,
8572
}
8673
}

libafl/src/executors/inprocess/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,16 +90,19 @@ where
9090
input: &I,
9191
) -> Result<ExitKind, Error> {
9292
*state.executions_mut() += 1;
93+
9394
unsafe {
9495
let executor_ptr = ptr::from_ref(self) as *const c_void;
9596
self.inner
9697
.enter_target(fuzzer, state, mgr, input, executor_ptr);
9798
}
99+
98100
self.inner.hooks.pre_exec_all(state, input);
99101

100102
let ret = self.harness_fn.borrow_mut()(input);
101103

102104
self.inner.hooks.post_exec_all(state, input);
105+
103106
self.inner.leave_target(fuzzer, state, mgr, input);
104107
Ok(ret)
105108
}

libafl/src/executors/inprocess/stateful.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ where
8686
input: &I,
8787
) -> Result<ExitKind, Error> {
8888
*state.executions_mut() += 1;
89+
8990
unsafe {
9091
let executor_ptr = ptr::from_ref(self) as *const c_void;
9192
self.inner
@@ -96,6 +97,7 @@ where
9697
let ret = self.harness_fn.borrow_mut()(&mut self.exposed_executor_state, state, input);
9798

9899
self.inner.hooks.post_exec_all(state, input);
100+
99101
self.inner.leave_target(fuzzer, state, mgr, input);
100102
Ok(ret)
101103
}

libafl_qemu/src/executor.rs

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use libafl::state::HasCorpus;
1414
use libafl::{
1515
events::{EventFirer, EventRestarter},
1616
executors::{
17-
hooks::inprocess::InProcessExecutorHandlerData,
17+
hooks::inprocess::{InProcessExecutorHandlerData, GLOBAL_STATE},
1818
inprocess::{stateful::StatefulInProcessExecutor, HasInProcessHooks},
1919
inprocess_fork::stateful::StatefulInProcessForkExecutor,
2020
Executor, ExitKind, HasObservers,
@@ -243,25 +243,39 @@ where
243243
OF: Feedback<EM, I, OT, S>,
244244
Z: HasObjective<Objective = OF> + HasScheduler<I, S> + ExecutionProcessor<EM, I, OT, S>,
245245
{
246-
let mut inner = StatefulInProcessExecutor::with_timeout(
246+
let inner = StatefulInProcessExecutor::with_timeout(
247247
harness_fn, emulator, observers, fuzzer, state, event_mgr, timeout,
248248
)?;
249249

250+
let data = &raw mut GLOBAL_STATE;
250251
#[cfg(feature = "usermode")]
251-
{
252-
inner.inprocess_hooks_mut().crash_handler =
252+
unsafe {
253+
// rewrite the crash handler pointer
254+
(*data).crash_handler =
253255
inproc_qemu_crash_handler::<Self, EM, ET, I, OF, S, Z> as *const c_void;
254256
}
255257

256-
inner.inprocess_hooks_mut().timeout_handler = inproc_qemu_timeout_handler::<
257-
StatefulInProcessExecutor<'a, EM, Emulator<C, CM, ED, ET, I, S, SM>, H, I, OT, S, Z>,
258-
EM,
259-
ET,
260-
I,
261-
OF,
262-
S,
263-
Z,
264-
> as *const c_void;
258+
unsafe {
259+
// rewrite the timeout handler pointer
260+
(*data).timeout_handler = inproc_qemu_timeout_handler::<
261+
StatefulInProcessExecutor<
262+
'a,
263+
EM,
264+
Emulator<C, CM, ED, ET, I, S, SM>,
265+
H,
266+
I,
267+
OT,
268+
S,
269+
Z,
270+
>,
271+
EM,
272+
ET,
273+
I,
274+
OF,
275+
S,
276+
Z,
277+
> as *const c_void;
278+
}
265279

266280
Ok(Self {
267281
inner,

0 commit comments

Comments
 (0)