diff --git a/libafl/src/events/simple.rs b/libafl/src/events/simple.rs index d79de4b277..44d5853968 100644 --- a/libafl/src/events/simple.rs +++ b/libafl/src/events/simple.rs @@ -482,7 +482,7 @@ where return Err(Error::shutting_down()); } - #[cfg(all(unix, feature = "std"))] + #[cfg(all(unix, feature = "std", not(miri)))] if child_status == SIGNAL_RECURSION_EXIT { return Err(Error::illegal_state( "The client is stuck in an unexpected signal handler recursion. It is most likely a fuzzer bug.", diff --git a/libafl_targets/src/coverage.c b/libafl_targets/src/coverage.c index 2ddba3963e..83d073c9fe 100644 --- a/libafl_targets/src/coverage.c +++ b/libafl_targets/src/coverage.c @@ -14,6 +14,12 @@ uint8_t *__afl_area_ptr = __afl_area_ptr_local; extern uint8_t __ddg_area_ptr_local[DDG_MAP_SIZE]; uint8_t *__ddg_area_ptr = __ddg_area_ptr_local; +extern uint8_t __afl_fuzz_ptr_local[EDGES_MAP_ALLOCATED_SIZE]; +uint8_t *__afl_fuzz_ptr = __afl_fuzz_ptr_local; + +extern uint32_t __afl_fuzz_len_local; +uint32_t *__afl_fuzz_len = &__afl_fuzz_len_local; + extern uint32_t __afl_acc_memop_ptr_local[ACCOUNTING_MAP_SIZE]; uint32_t *__afl_acc_memop_ptr = __afl_acc_memop_ptr_local; diff --git a/libafl_targets/src/coverage.rs b/libafl_targets/src/coverage.rs index 2a7e764da9..303c3bc9bd 100644 --- a/libafl_targets/src/coverage.rs +++ b/libafl_targets/src/coverage.rs @@ -1,5 +1,7 @@ //! Coverage maps as static mut array +use core::ffi::c_uint; + #[cfg(any( feature = "sancov_pcguard_edges", feature = "sancov_pcguard_hitcounts", @@ -20,6 +22,19 @@ use crate::{ACCOUNTING_MAP_SIZE, DDG_MAP_SIZE, EDGES_MAP_ALLOCATED_SIZE, EDGES_M pub static mut __afl_area_ptr_local: [u8; EDGES_MAP_ALLOCATED_SIZE] = [0; EDGES_MAP_ALLOCATED_SIZE]; pub use __afl_area_ptr_local as EDGES_MAP; +/// The map for input. +#[unsafe(no_mangle)] +#[allow(non_upper_case_globals)] // expect breaks here for some reason +pub static mut __afl_fuzz_ptr_local: [u8; EDGES_MAP_ALLOCATED_SIZE] = [0; EDGES_MAP_ALLOCATED_SIZE]; +pub use __afl_fuzz_ptr_local as INPUT_MAP; + +/// The length of input mapping +#[unsafe(no_mangle)] +#[allow(non_upper_case_globals)] // expect breaks here for some reason +pub static mut __afl_fuzz_len_local: u32 = 0; +pub use __afl_fuzz_len_local as INPUT_LENGTH; + + /// The map for data dependency #[unsafe(no_mangle)] #[allow(non_upper_case_globals)] // expect breaks here for some reason @@ -39,6 +54,12 @@ pub use __afl_acc_memop_ptr_local as ACCOUNTING_MEMOP_MAP; pub static mut MAX_EDGES_FOUND: usize = 0; unsafe extern "C" { + /// The sharedmemort fuzzing flag + pub static mut __afl_sharedmem_fuzzing: c_uint; + /// The pointer points to the length of AFL++ inputs + pub static mut __afl_fuzz_len: *mut u32; + /// The pointer points to the AFL++ inputs + pub static mut __afl_fuzz_ptr: *mut u8; /// The area pointer points to the edges map. pub static mut __afl_area_ptr: *mut u8; @@ -56,9 +77,12 @@ unsafe extern "C" { #[cfg(any(target_os = "linux", target_vendor = "apple"))] pub static __token_stop: *const u8; } +pub use __afl_sharedmem_fuzzing as SHM_FUZZING; pub use __afl_acc_memop_ptr as ACCOUNTING_MEMOP_MAP_PTR; pub use __afl_area_ptr as EDGES_MAP_PTR; pub use __ddg_area_ptr as DDG_MAP_PTR; +pub use __afl_fuzz_ptr as INPUT_PTR; +pub use __afl_fuzz_len as INPUT_LENGTH_PTR; /// Return Tokens from the compile-time token section #[cfg(any(target_os = "linux", target_vendor = "apple"))] @@ -81,6 +105,7 @@ pub fn autotokens() -> Result { #[allow(non_upper_case_globals)] // expect breaks here for some reason #[unsafe(no_mangle)] pub static mut __afl_map_size: usize = EDGES_MAP_DEFAULT_SIZE; +pub use __afl_map_size as EDGES_MAP_SIZE; #[cfg(any( feature = "sancov_pcguard_edges", diff --git a/libafl_targets/src/forkserver.c b/libafl_targets/src/forkserver.c index f5d16d4bc5..a8ed9ec9af 100644 --- a/libafl_targets/src/forkserver.c +++ b/libafl_targets/src/forkserver.c @@ -27,6 +27,12 @@ #define SHM_ENV_VAR "__AFL_SHM_ID" #define SHM_FUZZ_ENV_VAR "__AFL_SHM_FUZZ_ID" #define DEFAULT_PERMISSION 0600 +#define MAP_SIZE (1U << MAP_SIZE_POW2) +#if MAP_SIZE <= 2097152 + #define MAP_INITIAL_SIZE (2 << 20) // = 2097152 +#else + #define MAP_INITIAL_SIZE MAP_SIZE +#endif /* Reporting errors */ #define FS_OPT_ERROR 0xf800008f @@ -64,14 +70,19 @@ int __afl_sharedmem_fuzzing __attribute__((weak)); +static uint8_t __afl_area_initial[MAP_INITIAL_SIZE]; +static uint8_t *__afl_area_ptr_dummy = __afl_area_initial; +static uint8_t *__afl_area_ptr_backup = __afl_area_initial; + extern uint8_t *__afl_area_ptr; extern size_t __afl_map_size; extern uint8_t *__token_start; extern uint8_t *__token_stop; +extern uint8_t *__afl_fuzz_ptr; +extern uint32_t *__afl_fuzz_len; -uint8_t *__afl_fuzz_ptr; -static uint32_t __afl_fuzz_len_local; -uint32_t *__afl_fuzz_len = &__afl_fuzz_len_local; +static uint8_t __afl_fuzz_ptr_initial[MAP_INITIAL_SIZE]; +static uint32_t __afl_fuzz_len_local = 0; int already_initialized_shm; int already_initialized_forkserver; @@ -109,9 +120,8 @@ static void at_exit(int signal) { /* SHM fuzzing setup. */ -void __afl_map_shm(void) { - if (already_initialized_shm) return; - already_initialized_shm = 1; +uint8_t __afl_map_shm(void){ + if (already_initialized_shm) return 1; char *id_str = getenv(SHM_ENV_VAR); @@ -161,15 +171,15 @@ void __afl_map_shm(void) { our parent doesn't give up on us. */ __afl_area_ptr[0] = 1; + already_initialized_shm = 1; + return 1; } else { - fprintf(stderr, - "Error: variable for edge coverage shared memory is not set\n"); - send_forkserver_error(FS_ERROR_SHM_OPEN); - exit(1); + __afl_area_ptr = __afl_area_initial; + return 0; } } -static void map_input_shared_memory() { +uint8_t __afl_map_input_shm() { char *id_str = getenv(SHM_FUZZ_ENV_VAR); if (id_str) { @@ -206,11 +216,11 @@ static void map_input_shared_memory() { __afl_fuzz_len = (uint32_t *)map; __afl_fuzz_ptr = map + sizeof(uint32_t); - + return 1; } else { - fprintf(stderr, "Error: variable for fuzzing shared memory is not set\n"); - send_forkserver_error(FS_ERROR_SHM_OPEN); - exit(1); + __afl_fuzz_ptr = __afl_fuzz_ptr_initial; + __afl_fuzz_len = &__afl_fuzz_len_local; + return 0; } } @@ -294,7 +304,7 @@ void __afl_start_forkserver(void) { status = version; if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); } - if (__afl_sharedmem_fuzzing) { map_input_shared_memory(); } + if (__afl_sharedmem_fuzzing && !__afl_fuzz_ptr) { __afl_map_input_shm(); } while (1) { int status; diff --git a/libafl_targets/src/forkserver.rs b/libafl_targets/src/forkserver.rs index 79212bddd0..79c861aee8 100644 --- a/libafl_targets/src/forkserver.rs +++ b/libafl_targets/src/forkserver.rs @@ -2,18 +2,44 @@ unsafe extern "C" { /// Map a shared memory region for the edge coverage map. - fn __afl_map_shm(); + fn __afl_map_shm() -> u8; + /// Map the input shared memory + fn __afl_map_input_shm() -> u8; /// Start the forkserver. fn __afl_start_forkserver(); } -/// Map a shared memory region for the edge coverage map. +/// Map a shared memory region for the edge coverage map, also referred as +/// [`crate::coverage::EDGES_MAP_PTR`]. This function will intialize +/// [`crate::coverage::EDGES_MAP_PTR`] to a dummy memory region if +/// AFL is not present and return false. /// /// # Note /// /// The function's logic is written in C and this code is a wrapper. -pub fn map_shared_memory() { - unsafe { __afl_map_shm() } +pub fn map_shared_memory() -> bool { + let ret = unsafe { __afl_map_shm() > 0 }; + if !ret { + log::debug!("Shared memory for edge coverage map is not detected!"); + } + ret +} + +/// Map the input shared memory region, also referred as [`crate::coverage::INPUT_PTR`]. +/// [`start_forkserver`] will call this function automatically if the shared +/// memory feature is enabled. Likewise, [`crate::coverage::INPUT_PTR`] will be +/// initialized to a dummy memory region if AFL is not present. +/// +/// # Note +/// +/// The function's logic is written in C and this code is a wrapper. +pub fn map_input_shared_memory() -> bool { + let ret = unsafe { __afl_map_input_shm() > 0}; + + if !ret { + log::debug!("Shared memory for AFL++ inputs is not detected!"); + } + ret } /// Start the forkserver from this point. Any shared memory must be created before.