From 8b4896df289402f265f1ecefd386dc42418728fa Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 6 Jan 2021 04:43:40 +0100 Subject: [PATCH] moved std sharedmem to mod --- afl/src/events/shmem.rs | 398 +++++++++++++++++----------------- afl/src/executors/mod.rs | 5 +- afl/src/mutators/scheduled.rs | 8 +- 3 files changed, 207 insertions(+), 204 deletions(-) diff --git a/afl/src/events/shmem.rs b/afl/src/events/shmem.rs index 4e436b066a..c9024f03b4 100644 --- a/afl/src/events/shmem.rs +++ b/afl/src/events/shmem.rs @@ -1,63 +1,16 @@ //! A generic sharememory region to be used by any functions (queues or feedbacks // too.) +#[cfg(feature = "std")] +pub use shmem::AflShmem; + use alloc::string::{String, ToString}; use core::fmt::Debug; #[cfg(feature = "std")] -use core::{mem::size_of, slice}; -#[cfg(feature = "std")] -use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_ushort, c_void}; -#[cfg(feature = "std")] -use std::{env, ffi::CStr}; +use std::env; use crate::AflError; -extern "C" { - #[cfg(feature = "std")] - fn snprintf(_: *mut c_char, _: c_ulong, _: *const c_char, _: ...) -> c_int; - #[cfg(feature = "std")] - fn strncpy(_: *mut c_char, _: *const c_char, _: c_ulong) -> *mut c_char; - #[cfg(feature = "std")] - fn shmctl(__shmid: c_int, __cmd: c_int, __buf: *mut shmid_ds) -> c_int; - #[cfg(feature = "std")] - fn shmget(__key: c_int, __size: c_ulong, __shmflg: c_int) -> c_int; - #[cfg(feature = "std")] - fn shmat(__shmid: c_int, __shmaddr: *const c_void, __shmflg: c_int) -> *mut c_void; -} - -#[cfg(feature = "std")] -#[derive(Copy, Clone)] -#[repr(C)] -struct ipc_perm { - pub __key: c_int, - pub uid: c_uint, - pub gid: c_uint, - pub cuid: c_uint, - pub cgid: c_uint, - pub mode: c_ushort, - pub __pad1: c_ushort, - pub __seq: c_ushort, - pub __pad2: c_ushort, - pub __glibc_reserved1: c_ulong, - pub __glibc_reserved2: c_ulong, -} - -#[cfg(feature = "std")] -#[derive(Copy, Clone)] -#[repr(C)] -struct shmid_ds { - pub shm_perm: ipc_perm, - pub shm_segsz: c_ulong, - pub shm_atime: c_long, - pub shm_dtime: c_long, - pub shm_ctime: c_long, - pub shm_cpid: c_int, - pub shm_lpid: c_int, - pub shm_nattch: c_ulong, - pub __glibc_reserved4: c_ulong, - pub __glibc_reserved5: c_ulong, -} - /// A Shared map pub trait ShMem: Sized + Debug { /// Creates a new map with the given size @@ -119,166 +72,219 @@ pub trait ShMem: Sized + Debug { } #[cfg(feature = "std")] -#[derive(Clone, Debug)] -pub struct AflShmem { - pub shm_str: [u8; 20], - pub shm_id: c_int, - pub map: *mut u8, - pub map_size: usize, -} +pub mod shmem { -#[cfg(feature = "std")] -impl ShMem for AflShmem { - fn existing_from_shm_slice( - map_str_bytes: &[u8; 20], - map_size: usize, - ) -> Result { - unsafe { - let str_bytes = map_str_bytes as *const [u8; 20] as *const libc::c_char; - Self::from_str(CStr::from_ptr(str_bytes), map_size) + use core::{mem::size_of, slice}; + use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_ushort, c_void}; + use std::ffi::CStr; + + use crate::AflError; + + use super::ShMem; + + extern "C" { + #[cfg(feature = "std")] + fn snprintf(_: *mut c_char, _: c_ulong, _: *const c_char, _: ...) -> c_int; + #[cfg(feature = "std")] + fn strncpy(_: *mut c_char, _: *const c_char, _: c_ulong) -> *mut c_char; + #[cfg(feature = "std")] + fn shmctl(__shmid: c_int, __cmd: c_int, __buf: *mut shmid_ds) -> c_int; + #[cfg(feature = "std")] + fn shmget(__key: c_int, __size: c_ulong, __shmflg: c_int) -> c_int; + #[cfg(feature = "std")] + fn shmat(__shmid: c_int, __shmaddr: *const c_void, __shmflg: c_int) -> *mut c_void; + } + + #[derive(Copy, Clone)] + #[repr(C)] + struct ipc_perm { + pub __key: c_int, + pub uid: c_uint, + pub gid: c_uint, + pub cuid: c_uint, + pub cgid: c_uint, + pub mode: c_ushort, + pub __pad1: c_ushort, + pub __seq: c_ushort, + pub __pad2: c_ushort, + pub __glibc_reserved1: c_ulong, + pub __glibc_reserved2: c_ulong, + } + + #[derive(Copy, Clone)] + #[repr(C)] + struct shmid_ds { + pub shm_perm: ipc_perm, + pub shm_segsz: c_ulong, + pub shm_atime: c_long, + pub shm_dtime: c_long, + pub shm_ctime: c_long, + pub shm_cpid: c_int, + pub shm_lpid: c_int, + pub shm_nattch: c_ulong, + pub __glibc_reserved4: c_ulong, + pub __glibc_reserved5: c_ulong, + } + + /// The default Sharedmap impl for unix using shmctl & shmget + #[derive(Clone, Debug)] + pub struct AflShmem { + pub shm_str: [u8; 20], + pub shm_id: c_int, + pub map: *mut u8, + pub map_size: usize, + } + + impl ShMem for AflShmem { + fn existing_from_shm_slice( + map_str_bytes: &[u8; 20], + map_size: usize, + ) -> Result { + unsafe { + let str_bytes = map_str_bytes as *const [u8; 20] as *const libc::c_char; + Self::from_str(CStr::from_ptr(str_bytes), map_size) + } + } + + fn new_map(map_size: usize) -> Result { + Self::new(map_size) + } + + fn shm_slice(&self) -> &[u8; 20] { + &self.shm_str + } + + fn map(&self) -> &[u8] { + unsafe { slice::from_raw_parts(self.map, self.map_size) } + } + + fn map_mut(&mut self) -> &mut [u8] { + unsafe { slice::from_raw_parts_mut(self.map, self.map_size) } } } - fn new_map(map_size: usize) -> Result { - Self::new(map_size) - } - - fn shm_slice(&self) -> &[u8; 20] { - &self.shm_str - } - - fn map(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.map, self.map_size) } - } - - fn map_mut(&mut self) -> &mut [u8] { - unsafe { slice::from_raw_parts_mut(self.map, self.map_size) } - } -} - -#[cfg(feature = "std")] -/// Deinit sharedmaps on drop -impl Drop for AflShmem { - fn drop(&mut self) { - unsafe { - afl_shmem_deinit(self); - } - } -} - -#[cfg(feature = "std")] -/// Create an uninitialized shmap -const fn afl_shmem_unitialized() -> AflShmem { - AflShmem { - shm_str: [0; 20], - shm_id: -1, - map: 0 as *mut c_uchar, - map_size: 0, - } -} - -#[cfg(feature = "std")] -impl AflShmem { - pub fn from_str(shm_str: &CStr, map_size: usize) -> Result { - let mut ret = afl_shmem_unitialized(); - let map = unsafe { afl_shmem_by_str(&mut ret, shm_str, map_size) }; - if map != 0 as *mut u8 { - Ok(ret) - } else { - Err(AflError::Unknown(format!( - "Could not allocate map with id {:?} and size {}", - shm_str, map_size - ))) + /// Deinit sharedmaps on drop + impl Drop for AflShmem { + fn drop(&mut self) { + unsafe { + afl_shmem_deinit(self); + } } } - pub fn new(map_size: usize) -> Result { - let mut ret = afl_shmem_unitialized(); - let map = unsafe { afl_shmem_init(&mut ret, map_size) }; - if map != 0 as *mut u8 { - Ok(ret) - } else { - Err(AflError::Unknown(format!( - "Could not allocate map of size {}", - map_size - ))) + /// Create an uninitialized shmap + const fn afl_shmem_unitialized() -> AflShmem { + AflShmem { + shm_str: [0; 20], + shm_id: -1, + map: 0 as *mut c_uchar, + map_size: 0, } } -} -#[cfg(feature = "std")] -/// Deinitialize this shmem instance -unsafe fn afl_shmem_deinit(shm: *mut AflShmem) { - if shm.is_null() || (*shm).map.is_null() { - /* Serialized map id */ - // Not set or not initialized; - return; - } - (*shm).shm_str[0 as usize] = '\u{0}' as u8; - shmctl((*shm).shm_id, 0 as c_int, 0 as *mut shmid_ds); - (*shm).map = 0 as *mut c_uchar; -} + impl AflShmem { + pub fn from_str(shm_str: &CStr, map_size: usize) -> Result { + let mut ret = afl_shmem_unitialized(); + let map = unsafe { afl_shmem_by_str(&mut ret, shm_str, map_size) }; + if map != 0 as *mut u8 { + Ok(ret) + } else { + Err(AflError::Unknown(format!( + "Could not allocate map with id {:?} and size {}", + shm_str, map_size + ))) + } + } -#[cfg(feature = "std")] -/// Functions to create Shared memory region, for observation channels and -/// opening inputs and stuff. -unsafe fn afl_shmem_init(shm: *mut AflShmem, map_size: usize) -> *mut c_uchar { - (*shm).map_size = map_size; - (*shm).map = 0 as *mut c_uchar; - (*shm).shm_id = shmget( - 0 as c_int, - map_size as c_ulong, - 0o1000 as c_int | 0o2000 as c_int | 0o600 as c_int, - ); - if (*shm).shm_id < 0 as c_int { - (*shm).shm_str[0] = '\u{0}' as u8; - return 0 as *mut c_uchar; + pub fn new(map_size: usize) -> Result { + let mut ret = afl_shmem_unitialized(); + let map = unsafe { afl_shmem_init(&mut ret, map_size) }; + if map != 0 as *mut u8 { + Ok(ret) + } else { + Err(AflError::Unknown(format!( + "Could not allocate map of size {}", + map_size + ))) + } + } } - snprintf( - (*shm).shm_str.as_mut_ptr() as *mut i8, - size_of::<[c_char; 20]>() as c_ulong, - b"%d\x00" as *const u8 as *const c_char, - (*shm).shm_id, - ); - (*shm).shm_str - [(size_of::<[c_char; 20]>() as c_ulong).wrapping_sub(1 as c_int as c_ulong) as usize] = - '\u{0}' as u8; - (*shm).map = shmat((*shm).shm_id, 0 as *const c_void, 0 as c_int) as *mut c_uchar; - if (*shm).map == -(1 as c_int) as *mut c_void as *mut c_uchar || (*shm).map.is_null() { + + /// Deinitialize this shmem instance + unsafe fn afl_shmem_deinit(shm: *mut AflShmem) { + if shm.is_null() || (*shm).map.is_null() { + /* Serialized map id */ + // Not set or not initialized; + return; + } + (*shm).shm_str[0 as usize] = '\u{0}' as u8; shmctl((*shm).shm_id, 0 as c_int, 0 as *mut shmid_ds); - (*shm).shm_id = -(1 as c_int); - (*shm).shm_str[0 as c_int as usize] = '\u{0}' as u8; - return 0 as *mut c_uchar; - } - return (*shm).map; -} - -#[cfg(feature = "std")] -/// Uses a shmap id string to open a shared map -unsafe fn afl_shmem_by_str(shm: *mut AflShmem, shm_str: &CStr, map_size: usize) -> *mut c_uchar { - if shm.is_null() || shm_str.to_bytes().len() == 0 || map_size == 0 { - return 0 as *mut c_uchar; - } - (*shm).map = 0 as *mut c_uchar; - (*shm).map_size = map_size; - strncpy( - (*shm).shm_str.as_mut_ptr() as *mut c_char, - shm_str.as_ptr() as *const c_char, - (size_of::<[c_char; 20]>() as c_ulong).wrapping_sub(1 as c_int as c_ulong), - ); - (*shm).shm_id = shm_str - .to_str() - .expect(&format!("illegal shm_str {:?}", shm_str)) - .parse::() - .unwrap(); - (*shm).map = shmat((*shm).shm_id, 0 as *const c_void, 0 as c_int) as *mut c_uchar; - if (*shm).map == -(1 as c_int) as *mut c_void as *mut c_uchar { (*shm).map = 0 as *mut c_uchar; - (*shm).map_size = 0; - (*shm).shm_str[0] = '\u{0}' as u8; - return 0 as *mut c_uchar; } - return (*shm).map; + + /// Functions to create Shared memory region, for observation channels and + /// opening inputs and stuff. + unsafe fn afl_shmem_init(shm: *mut AflShmem, map_size: usize) -> *mut c_uchar { + (*shm).map_size = map_size; + (*shm).map = 0 as *mut c_uchar; + (*shm).shm_id = shmget( + 0 as c_int, + map_size as c_ulong, + 0o1000 as c_int | 0o2000 as c_int | 0o600 as c_int, + ); + if (*shm).shm_id < 0 as c_int { + (*shm).shm_str[0] = '\u{0}' as u8; + return 0 as *mut c_uchar; + } + snprintf( + (*shm).shm_str.as_mut_ptr() as *mut i8, + size_of::<[c_char; 20]>() as c_ulong, + b"%d\x00" as *const u8 as *const c_char, + (*shm).shm_id, + ); + (*shm).shm_str + [(size_of::<[c_char; 20]>() as c_ulong).wrapping_sub(1 as c_int as c_ulong) as usize] = + '\u{0}' as u8; + (*shm).map = shmat((*shm).shm_id, 0 as *const c_void, 0 as c_int) as *mut c_uchar; + if (*shm).map == -(1 as c_int) as *mut c_void as *mut c_uchar || (*shm).map.is_null() { + shmctl((*shm).shm_id, 0 as c_int, 0 as *mut shmid_ds); + (*shm).shm_id = -(1 as c_int); + (*shm).shm_str[0 as c_int as usize] = '\u{0}' as u8; + return 0 as *mut c_uchar; + } + return (*shm).map; + } + + /// Uses a shmap id string to open a shared map + unsafe fn afl_shmem_by_str( + shm: *mut AflShmem, + shm_str: &CStr, + map_size: usize, + ) -> *mut c_uchar { + if shm.is_null() || shm_str.to_bytes().len() == 0 || map_size == 0 { + return 0 as *mut c_uchar; + } + (*shm).map = 0 as *mut c_uchar; + (*shm).map_size = map_size; + strncpy( + (*shm).shm_str.as_mut_ptr() as *mut c_char, + shm_str.as_ptr() as *const c_char, + (size_of::<[c_char; 20]>() as c_ulong).wrapping_sub(1 as c_int as c_ulong), + ); + (*shm).shm_id = shm_str + .to_str() + .expect(&format!("illegal shm_str {:?}", shm_str)) + .parse::() + .unwrap(); + (*shm).map = shmat((*shm).shm_id, 0 as *const c_void, 0 as c_int) as *mut c_uchar; + if (*shm).map == -(1 as c_int) as *mut c_void as *mut c_uchar { + (*shm).map = 0 as *mut c_uchar; + (*shm).map_size = 0; + (*shm).shm_str[0] = '\u{0}' as u8; + return 0 as *mut c_uchar; + } + return (*shm).map; + } } #[cfg(test)] diff --git a/afl/src/executors/mod.rs b/afl/src/executors/mod.rs index 8c33e2cbaa..6863f6f9f1 100644 --- a/afl/src/executors/mod.rs +++ b/afl/src/executors/mod.rs @@ -1,4 +1,5 @@ pub mod inmemory; +pub use inmemory::InMemoryExecutor; #[cfg(feature = "runtime")] pub mod runtime; @@ -113,11 +114,9 @@ where mod test { use core::marker::PhantomData; - use crate::executors::Executor; + use super::{Executor, NopExecutor}; use crate::inputs::BytesInput; - use super::NopExecutor; - #[test] fn nop_executor() { let empty_input = BytesInput::new(vec![]); diff --git a/afl/src/mutators/scheduled.rs b/afl/src/mutators/scheduled.rs index 81c797bd95..b77233f716 100644 --- a/afl/src/mutators/scheduled.rs +++ b/afl/src/mutators/scheduled.rs @@ -304,16 +304,14 @@ where #[cfg(test)] mod tests { - use crate::inputs::BytesInput; - use crate::mutators::scheduled::StdScheduledMutator; - use crate::utils::{Rand, XKCDRand}; use crate::{ corpus::{Corpus, InMemoryCorpus, Testcase}, + inputs::BytesInput, inputs::HasBytesVec, + mutators::scheduled::{mutation_splice, StdScheduledMutator}, + utils::{Rand, XKCDRand}, }; - use super::mutation_splice; - #[test] fn test_mut_splice() { // With the current impl, seed of 1 will result in a split at pos 2.