From 8459997d9f184b47292a55fb32a319fe2873c086 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sat, 6 Mar 2021 16:32:42 +0100 Subject: [PATCH] volatile for signal handlers --- libafl/src/bolts/llmp.rs | 4 +-- libafl/src/bolts/os/unix_signals.rs | 12 ++++++--- libafl/src/executors/inprocess.rs | 40 +++++++++++++++++++++-------- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/libafl/src/bolts/llmp.rs b/libafl/src/bolts/llmp.rs index 435deb4bab..96cee0bbc6 100644 --- a/libafl/src/bolts/llmp.rs +++ b/libafl/src/bolts/llmp.rs @@ -1347,14 +1347,14 @@ where #[inline] #[cfg(unix)] fn is_shutting_down(&self) -> bool { - unsafe { !ptr::read_volatile(&GLOBAL_SIGHANDLER_STATE.shutting_down) } + unsafe { ptr::read_volatile(&GLOBAL_SIGHANDLER_STATE.shutting_down) } } /// Always returns true on platforms, where no shutdown signal handlers are supported #[inline] #[cfg(not(unix))] fn is_shutting_down(&self) -> bool { - true + false } /// Loops infinitely, forwarding and handling all incoming messages from clients. diff --git a/libafl/src/bolts/os/unix_signals.rs b/libafl/src/bolts/os/unix_signals.rs index 1dd5d0579e..737cf533fa 100644 --- a/libafl/src/bolts/os/unix_signals.rs +++ b/libafl/src/bolts/os/unix_signals.rs @@ -4,6 +4,8 @@ use core::{ convert::TryFrom, fmt::{self, Display, Formatter}, mem, ptr, + ptr::write_volatile, + sync::atomic::{compiler_fence, Ordering}, }; #[cfg(feature = "std")] @@ -151,9 +153,12 @@ pub unsafe fn setup_signal_handler(handler: &mut T) -> Res sa.sa_sigaction = handle_signal as usize; let signals = handler.signals(); for sig in signals { - SIGNAL_HANDLERS[sig as usize] = Some(HandlerHolder { - handler: UnsafeCell::new(handler as *mut dyn Handler), - }); + write_volatile( + &mut SIGNAL_HANDLERS[sig as usize], + Some(HandlerHolder { + handler: UnsafeCell::new(handler as *mut dyn Handler), + }), + ); if sigaction(sig as i32, &mut sa as *mut sigaction, ptr::null_mut()) < 0 { #[cfg(feature = "std")] @@ -164,6 +169,7 @@ pub unsafe fn setup_signal_handler(handler: &mut T) -> Res return Err(Error::Unknown(format!("Could not set up {} handler", sig))); } } + compiler_fence(Ordering::SeqCst); Ok(()) } diff --git a/libafl/src/executors/inprocess.rs b/libafl/src/executors/inprocess.rs index 889c919a8d..a890be9518 100644 --- a/libafl/src/executors/inprocess.rs +++ b/libafl/src/executors/inprocess.rs @@ -3,7 +3,10 @@ use core::marker::PhantomData; #[cfg(unix)] -use core::ptr; +use core::{ + ptr::{self, write_volatile}, + sync::atomic::{compiler_fence, Ordering}, +}; #[cfg(unix)] use crate::bolts::os::unix_signals::{c_void, setup_signal_handler}; @@ -52,11 +55,15 @@ where #[cfg(unix)] unsafe { let data = &mut unix_signal_handler::GLOBAL_STATE; - data.current_input_ptr = _input as *const _ as *const c_void; + write_volatile( + &mut data.current_input_ptr, + _input as *const _ as *const c_void, + ); // 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 - data.state_ptr = _state as *mut _ as *mut c_void; - data.event_mgr_ptr = _event_mgr as *mut _ as *mut c_void; + write_volatile(&mut data.state_ptr, _state as *mut _ as *mut c_void); + write_volatile(&mut data.event_mgr_ptr, _event_mgr as *mut _ as *mut c_void); + compiler_fence(Ordering::SeqCst); } Ok(()) } @@ -67,7 +74,11 @@ where let ret = (self.harness_fn)(self, bytes.as_slice()); #[cfg(unix)] unsafe { - unix_signal_handler::GLOBAL_STATE.current_input_ptr = ptr::null(); + write_volatile( + &mut unix_signal_handler::GLOBAL_STATE.current_input_ptr, + ptr::null(), + ); + compiler_fence(Ordering::SeqCst); } Ok(ret) } @@ -126,13 +137,22 @@ where { #[cfg(unix)] unsafe { - let mut data = &mut unix_signal_handler::GLOBAL_STATE; - data.observers_ptr = &observers as *const _ as *const c_void; - data.crash_handler = unix_signal_handler::inproc_crash_handler::; - data.timeout_handler = - unix_signal_handler::inproc_timeout_handler::; + let data = &mut unix_signal_handler::GLOBAL_STATE; + write_volatile( + &mut data.observers_ptr, + &observers as *const _ as *const c_void, + ); + write_volatile( + &mut data.crash_handler, + unix_signal_handler::inproc_crash_handler::, + ); + write_volatile( + &mut data.timeout_handler, + unix_signal_handler::inproc_timeout_handler::, + ); setup_signal_handler(data)?; + compiler_fence(Ordering::SeqCst); } Ok(Self {