Fork (#20)
* wip forking * fixed build * fixed build * import cleanup * more fork * added windows ci * fmt * no_std fixes * windows * unix build fixed * ignoring tests on windows * fixed windows tests
This commit is contained in:
parent
8238d65cac
commit
eaa3dc786b
8
.github/workflows/build_and_test.yml
vendored
8
.github/workflows/build_and_test.yml
vendored
@ -14,6 +14,14 @@ jobs:
|
|||||||
run: cargo build --verbose
|
run: cargo build --verbose
|
||||||
- name: Test
|
- name: Test
|
||||||
run: cargo test --verbose
|
run: cargo test --verbose
|
||||||
|
windows:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Windows Build
|
||||||
|
run: cargo build --verbose
|
||||||
|
- name: Windows Test
|
||||||
|
run: cargo test --verbose
|
||||||
all-features:
|
all-features:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
// build.rs
|
// build.rs
|
||||||
|
|
||||||
use std::env;
|
use std::{
|
||||||
use std::path::Path;
|
env,
|
||||||
use std::process::Command;
|
path::Path,
|
||||||
|
process::{exit, Command},
|
||||||
|
};
|
||||||
|
|
||||||
const LIBMOZJPEG_URL: &str = "https://github.com/mozilla/mozjpeg/archive/v4.0.3.tar.gz";
|
const LIBMOZJPEG_URL: &str = "https://github.com/mozilla/mozjpeg/archive/v4.0.3.tar.gz";
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
if cfg!(windows) {
|
||||||
|
println!("cargo:warning=Skipping libmozjpeg example on Windows");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||||
let cwd = env::current_dir().unwrap().to_string_lossy().to_string();
|
let cwd = env::current_dir().unwrap().to_string_lossy().to_string();
|
||||||
let out_dir = out_dir.to_string_lossy().to_string();
|
let out_dir = out_dir.to_string_lossy().to_string();
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
use std::{env, path::PathBuf};
|
use std::{env, path::PathBuf};
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
use libafl::{
|
use libafl::{
|
||||||
bolts::{shmem::UnixShMem, tuples::tuple_list},
|
bolts::{shmem::UnixShMem, tuples::tuple_list},
|
||||||
corpus::{Corpus, InMemoryCorpus, OnDiskCorpus, RandCorpusScheduler},
|
corpus::{Corpus, InMemoryCorpus, OnDiskCorpus, RandCorpusScheduler},
|
||||||
@ -22,6 +23,7 @@ use libafl::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// We will interact with a C++ target, so use external c functionality
|
/// We will interact with a C++ target, so use external c functionality
|
||||||
|
#[cfg(unix)]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
/// int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
/// int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
||||||
fn LLVMFuzzerTestOneInput(data: *const u8, size: usize) -> i32;
|
fn LLVMFuzzerTestOneInput(data: *const u8, size: usize) -> i32;
|
||||||
@ -35,6 +37,7 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The wrapped harness function, calling out to the LLVM-style harness
|
/// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
|
#[cfg(unix)]
|
||||||
fn harness<E, I>(_executor: &E, buf: &[u8]) -> ExitKind
|
fn harness<E, I>(_executor: &E, buf: &[u8]) -> ExitKind
|
||||||
where
|
where
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
@ -65,7 +68,14 @@ pub fn main() {
|
|||||||
.expect("An error occurred while fuzzing");
|
.expect("An error occurred while fuzzing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Not supported on windows right now
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn fuzz(_corpus_dirs: Vec<PathBuf>, _objective_dir: PathBuf, _broker_port: u16) -> Result<(), ()> {
|
||||||
|
todo!("Example not supported on Windows");
|
||||||
|
}
|
||||||
|
|
||||||
/// The actual fuzzer
|
/// The actual fuzzer
|
||||||
|
#[cfg(unix)]
|
||||||
fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) -> Result<(), Error> {
|
fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) -> Result<(), Error> {
|
||||||
// 'While the stats are state, they are usually used in the broker - which is likely never restarted
|
// 'While the stats are state, they are usually used in the broker - which is likely never restarted
|
||||||
let stats = SimpleStats::new(|s| println!("{}", s));
|
let stats = SimpleStats::new(|s| println!("{}", s));
|
||||||
|
@ -1,13 +1,20 @@
|
|||||||
// build.rs
|
// build.rs
|
||||||
|
|
||||||
use std::env;
|
use std::{
|
||||||
use std::path::Path;
|
env,
|
||||||
use std::process::Command;
|
path::Path,
|
||||||
|
process::{exit, Command},
|
||||||
|
};
|
||||||
|
|
||||||
const LIBPNG_URL: &str =
|
const LIBPNG_URL: &str =
|
||||||
"https://deac-fra.dl.sourceforge.net/project/libpng/libpng16/1.6.37/libpng-1.6.37.tar.xz";
|
"https://deac-fra.dl.sourceforge.net/project/libpng/libpng16/1.6.37/libpng-1.6.37.tar.xz";
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
if cfg!(windows) {
|
||||||
|
println!("cargo:warning=Skipping libpng example on Windows");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||||
let cwd = env::current_dir().unwrap().to_string_lossy().to_string();
|
let cwd = env::current_dir().unwrap().to_string_lossy().to_string();
|
||||||
let out_dir = out_dir.to_string_lossy().to_string();
|
let out_dir = out_dir.to_string_lossy().to_string();
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
use std::{env, path::PathBuf};
|
use std::{env, path::PathBuf};
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
use libafl::{
|
use libafl::{
|
||||||
bolts::{shmem::UnixShMem, tuples::tuple_list},
|
bolts::{shmem::UnixShMem, tuples::tuple_list},
|
||||||
corpus::{
|
corpus::{
|
||||||
@ -24,6 +25,7 @@ use libafl::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// We will interact with a C++ target, so use external c functionality
|
/// We will interact with a C++ target, so use external c functionality
|
||||||
|
#[cfg(unix)]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
/// int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
/// int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
||||||
fn LLVMFuzzerTestOneInput(data: *const u8, size: usize) -> i32;
|
fn LLVMFuzzerTestOneInput(data: *const u8, size: usize) -> i32;
|
||||||
@ -37,6 +39,7 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The wrapped harness function, calling out to the LLVM-style harness
|
/// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
|
#[cfg(unix)]
|
||||||
fn harness<E, I>(_executor: &E, buf: &[u8]) -> ExitKind
|
fn harness<E, I>(_executor: &E, buf: &[u8]) -> ExitKind
|
||||||
where
|
where
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
@ -67,7 +70,14 @@ pub fn main() {
|
|||||||
.expect("An error occurred while fuzzing");
|
.expect("An error occurred while fuzzing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Not supported on windows right now
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn fuzz(_corpus_dirs: Vec<PathBuf>, _objective_dir: PathBuf, _broker_port: u16) -> Result<(), ()> {
|
||||||
|
todo!("Example not supported on Windows");
|
||||||
|
}
|
||||||
|
|
||||||
/// The actual fuzzer
|
/// The actual fuzzer
|
||||||
|
#[cfg(unix)]
|
||||||
fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) -> Result<(), Error> {
|
fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) -> Result<(), Error> {
|
||||||
// 'While the stats are state, they are usually used in the broker - which is likely never restarted
|
// 'While the stats are state, they are usually used in the broker - which is likely never restarted
|
||||||
let stats = SimpleStats::new(|s| println!("{}", s));
|
let stats = SimpleStats::new(|s| println!("{}", s));
|
||||||
|
@ -3,17 +3,21 @@ This shows how llmp can be used directly, without libafl abstractions
|
|||||||
*/
|
*/
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
#[cfg(all(unix, feature = "std"))]
|
||||||
use core::{convert::TryInto, time::Duration};
|
use core::{convert::TryInto, time::Duration};
|
||||||
|
#[cfg(all(unix, feature = "std"))]
|
||||||
use std::{thread, time};
|
use std::{thread, time};
|
||||||
|
|
||||||
|
#[cfg(all(unix, feature = "std"))]
|
||||||
use libafl::{
|
use libafl::{
|
||||||
bolts::{llmp, shmem::UnixShMem},
|
bolts::{llmp, shmem::UnixShMem},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
const TAG_SIMPLE_U32_V1: u32 = 0x51300321;
|
const _TAG_SIMPLE_U32_V1: u32 = 0x51300321;
|
||||||
const TAG_MATH_RESULT_V1: u32 = 0x77474331;
|
const _TAG_MATH_RESULT_V1: u32 = 0x77474331;
|
||||||
|
|
||||||
|
#[cfg(all(unix, feature = "std"))]
|
||||||
fn adder_loop(port: u16) -> ! {
|
fn adder_loop(port: u16) -> ! {
|
||||||
let mut client = llmp::LlmpClient::<UnixShMem>::create_attach_to_tcp(port).unwrap();
|
let mut client = llmp::LlmpClient::<UnixShMem>::create_attach_to_tcp(port).unwrap();
|
||||||
let mut last_result: u32 = 0;
|
let mut last_result: u32 = 0;
|
||||||
@ -27,7 +31,7 @@ fn adder_loop(port: u16) -> ! {
|
|||||||
};
|
};
|
||||||
msg_counter += 1;
|
msg_counter += 1;
|
||||||
match tag {
|
match tag {
|
||||||
TAG_SIMPLE_U32_V1 => {
|
_TAG_SIMPLE_U32_V1 => {
|
||||||
current_result =
|
current_result =
|
||||||
current_result.wrapping_add(u32::from_le_bytes(buf.try_into().unwrap()));
|
current_result.wrapping_add(u32::from_le_bytes(buf.try_into().unwrap()));
|
||||||
}
|
}
|
||||||
@ -42,7 +46,7 @@ fn adder_loop(port: u16) -> ! {
|
|||||||
);
|
);
|
||||||
|
|
||||||
client
|
client
|
||||||
.send_buf(TAG_MATH_RESULT_V1, ¤t_result.to_le_bytes())
|
.send_buf(_TAG_MATH_RESULT_V1, ¤t_result.to_le_bytes())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
last_result = current_result;
|
last_result = current_result;
|
||||||
}
|
}
|
||||||
@ -51,13 +55,14 @@ fn adder_loop(port: u16) -> ! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(unix, feature = "std"))]
|
||||||
fn broker_message_hook(
|
fn broker_message_hook(
|
||||||
client_id: u32,
|
client_id: u32,
|
||||||
tag: llmp::Tag,
|
tag: llmp::Tag,
|
||||||
message: &[u8],
|
message: &[u8],
|
||||||
) -> Result<llmp::LlmpMsgHookResult, Error> {
|
) -> Result<llmp::LlmpMsgHookResult, Error> {
|
||||||
match tag {
|
match tag {
|
||||||
TAG_SIMPLE_U32_V1 => {
|
_TAG_SIMPLE_U32_V1 => {
|
||||||
println!(
|
println!(
|
||||||
"Client {:?} sent message: {:?}",
|
"Client {:?} sent message: {:?}",
|
||||||
client_id,
|
client_id,
|
||||||
@ -65,7 +70,7 @@ fn broker_message_hook(
|
|||||||
);
|
);
|
||||||
Ok(llmp::LlmpMsgHookResult::ForwardToClients)
|
Ok(llmp::LlmpMsgHookResult::ForwardToClients)
|
||||||
}
|
}
|
||||||
TAG_MATH_RESULT_V1 => {
|
_TAG_MATH_RESULT_V1 => {
|
||||||
println!(
|
println!(
|
||||||
"Adder Client has this current result: {:?}",
|
"Adder Client has this current result: {:?}",
|
||||||
u32::from_le_bytes(message.try_into().unwrap())
|
u32::from_le_bytes(message.try_into().unwrap())
|
||||||
@ -79,6 +84,12 @@ fn broker_message_hook(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(unix))]
|
||||||
|
fn main() {
|
||||||
|
todo!("LLMP is not yet supported on this platform.");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
fn main() {
|
fn main() {
|
||||||
/* The main node has a broker, and a few worker threads */
|
/* The main node has a broker, and a few worker threads */
|
||||||
|
|
||||||
@ -108,7 +119,7 @@ fn main() {
|
|||||||
loop {
|
loop {
|
||||||
counter = counter.wrapping_add(1);
|
counter = counter.wrapping_add(1);
|
||||||
client
|
client
|
||||||
.send_buf(TAG_SIMPLE_U32_V1, &counter.to_le_bytes())
|
.send_buf(_TAG_SIMPLE_U32_V1, &counter.to_le_bytes())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
println!("CTR Client writing {}", counter);
|
println!("CTR Client writing {}", counter);
|
||||||
thread::sleep(Duration::from_secs(1))
|
thread::sleep(Duration::from_secs(1))
|
||||||
|
@ -74,7 +74,6 @@ use std::{
|
|||||||
#[cfg(all(feature = "std", unix))]
|
#[cfg(all(feature = "std", unix))]
|
||||||
use nix::{
|
use nix::{
|
||||||
cmsg_space,
|
cmsg_space,
|
||||||
mem::zeroed,
|
|
||||||
sys::{
|
sys::{
|
||||||
socket::{recvmsg, sendmsg, ControlMessage, ControlMessageOwned, MsgFlags},
|
socket::{recvmsg, sendmsg, ControlMessage, ControlMessageOwned, MsgFlags},
|
||||||
uio::IoVec,
|
uio::IoVec,
|
||||||
@ -83,7 +82,9 @@ use nix::{
|
|||||||
#[cfg(all(feature = "std", unix))]
|
#[cfg(all(feature = "std", unix))]
|
||||||
use std::{
|
use std::{
|
||||||
ffi::CStr,
|
ffi::CStr,
|
||||||
|
mem::zeroed,
|
||||||
os::unix::{
|
os::unix::{
|
||||||
|
self,
|
||||||
net::{UnixListener, UnixStream},
|
net::{UnixListener, UnixStream},
|
||||||
{io::AsRawFd, prelude::RawFd},
|
{io::AsRawFd, prelude::RawFd},
|
||||||
},
|
},
|
||||||
@ -1330,6 +1331,7 @@ where
|
|||||||
|
|
||||||
/// Called from an interrupt: Sets broker `shutting_down` flag to `true`.
|
/// Called from an interrupt: Sets broker `shutting_down` flag to `true`.
|
||||||
/// Currently only supported on `std` unix systems.
|
/// Currently only supported on `std` unix systems.
|
||||||
|
#[cfg(all(feature = "std", unix))]
|
||||||
fn shutdown(&mut self) {
|
fn shutdown(&mut self) {
|
||||||
unsafe { ptr::write_volatile(&mut self.shutting_down, true) };
|
unsafe { ptr::write_volatile(&mut self.shutting_down, true) };
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
@ -1928,22 +1930,20 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
#[cfg(all(unix, feature = "std"))]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
use std::{thread::sleep, time::Duration};
|
use std::{thread::sleep, time::Duration};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
use super::{
|
use super::{
|
||||||
LlmpClient,
|
LlmpClient,
|
||||||
LlmpConnection::{self, IsBroker, IsClient},
|
LlmpConnection::{self, IsBroker, IsClient},
|
||||||
LlmpMsgHookResult::ForwardToClients,
|
LlmpMsgHookResult::ForwardToClients,
|
||||||
Tag,
|
Tag,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "std")]
|
|
||||||
use crate::bolts::shmem::UnixShMem;
|
use crate::bolts::shmem::UnixShMem;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn llmp_connection() {
|
pub fn llmp_connection() {
|
||||||
let mut broker = match LlmpConnection::<UnixShMem>::on_port(1337).unwrap() {
|
let mut broker = match LlmpConnection::<UnixShMem>::on_port(1337).unwrap() {
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
//! 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")]
|
#[cfg(all(feature = "std", unix))]
|
||||||
#[cfg(unix)]
|
|
||||||
pub use unix_shmem::UnixShMem;
|
pub use unix_shmem::UnixShMem;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(all(windows, feature = "std"))]
|
||||||
#[cfg(windows)]
|
|
||||||
pub use shmem::Win32ShMem;
|
pub use shmem::Win32ShMem;
|
||||||
|
|
||||||
use alloc::string::{String, ToString};
|
use alloc::string::{String, ToString};
|
||||||
@ -465,10 +463,10 @@ pub mod shmem {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(all(unix, feature = "std"))]
|
||||||
use super::{ShMem, UnixShMem};
|
use super::{ShMem, UnixShMem};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(all(unix, feature = "std"))]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_str_conversions() {
|
fn test_str_conversions() {
|
||||||
let mut shm_str: [u8; 20] = [0; 20];
|
let mut shm_str: [u8; 20] = [0; 20];
|
||||||
|
@ -6,11 +6,13 @@ use serde::{de::DeserializeOwned, Serialize};
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use crate::bolts::llmp::LlmpReceiver;
|
use crate::bolts::llmp::LlmpReceiver;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(all(feature = "std", windows))]
|
||||||
use std::{env, process::Command};
|
use crate::utils::startable_self;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(all(feature = "std", unix))]
|
||||||
#[cfg(unix)]
|
use crate::utils::{fork, ForkResult};
|
||||||
|
|
||||||
|
#[cfg(all(feature = "std", unix))]
|
||||||
use crate::bolts::shmem::UnixShMem;
|
use crate::bolts::shmem::UnixShMem;
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::{
|
bolts::{
|
||||||
@ -513,7 +515,7 @@ where
|
|||||||
let mut mgr;
|
let mut mgr;
|
||||||
|
|
||||||
// We start ourself as child process to actually fuzz
|
// We start ourself as child process to actually fuzz
|
||||||
if std::env::var(_ENV_FUZZER_SENDER).is_err() {
|
let (sender, mut receiver) = if std::env::var(_ENV_FUZZER_SENDER).is_err() {
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
{
|
{
|
||||||
let path = std::env::current_dir()?;
|
let path = std::env::current_dir()?;
|
||||||
@ -549,22 +551,32 @@ where
|
|||||||
// Client->parent loop
|
// Client->parent loop
|
||||||
loop {
|
loop {
|
||||||
dbg!("Spawning next client (id {})", ctr);
|
dbg!("Spawning next client (id {})", ctr);
|
||||||
Command::new(env::current_exe()?)
|
|
||||||
.current_dir(env::current_dir()?)
|
// On Unix, we fork (todo: measure if that is actually faster.)
|
||||||
.args(env::args())
|
#[cfg(unix)]
|
||||||
.status()?;
|
let _ = match unsafe { fork() }? {
|
||||||
|
ForkResult::Parent(handle) => handle.status(),
|
||||||
|
ForkResult::Child => break (sender, receiver),
|
||||||
|
};
|
||||||
|
|
||||||
|
// On windows, we spawn ourself again
|
||||||
|
#[cfg(windows)]
|
||||||
|
startable_self()?.status()?;
|
||||||
|
|
||||||
ctr += 1;
|
ctr += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
// We are the newly started fuzzing instance, first, connect to our own restore map.
|
||||||
|
// A sender and a receiver for single communication
|
||||||
|
(
|
||||||
|
LlmpSender::<SH>::on_existing_from_env(_ENV_FUZZER_SENDER)?,
|
||||||
|
LlmpReceiver::<SH>::on_existing_from_env(_ENV_FUZZER_RECEIVER)?,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
println!("We're a client, let's fuzz :)");
|
println!("We're a client, let's fuzz :)");
|
||||||
|
|
||||||
// We are the fuzzing instance, first, connect to our own restore map.
|
|
||||||
// A sender and a receiver for single communication
|
|
||||||
let mut receiver = LlmpReceiver::<SH>::on_existing_from_env(_ENV_FUZZER_RECEIVER)?;
|
|
||||||
let sender = LlmpSender::<SH>::on_existing_from_env(_ENV_FUZZER_SENDER)?;
|
|
||||||
|
|
||||||
// If we're restarting, deserialize the old state.
|
// If we're restarting, deserialize the old state.
|
||||||
let (state, mut mgr) = match receiver.recv_buf()? {
|
let (state, mut mgr) = match receiver.recv_buf()? {
|
||||||
None => {
|
None => {
|
||||||
|
@ -4,8 +4,19 @@ 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)]
|
||||||
|
use libc::pid_t;
|
||||||
|
|
||||||
|
use crate::Error;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::{
|
||||||
|
env,
|
||||||
|
process::Command,
|
||||||
|
time::{SystemTime, UNIX_EPOCH},
|
||||||
|
};
|
||||||
|
|
||||||
pub trait AsSlice<T> {
|
pub trait AsSlice<T> {
|
||||||
/// Convert to a slice
|
/// Convert to a slice
|
||||||
@ -378,6 +389,53 @@ impl XKCDRand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Child Process Handle
|
||||||
|
#[cfg(unix)]
|
||||||
|
pub struct ChildHandle {
|
||||||
|
pid: pid_t,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
impl ChildHandle {
|
||||||
|
/// Block until the child exited and the status code becomes available
|
||||||
|
pub fn status(&self) -> i32 {
|
||||||
|
let mut status = -1;
|
||||||
|
unsafe {
|
||||||
|
libc::waitpid(self.pid, &mut status, 0);
|
||||||
|
}
|
||||||
|
status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
/// The ForkResult
|
||||||
|
pub enum ForkResult {
|
||||||
|
Parent(ChildHandle),
|
||||||
|
Child,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Unix has forks.
|
||||||
|
#[cfg(unix)]
|
||||||
|
pub unsafe fn fork() -> Result<ForkResult, Error> {
|
||||||
|
let pid = libc::fork();
|
||||||
|
if pid < 0 {
|
||||||
|
Err(Error::Unknown("Fork failed".to_string()))
|
||||||
|
} else if pid == 0 {
|
||||||
|
Ok(ForkResult::Child)
|
||||||
|
} else {
|
||||||
|
Ok(ForkResult::Parent(ChildHandle { pid }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Executes the current process from the beginning, as subprocess.
|
||||||
|
/// use `start_self.status()?` to wait for the child
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
pub fn startable_self() -> Result<Command, Error> {
|
||||||
|
let mut startable = Command::new(env::current_exe()?);
|
||||||
|
startable.current_dir(env::current_dir()?).args(env::args());
|
||||||
|
Ok(startable)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
//use xxhash_rust::xxh3::xxh3_64_with_seed;
|
//use xxhash_rust::xxh3::xxh3_64_with_seed;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user