moved std sharedmem to mod

This commit is contained in:
Dominik Maier 2021-01-06 04:43:40 +01:00
parent db5183d43f
commit 8b4896df28
3 changed files with 207 additions and 204 deletions

View File

@ -1,63 +1,16 @@
//! A generic sharememory region to be used by any functions (queues or feedbacks //! A generic sharememory region to be used by any functions (queues or feedbacks
// too.) // too.)
#[cfg(feature = "std")]
pub use shmem::AflShmem;
use alloc::string::{String, ToString}; use alloc::string::{String, ToString};
use core::fmt::Debug; use core::fmt::Debug;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use core::{mem::size_of, slice}; use std::env;
#[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 crate::AflError; 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 /// A Shared map
pub trait ShMem: Sized + Debug { pub trait ShMem: Sized + Debug {
/// Creates a new map with the given size /// Creates a new map with the given size
@ -119,166 +72,219 @@ pub trait ShMem: Sized + Debug {
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[derive(Clone, Debug)] pub mod shmem {
pub struct AflShmem {
pub shm_str: [u8; 20],
pub shm_id: c_int,
pub map: *mut u8,
pub map_size: usize,
}
#[cfg(feature = "std")] use core::{mem::size_of, slice};
impl ShMem for AflShmem { use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_ushort, c_void};
fn existing_from_shm_slice( use std::ffi::CStr;
map_str_bytes: &[u8; 20],
map_size: usize, use crate::AflError;
) -> Result<Self, AflError> {
unsafe { use super::ShMem;
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) 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<Self, AflError> {
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, AflError> {
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, AflError> { /// Deinit sharedmaps on drop
Self::new(map_size) impl Drop for AflShmem {
} fn drop(&mut self) {
unsafe {
fn shm_slice(&self) -> &[u8; 20] { afl_shmem_deinit(self);
&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<Self, AflError> {
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
)))
} }
} }
pub fn new(map_size: usize) -> Result<Self, AflError> { /// Create an uninitialized shmap
let mut ret = afl_shmem_unitialized(); const fn afl_shmem_unitialized() -> AflShmem {
let map = unsafe { afl_shmem_init(&mut ret, map_size) }; AflShmem {
if map != 0 as *mut u8 { shm_str: [0; 20],
Ok(ret) shm_id: -1,
} else { map: 0 as *mut c_uchar,
Err(AflError::Unknown(format!( map_size: 0,
"Could not allocate map of size {}",
map_size
)))
} }
} }
}
#[cfg(feature = "std")] impl AflShmem {
/// Deinitialize this shmem instance pub fn from_str(shm_str: &CStr, map_size: usize) -> Result<Self, AflError> {
unsafe fn afl_shmem_deinit(shm: *mut AflShmem) { let mut ret = afl_shmem_unitialized();
if shm.is_null() || (*shm).map.is_null() { let map = unsafe { afl_shmem_by_str(&mut ret, shm_str, map_size) };
/* Serialized map id */ if map != 0 as *mut u8 {
// Not set or not initialized; Ok(ret)
return; } else {
} Err(AflError::Unknown(format!(
(*shm).shm_str[0 as usize] = '\u{0}' as u8; "Could not allocate map with id {:?} and size {}",
shmctl((*shm).shm_id, 0 as c_int, 0 as *mut shmid_ds); shm_str, map_size
(*shm).map = 0 as *mut c_uchar; )))
} }
}
#[cfg(feature = "std")] pub fn new(map_size: usize) -> Result<Self, AflError> {
/// Functions to create Shared memory region, for observation channels and let mut ret = afl_shmem_unitialized();
/// opening inputs and stuff. let map = unsafe { afl_shmem_init(&mut ret, map_size) };
unsafe fn afl_shmem_init(shm: *mut AflShmem, map_size: usize) -> *mut c_uchar { if map != 0 as *mut u8 {
(*shm).map_size = map_size; Ok(ret)
(*shm).map = 0 as *mut c_uchar; } else {
(*shm).shm_id = shmget( Err(AflError::Unknown(format!(
0 as c_int, "Could not allocate map of size {}",
map_size as c_ulong, map_size
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, /// Deinitialize this shmem instance
size_of::<[c_char; 20]>() as c_ulong, unsafe fn afl_shmem_deinit(shm: *mut AflShmem) {
b"%d\x00" as *const u8 as *const c_char, if shm.is_null() || (*shm).map.is_null() {
(*shm).shm_id, /* Serialized map id */
); // Not set or not initialized;
(*shm).shm_str return;
[(size_of::<[c_char; 20]>() as c_ulong).wrapping_sub(1 as c_int as c_ulong) as usize] = }
'\u{0}' as u8; (*shm).shm_str[0 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); 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::<i32>()
.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 = 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::<i32>()
.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)] #[cfg(test)]

View File

@ -1,4 +1,5 @@
pub mod inmemory; pub mod inmemory;
pub use inmemory::InMemoryExecutor;
#[cfg(feature = "runtime")] #[cfg(feature = "runtime")]
pub mod runtime; pub mod runtime;
@ -113,11 +114,9 @@ where
mod test { mod test {
use core::marker::PhantomData; use core::marker::PhantomData;
use crate::executors::Executor; use super::{Executor, NopExecutor};
use crate::inputs::BytesInput; use crate::inputs::BytesInput;
use super::NopExecutor;
#[test] #[test]
fn nop_executor() { fn nop_executor() {
let empty_input = BytesInput::new(vec![]); let empty_input = BytesInput::new(vec![]);

View File

@ -304,16 +304,14 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::inputs::BytesInput;
use crate::mutators::scheduled::StdScheduledMutator;
use crate::utils::{Rand, XKCDRand};
use crate::{ use crate::{
corpus::{Corpus, InMemoryCorpus, Testcase}, corpus::{Corpus, InMemoryCorpus, Testcase},
inputs::BytesInput,
inputs::HasBytesVec, inputs::HasBytesVec,
mutators::scheduled::{mutation_splice, StdScheduledMutator},
utils::{Rand, XKCDRand},
}; };
use super::mutation_splice;
#[test] #[test]
fn test_mut_splice() { fn test_mut_splice() {
// With the current impl, seed of 1 will result in a split at pos 2. // With the current impl, seed of 1 will result in a split at pos 2.