included more clippy suggestions
This commit is contained in:
parent
0c1c284bed
commit
bb54d551ac
@ -86,10 +86,9 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
|
|||||||
.expect("Failed to setup the restarter".into());
|
.expect("Failed to setup the restarter".into());
|
||||||
|
|
||||||
// Create an observation channel using the coverage map
|
// Create an observation channel using the coverage map
|
||||||
let edges_observer =
|
let edges_observer = unsafe {
|
||||||
StdMapObserver::new_from_ptr("edges", unsafe { __lafl_edges_map }, unsafe {
|
StdMapObserver::new_from_ptr("edges", __lafl_edges_map, __lafl_max_edges_size as usize)
|
||||||
__lafl_max_edges_size as usize
|
};
|
||||||
});
|
|
||||||
|
|
||||||
// If not restarting, create a State from scratch
|
// If not restarting, create a State from scratch
|
||||||
let mut state = state.unwrap_or_else(|| {
|
let mut state = state.unwrap_or_else(|| {
|
||||||
|
@ -97,11 +97,9 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Create an observation channel using the coverage map
|
// Create an observation channel using the coverage map
|
||||||
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new_from_ptr(
|
let edges_observer = HitcountsMapObserver::new(unsafe {
|
||||||
"edges",
|
StdMapObserver::new_from_ptr("edges", __lafl_edges_map, __lafl_max_edges_size as usize)
|
||||||
unsafe { __lafl_edges_map },
|
});
|
||||||
unsafe { __lafl_max_edges_size as usize },
|
|
||||||
));
|
|
||||||
|
|
||||||
// If not restarting, create a State from scratch
|
// If not restarting, create a State from scratch
|
||||||
let mut state = state.unwrap_or_else(|| {
|
let mut state = state.unwrap_or_else(|| {
|
||||||
|
@ -976,61 +976,59 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Let's see what we go here.
|
// Let's see what we go here.
|
||||||
match ret {
|
if let Some(msg) = ret {
|
||||||
Some(msg) => {
|
if !(*msg).in_map(&mut self.current_recv_map) {
|
||||||
if !(*msg).in_map(&mut self.current_recv_map) {
|
return Err(Error::IllegalState("Unexpected message in map (out of map bounds) - bugy client or tampered shared map detedted!".into()));
|
||||||
return Err(Error::IllegalState("Unexpected message in map (out of map bounds) - bugy client or tampered shared map detedted!".into()));
|
|
||||||
}
|
|
||||||
// Handle special, LLMP internal, messages.
|
|
||||||
match (*msg).tag {
|
|
||||||
LLMP_TAG_UNSET => panic!("BUG: Read unallocated msg"),
|
|
||||||
LLMP_TAG_END_OF_PAGE => {
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
dbg!("Got end of page, allocing next");
|
|
||||||
// Handle end of page
|
|
||||||
if (*msg).buf_len < size_of::<LlmpPayloadSharedMapInfo>() as u64 {
|
|
||||||
panic!(
|
|
||||||
"Illegal message length for EOP (is {}, expected {})",
|
|
||||||
(*msg).buf_len_padded,
|
|
||||||
size_of::<LlmpPayloadSharedMapInfo>()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let pageinfo = (*msg).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo;
|
|
||||||
|
|
||||||
/* We can reuse the map mem space, no need to free and calloc.
|
|
||||||
However, the pageinfo points to the map we're about to unmap.
|
|
||||||
Clone the contents first to be safe (probably fine in rust eitner way). */
|
|
||||||
let pageinfo_cpy = (*pageinfo).clone();
|
|
||||||
|
|
||||||
// Mark the old page save to unmap, in case we didn't so earlier.
|
|
||||||
ptr::write_volatile(&mut (*page).save_to_unmap, 1);
|
|
||||||
// Map the new page. The old one should be unmapped by Drop
|
|
||||||
self.current_recv_map =
|
|
||||||
LlmpSharedMap::existing(SH::existing_from_shm_slice(
|
|
||||||
&pageinfo_cpy.shm_str,
|
|
||||||
pageinfo_cpy.map_size,
|
|
||||||
)?);
|
|
||||||
// Mark the new page save to unmap also (it's mapped by us, the broker now)
|
|
||||||
ptr::write_volatile(&mut (*page).save_to_unmap, 1);
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
dbg!("Got a new recv map", self.current_recv_map.shmem.shm_str());
|
|
||||||
// After we mapped the new page, return the next message, if available
|
|
||||||
return self.recv();
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the last msg for next time
|
|
||||||
self.last_msg_recvd = msg;
|
|
||||||
}
|
}
|
||||||
_ => (),
|
// Handle special, LLMP internal, messages.
|
||||||
|
match (*msg).tag {
|
||||||
|
LLMP_TAG_UNSET => panic!("BUG: Read unallocated msg"),
|
||||||
|
LLMP_TAG_END_OF_PAGE => {
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
dbg!("Got end of page, allocing next");
|
||||||
|
// Handle end of page
|
||||||
|
if (*msg).buf_len < size_of::<LlmpPayloadSharedMapInfo>() as u64 {
|
||||||
|
panic!(
|
||||||
|
"Illegal message length for EOP (is {}, expected {})",
|
||||||
|
(*msg).buf_len_padded,
|
||||||
|
size_of::<LlmpPayloadSharedMapInfo>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let pageinfo = (*msg).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo;
|
||||||
|
|
||||||
|
/* We can reuse the map mem space, no need to free and calloc.
|
||||||
|
However, the pageinfo points to the map we're about to unmap.
|
||||||
|
Clone the contents first to be safe (probably fine in rust eitner way). */
|
||||||
|
let pageinfo_cpy = (*pageinfo).clone();
|
||||||
|
|
||||||
|
// Mark the old page save to unmap, in case we didn't so earlier.
|
||||||
|
ptr::write_volatile(&mut (*page).save_to_unmap, 1);
|
||||||
|
// Map the new page. The old one should be unmapped by Drop
|
||||||
|
self.current_recv_map = LlmpSharedMap::existing(SH::existing_from_shm_slice(
|
||||||
|
&pageinfo_cpy.shm_str,
|
||||||
|
pageinfo_cpy.map_size,
|
||||||
|
)?);
|
||||||
|
// Mark the new page save to unmap also (it's mapped by us, the broker now)
|
||||||
|
ptr::write_volatile(&mut (*page).save_to_unmap, 1);
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
dbg!("Got a new recv map", self.current_recv_map.shmem.shm_str());
|
||||||
|
// After we mapped the new page, return the next message, if available
|
||||||
|
return self.recv();
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the last msg for next time
|
||||||
|
self.last_msg_recvd = msg;
|
||||||
};
|
};
|
||||||
Ok(ret)
|
Ok(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Blocks/spins until the next message gets posted to the page,
|
/// Blocks/spins until the next message gets posted to the page,
|
||||||
/// then returns that message.
|
/// then returns that message.
|
||||||
|
/// # Safety
|
||||||
|
/// Returns a raw ptr, on the recv map. Should be safe in general
|
||||||
pub unsafe fn recv_blocking(&mut self) -> Result<*mut LlmpMsg, Error> {
|
pub unsafe fn recv_blocking(&mut self) -> Result<*mut LlmpMsg, Error> {
|
||||||
let mut current_msg_id = 0;
|
let mut current_msg_id = 0;
|
||||||
let page = self.current_recv_map.page_mut();
|
let page = self.current_recv_map.page_mut();
|
||||||
@ -1774,6 +1772,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Commits a msg to the client's out map
|
/// Commits a msg to the client's out map
|
||||||
|
/// # Safety
|
||||||
|
/// Needs to be called with a proper msg pointer
|
||||||
pub unsafe fn send(&mut self, msg: *mut LlmpMsg) -> Result<(), Error> {
|
pub unsafe fn send(&mut self, msg: *mut LlmpMsg) -> Result<(), Error> {
|
||||||
self.sender.send(msg)
|
self.sender.send(msg)
|
||||||
}
|
}
|
||||||
@ -1804,6 +1804,8 @@ where
|
|||||||
|
|
||||||
/// A client receives a broadcast message.
|
/// A client receives a broadcast message.
|
||||||
/// Returns null if no message is availiable
|
/// Returns null if no message is availiable
|
||||||
|
/// # Safety
|
||||||
|
/// Should be save, unless the internal state is corrupt. Returns raw ptr.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn recv(&mut self) -> Result<Option<*mut LlmpMsg>, Error> {
|
pub unsafe fn recv(&mut self) -> Result<Option<*mut LlmpMsg>, Error> {
|
||||||
self.receiver.recv()
|
self.receiver.recv()
|
||||||
@ -1811,6 +1813,8 @@ where
|
|||||||
|
|
||||||
/// A client blocks/spins until the next message gets posted to the page,
|
/// A client blocks/spins until the next message gets posted to the page,
|
||||||
/// then returns that message.
|
/// then returns that message.
|
||||||
|
/// # Safety
|
||||||
|
/// Should be save, unless the internal state is corrupt. Returns raw ptr.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn recv_blocking(&mut self) -> Result<*mut LlmpMsg, Error> {
|
pub unsafe fn recv_blocking(&mut self) -> Result<*mut LlmpMsg, Error> {
|
||||||
self.receiver.recv_blocking()
|
self.receiver.recv_blocking()
|
||||||
@ -1857,7 +1861,7 @@ where
|
|||||||
LLMP_PREF_INITIAL_MAP_SIZE,
|
LLMP_PREF_INITIAL_MAP_SIZE,
|
||||||
)?))?;
|
)?))?;
|
||||||
|
|
||||||
stream.write(ret.sender.out_maps.first().unwrap().shmem.shm_slice())?;
|
stream.write_all(ret.sender.out_maps.first().unwrap().shmem.shm_slice())?;
|
||||||
Ok(ret)
|
Ok(ret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,8 +31,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Sized> Ptr<'a, T> {
|
impl<'a, T: Sized> AsRef<T> for Ptr<'a, T> {
|
||||||
pub fn as_ref(&self) -> &T {
|
fn as_ref(&self) -> &T {
|
||||||
match self {
|
match self {
|
||||||
Ptr::Ref(r) => r,
|
Ptr::Ref(r) => r,
|
||||||
Ptr::Owned(v) => v.as_ref(),
|
Ptr::Owned(v) => v.as_ref(),
|
||||||
@ -69,15 +69,17 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Sized> PtrMut<'a, T> {
|
impl<'a, T: Sized> AsRef<T> for PtrMut<'a, T> {
|
||||||
pub fn as_ref(&self) -> &T {
|
fn as_ref(&self) -> &T {
|
||||||
match self {
|
match self {
|
||||||
PtrMut::Ref(r) => r,
|
PtrMut::Ref(r) => r,
|
||||||
PtrMut::Owned(v) => v.as_ref(),
|
PtrMut::Owned(v) => v.as_ref(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_mut(&mut self) -> &T {
|
impl<'a, T: Sized> AsMut<T> for PtrMut<'a, T> {
|
||||||
|
fn as_mut(&mut self) -> &mut T {
|
||||||
match self {
|
match self {
|
||||||
PtrMut::Ref(r) => r,
|
PtrMut::Ref(r) => r,
|
||||||
PtrMut::Owned(v) => v.as_mut(),
|
PtrMut::Owned(v) => v.as_mut(),
|
||||||
@ -195,8 +197,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Sized> Cptr<T> {
|
impl<T: Sized> AsRef<T> for Cptr<T> {
|
||||||
pub fn as_ref(&self) -> &T {
|
fn as_ref(&self) -> &T {
|
||||||
match self {
|
match self {
|
||||||
Cptr::Cptr(p) => unsafe { p.as_ref().unwrap() },
|
Cptr::Cptr(p) => unsafe { p.as_ref().unwrap() },
|
||||||
Cptr::Owned(v) => v.as_ref(),
|
Cptr::Owned(v) => v.as_ref(),
|
||||||
@ -230,15 +232,17 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Sized> CptrMut<T> {
|
impl<T: Sized> AsRef<T> for CptrMut<T> {
|
||||||
pub fn as_ref(&self) -> &T {
|
fn as_ref(&self) -> &T {
|
||||||
match self {
|
match self {
|
||||||
CptrMut::Cptr(p) => unsafe { p.as_ref().unwrap() },
|
CptrMut::Cptr(p) => unsafe { p.as_ref().unwrap() },
|
||||||
CptrMut::Owned(b) => b.as_ref(),
|
CptrMut::Owned(b) => b.as_ref(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_mut(&mut self) -> &mut T {
|
impl<T: Sized> AsMut<T> for CptrMut<T> {
|
||||||
|
fn as_mut(&mut self) -> &mut T {
|
||||||
match self {
|
match self {
|
||||||
CptrMut::Cptr(p) => unsafe { p.as_mut().unwrap() },
|
CptrMut::Cptr(p) => unsafe { p.as_mut().unwrap() },
|
||||||
CptrMut::Owned(b) => b.as_mut(),
|
CptrMut::Owned(b) => b.as_mut(),
|
||||||
|
@ -169,7 +169,7 @@ pub mod unix_shmem {
|
|||||||
|
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
unsafe fn shmctl(__shmid: c_int, __cmd: c_int, _buf: *mut shmid_ds) -> c_int {
|
unsafe fn shmctl(__shmid: c_int, __cmd: c_int, _buf: *mut shmid_ds) -> c_int {
|
||||||
print!("shmctl(__shmid: {})\n", __shmid);
|
println!("shmctl(__shmid: {})", __shmid);
|
||||||
if __cmd == 0 {
|
if __cmd == 0 {
|
||||||
let length = ioctl(__shmid, ASHMEM_GET_SIZE);
|
let length = ioctl(__shmid, ASHMEM_GET_SIZE);
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ pub mod unix_shmem {
|
|||||||
__key,
|
__key,
|
||||||
);
|
);
|
||||||
|
|
||||||
print!("ourkey: {:?}\n", ourkey);
|
println!("ourkey: {:?}", ourkey);
|
||||||
if ioctl(fd, ASHMEM_SET_NAME, &ourkey) != 0 {
|
if ioctl(fd, ASHMEM_SET_NAME, &ourkey) != 0 {
|
||||||
close(fd);
|
close(fd);
|
||||||
return 0;
|
return 0;
|
||||||
@ -210,13 +210,13 @@ pub mod unix_shmem {
|
|||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
print!("shmget returns {}\n", fd);
|
println!("shmget returns {}", fd);
|
||||||
fd
|
fd
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
unsafe fn shmat(__shmid: c_int, __shmaddr: *const c_void, __shmflg: c_int) -> *mut c_void {
|
unsafe fn shmat(__shmid: c_int, __shmaddr: *const c_void, __shmflg: c_int) -> *mut c_void {
|
||||||
print!("shmat(__shmid: {})\n", __shmid);
|
println!("shmat(__shmid: {})", __shmid);
|
||||||
|
|
||||||
let size = ioctl(__shmid, ASHMEM_GET_SIZE);
|
let size = ioctl(__shmid, ASHMEM_GET_SIZE);
|
||||||
if size < 0 {
|
if size < 0 {
|
||||||
|
@ -39,6 +39,11 @@ where
|
|||||||
/// Returns the number of elements
|
/// Returns the number of elements
|
||||||
fn count(&self) -> usize;
|
fn count(&self) -> usize;
|
||||||
|
|
||||||
|
/// Returns true, if no elements are in this corpus yet
|
||||||
|
fn is_empty(&self) -> bool {
|
||||||
|
self.count() == 0
|
||||||
|
}
|
||||||
|
|
||||||
/// Add an entry to the corpus and return its index
|
/// Add an entry to the corpus and return its index
|
||||||
fn add(&mut self, testcase: Testcase<I>) -> Result<usize, Error>;
|
fn add(&mut self, testcase: Testcase<I>) -> Result<usize, Error>;
|
||||||
|
|
||||||
|
@ -127,12 +127,10 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new MapObserver from a raw pointer
|
/// Creates a new MapObserver from a raw pointer
|
||||||
pub fn new_from_ptr(name: &'static str, map_ptr: *mut T, len: usize) -> Self {
|
/// # Safety
|
||||||
let initial = if len > 0 {
|
/// Will dereference the map_ptr with up to len elements.
|
||||||
unsafe { *map_ptr }
|
pub unsafe fn new_from_ptr(name: &'static str, map_ptr: *mut T, len: usize) -> Self {
|
||||||
} else {
|
let initial = if len > 0 { *map_ptr } else { T::default() };
|
||||||
T::default()
|
|
||||||
};
|
|
||||||
StdMapObserver {
|
StdMapObserver {
|
||||||
map: ArrayMut::Cptr((map_ptr, len)),
|
map: ArrayMut::Cptr((map_ptr, len)),
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
@ -215,7 +213,7 @@ where
|
|||||||
{
|
{
|
||||||
/// Creates a new MapObserver
|
/// Creates a new MapObserver
|
||||||
pub fn new(name: &'static str, map: &'static mut [T], size: &usize) -> Self {
|
pub fn new(name: &'static str, map: &'static mut [T], size: &usize) -> Self {
|
||||||
let initial = if map.len() > 0 { map[0] } else { T::default() };
|
let initial = if map.is_empty() { T::default() } else { map[0] };
|
||||||
Self {
|
Self {
|
||||||
map: ArrayMut::Cptr((map.as_mut_ptr(), map.len())),
|
map: ArrayMut::Cptr((map.as_mut_ptr(), map.len())),
|
||||||
size: Cptr::Cptr(size as *const _),
|
size: Cptr::Cptr(size as *const _),
|
||||||
@ -225,17 +223,15 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new MapObserver from a raw pointer
|
/// Creates a new MapObserver from a raw pointer
|
||||||
pub fn new_from_ptr(
|
/// # Safety
|
||||||
|
/// Dereferences map_ptr with up to max_len elements of size_ptr.
|
||||||
|
pub unsafe fn new_from_ptr(
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
map_ptr: *mut T,
|
map_ptr: *mut T,
|
||||||
max_len: usize,
|
max_len: usize,
|
||||||
size_ptr: *const usize,
|
size_ptr: *const usize,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let initial = if max_len > 0 {
|
let initial = if max_len > 0 { *map_ptr } else { T::default() };
|
||||||
unsafe { *map_ptr }
|
|
||||||
} else {
|
|
||||||
T::default()
|
|
||||||
};
|
|
||||||
VariableMapObserver {
|
VariableMapObserver {
|
||||||
map: ArrayMut::Cptr((map_ptr, max_len)),
|
map: ArrayMut::Cptr((map_ptr, max_len)),
|
||||||
size: Cptr::Cptr(size_ptr),
|
size: Cptr::Cptr(size_ptr),
|
||||||
|
@ -4,10 +4,10 @@ use core::{cell::RefCell, debug_assert, fmt::Debug, time};
|
|||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
use xxhash_rust::xxh3::xxh3_64_with_seed;
|
use xxhash_rust::xxh3::xxh3_64_with_seed;
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
use alloc::string::ToString;
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use libc::pid_t;
|
use libc::pid_t;
|
||||||
|
#[cfg(unix)]
|
||||||
|
use std::ffi::CString;
|
||||||
|
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
|
|
||||||
@ -415,15 +415,19 @@ pub enum ForkResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Unix has forks.
|
/// Unix has forks.
|
||||||
|
/// # Safety
|
||||||
|
/// A Normal fork. Runs on in two processes. Should be memory safe in general.
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub unsafe fn fork() -> Result<ForkResult, Error> {
|
pub unsafe fn fork() -> Result<ForkResult, Error> {
|
||||||
let pid = libc::fork();
|
match libc::fork() {
|
||||||
if pid < 0 {
|
pid if pid > 0 => Ok(ForkResult::Parent(ChildHandle { pid })),
|
||||||
Err(Error::Unknown("Fork failed".to_string()))
|
pid if pid < 0 => {
|
||||||
} else if pid == 0 {
|
// Getting errno from rust is hard, we'll just let the libc print to stderr for now.
|
||||||
Ok(ForkResult::Child)
|
// In any case, this should usually not happen.
|
||||||
} else {
|
libc::perror(CString::new("Fork failed").unwrap().as_ptr());
|
||||||
Ok(ForkResult::Parent(ChildHandle { pid }))
|
Err(Error::Unknown(format!("Fork failed ({})", pid)))
|
||||||
|
}
|
||||||
|
_ => Ok(ForkResult::Child),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user