Skip to content

Commit 3141cba

Browse files
authored
Remove unsafe inprocess access functions, document remaining function… (#3306)
* Remove unsafe inprocess access functions, document remaining functions better * more docs
1 parent 8ea8209 commit 3141cba

File tree

6 files changed

+87
-73
lines changed

6 files changed

+87
-73
lines changed

fuzzers/forkserver/forkserver_simple/Cargo.lock

Lines changed: 43 additions & 30 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libafl/src/executors/hooks/inprocess.rs

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -527,8 +527,8 @@ impl InProcessExecutorHandlerData {
527527
}
528528
}
529529

530-
/// Exception handling needs some nasty unsafe.
531-
pub static mut GLOBAL_STATE: InProcessExecutorHandlerData = InProcessExecutorHandlerData {
530+
/// Exception handling needs some nasty globals.
531+
pub(crate) static mut GLOBAL_STATE: InProcessExecutorHandlerData = InProcessExecutorHandlerData {
532532
// The state ptr for signal handling
533533
state_ptr: null_mut(),
534534
// The event manager ptr for signal handling
@@ -560,44 +560,12 @@ pub static mut GLOBAL_STATE: InProcessExecutorHandlerData = InProcessExecutorHan
560560
/// Get the inprocess State
561561
///
562562
/// # Safety
563+
/// This is a *very* dangerous and mainly for internal use (unless you _really_ know what you're doing.
564+
/// The type is not checked and needs to be specified correctly.
563565
/// Only safe if not called twice and if the state is not accessed from another borrow while this one is alive.
564566
#[must_use]
565567
pub unsafe fn inprocess_get_state<'a, S>() -> Option<&'a mut S> {
568+
// # Safety
569+
// As unsafe as it gets, but the function is documented accordingly.
566570
unsafe { (GLOBAL_STATE.state_ptr as *mut S).as_mut() }
567571
}
568-
569-
/// Get the `EventManager`
570-
///
571-
/// # Safety
572-
/// Only safe if not called twice and if the event manager is not accessed from another borrow while this one is alive.
573-
#[must_use]
574-
pub unsafe fn inprocess_get_event_manager<'a, EM>() -> Option<&'a mut EM> {
575-
unsafe { (GLOBAL_STATE.event_mgr_ptr as *mut EM).as_mut() }
576-
}
577-
578-
/// Gets the inprocess [`crate::fuzzer::Fuzzer`]
579-
///
580-
/// # Safety
581-
/// Only safe if not called twice and if the fuzzer is not accessed from another borrow while this one is alive.
582-
#[must_use]
583-
pub unsafe fn inprocess_get_fuzzer<'a, F>() -> Option<&'a mut F> {
584-
unsafe { (GLOBAL_STATE.fuzzer_ptr as *mut F).as_mut() }
585-
}
586-
587-
/// Gets the inprocess [`Executor`]
588-
///
589-
/// # Safety
590-
/// Only safe if not called twice and if the executor is not accessed from another borrow while this one is alive.
591-
#[must_use]
592-
pub unsafe fn inprocess_get_executor<'a, E>() -> Option<&'a mut E> {
593-
unsafe { (GLOBAL_STATE.executor_ptr as *mut E).as_mut() }
594-
}
595-
596-
/// Gets the inprocess input
597-
///
598-
/// # Safety
599-
/// Only safe if not called concurrently and if the input is not used mutably while this reference is alive.
600-
#[must_use]
601-
pub unsafe fn inprocess_get_input<'a, I>() -> Option<&'a I> {
602-
unsafe { (GLOBAL_STATE.current_input_ptr as *const I).as_ref() }
603-
}

libafl/src/executors/hooks/unix.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ pub mod unix_signal_handler {
5151
info: &mut siginfo_t,
5252
context: Option<&mut ucontext_t>,
5353
) {
54+
// # Safety
55+
// This runs in a signal handler, no other threads access these variables/borrows anymore.
5456
unsafe {
5557
let data = &raw mut GLOBAL_STATE;
5658
let (max_depth_reached, signal_depth) = (*data).signal_handler_enter();
@@ -97,6 +99,9 @@ pub mod unix_signal_handler {
9799
I: Input + Clone,
98100
{
99101
let old_hook = panic::take_hook();
102+
// # Safety
103+
// The panic handler should only run when all other execution stopped.
104+
// At this point, accessing the global state should be sound.
100105
panic::set_hook(Box::new(move |panic_info| unsafe {
101106
old_hook(panic_info);
102107
let data = &raw mut GLOBAL_STATE;

libafl/src/executors/inprocess/inner.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ where
8686
input: &I,
8787
executor_ptr: *const c_void,
8888
) {
89+
// # Safety
90+
// This writes pointers to global state. Only unsafe if the state is they are accessed incorrectly.
8991
unsafe {
9092
let data = &raw mut GLOBAL_STATE;
9193
write_volatile(
@@ -114,6 +116,8 @@ where
114116
/// This function marks the boundary between the fuzzer and the target
115117
#[inline]
116118
pub fn leave_target(&mut self, _fuzzer: &mut Z, _state: &mut S, _mgr: &mut EM, _input: &I) {
119+
// # Safety
120+
// We set the global pointer to null, no direct safety concerns arise.
117121
unsafe {
118122
let data = &raw mut GLOBAL_STATE;
119123

libafl_targets/src/cmps/mod.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@ pub const CMPLOG_KIND_RTN: u8 = 1;
4545

4646
// EXTERNS, GLOBALS
4747

48-
#[cfg(any(feature = "cmplog", feature = "sancov_cmplog", feature = "sancov_value_profile"))]
48+
#[cfg(any(
49+
feature = "cmplog",
50+
feature = "sancov_cmplog",
51+
feature = "sancov_value_profile"
52+
))]
4953
// void __libafl_targets_cmplog_instructions(uintptr_t k, uint8_t size, uint64_t arg1, uint64_t arg2)
5054
unsafe extern "C" {
5155
/// Logs an instruction for feedback during fuzzing
@@ -58,7 +62,12 @@ unsafe extern "C" {
5862
pub fn __libafl_targets_cmplog_routines(k: usize, ptr1: *const u8, ptr2: *const u8);
5963

6064
/// Cmplog routines but with len specified.
61-
pub fn __libafl_targets_cmplog_routines_len(k: usize, ptr1: *const u8, ptr2: *const u8, len: usize);
65+
pub fn __libafl_targets_cmplog_routines_len(
66+
k: usize,
67+
ptr1: *const u8,
68+
ptr2: *const u8,
69+
len: usize,
70+
);
6271

6372
/// Pointer to the `CmpLog` map
6473
pub static mut libafl_cmplog_map_ptr: *mut CmpLogMap;
@@ -72,7 +81,12 @@ unsafe extern "C" {
7281
/// Logs an AFL++ style routine for feedback during fuzzing
7382
pub fn __libafl_targets_cmplog_routines_extended(k: usize, ptr1: *const u8, ptr2: *const u8);
7483
/// Extended cmplog routines but with len specified.
75-
pub fn __libafl_targets_cmplog_routines_extended_len(k: usize, ptr1: *const u8, ptr2: *const u8, len: usize);
84+
pub fn __libafl_targets_cmplog_routines_extended_len(
85+
k: usize,
86+
ptr1: *const u8,
87+
ptr2: *const u8,
88+
len: usize,
89+
);
7690
}
7791

7892
#[cfg(feature = "cmplog_extended_instrumentation")]

libafl_targets/src/sancov_cmp.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,12 @@ pub unsafe extern "C" fn __sanitizer_weak_hook_strncmp(
8686
}
8787
actual_len += 1;
8888
}
89-
crate::__libafl_targets_cmplog_routines_len(k, s1 as *const u8, s2 as *const u8, actual_len);
89+
crate::__libafl_targets_cmplog_routines_len(
90+
k,
91+
s1 as *const u8,
92+
s2 as *const u8,
93+
actual_len,
94+
);
9095
}
9196
}
9297
}
@@ -132,7 +137,12 @@ pub unsafe extern "C" fn __sanitizer_weak_hook_strcmp(
132137
}
133138
actual_len += 1;
134139
}
135-
crate::__libafl_targets_cmplog_routines_len(k, s1 as *const u8, s2 as *const u8, actual_len);
140+
crate::__libafl_targets_cmplog_routines_len(
141+
k,
142+
s1 as *const u8,
143+
s2 as *const u8,
144+
actual_len,
145+
);
136146
}
137147
}
138148
}

0 commit comments

Comments
 (0)