
* add Forkserver, Pipe Outfile struct * add forkserver executor struct, and shmem init * close pipes in the destructor of Forkserver * fill pre_exec to write out the inputs * fix * read_st, write_ctl * more handshakes * wrap Pipe in Arc, fill post_exec * add Forkserver, Pipe Outfile struct * add forkserver executor struct, and shmem init * close pipes in the destructor of Forkserver * fill pre_exec to write out the inputs * fix * read_st, write_ctl * more handshakes * wrap Pipe in Arc, fill post_exec * fix for the lastest HasExecHooks trait * use Dominik's pipe, remove Arc and temporarily pass RawFd to setstdin but trying to figure out other solutions * add libafl_tests, put a very simple vulnerable program * fix * added forkserver_simple (mostly copy-pasted from babyfuzzer) * fix test * handle crash in post_exec * add README.md * check exec time to see why it's so slow * remove double invokation of is_interesting for the obejctive * make forkserver_simple AFL-like and improve speed * some debugging help * do not evaluate feedback if solution * speedup the things * working input placement via stdin in Forkserver * don't call panic! but return errors, rewrite some comments * use AFLplusplus/afl-cc instead of AFL * use .cur_input like AFL * bring the test for forkserver back * add better README.md message * failing the initial handshake should return an error * delete some commented-out code * format * format * ForkserverExecutor needs std and is unix-only for now * clippy * OutFile error handling * fmt * clippy * don't build libafl_tests on windows * fix * keep test in forkserver.rs simple * add forkserver_test feature for libafl_tests * format * some doc Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
104 lines
2.5 KiB
Rust
104 lines
2.5 KiB
Rust
//! Unix `pipe` wrapper for `LibAFL`
|
|
use crate::Error;
|
|
use nix::unistd::{close, pipe};
|
|
|
|
#[cfg(feature = "std")]
|
|
use nix::unistd::{read, write};
|
|
#[cfg(feature = "std")]
|
|
use std::{
|
|
io::{self, ErrorKind, Read, Write},
|
|
os::unix::io::RawFd,
|
|
};
|
|
|
|
#[cfg(not(feature = "std"))]
|
|
type RawFd = i32;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Pipe {
|
|
read_end: Option<RawFd>,
|
|
write_end: Option<RawFd>,
|
|
}
|
|
|
|
impl Pipe {
|
|
pub fn new() -> Result<Self, Error> {
|
|
let (read_end, write_end) = pipe()?;
|
|
Ok(Self {
|
|
read_end: Some(read_end),
|
|
write_end: Some(write_end),
|
|
})
|
|
}
|
|
|
|
pub fn close_read_end(&mut self) {
|
|
if let Some(read_end) = self.read_end {
|
|
let _ = close(read_end);
|
|
self.read_end = None;
|
|
}
|
|
}
|
|
|
|
pub fn close_write_end(&mut self) {
|
|
if let Some(write_end) = self.write_end {
|
|
let _ = close(write_end);
|
|
self.write_end = None;
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn read_end(&self) -> Option<RawFd> {
|
|
self.read_end
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn write_end(&self) -> Option<RawFd> {
|
|
self.write_end
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "std")]
|
|
impl Read for Pipe {
|
|
/// Reads a few bytes
|
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
|
|
match self.read_end {
|
|
Some(read_end) => match read(read_end, buf) {
|
|
Ok(res) => Ok(res),
|
|
Err(e) => Err(io::Error::from_raw_os_error(e.as_errno().unwrap() as i32)),
|
|
},
|
|
None => Err(io::Error::new(
|
|
ErrorKind::BrokenPipe,
|
|
"Read pipe end was already closed",
|
|
)),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "std")]
|
|
impl Write for Pipe {
|
|
/// Writes a few bytes
|
|
fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
|
|
match self.write_end {
|
|
Some(write_end) => match write(write_end, buf) {
|
|
Ok(res) => Ok(res),
|
|
Err(e) => Err(io::Error::from_raw_os_error(e.as_errno().unwrap() as i32)),
|
|
},
|
|
None => Err(io::Error::new(
|
|
ErrorKind::BrokenPipe,
|
|
"Write pipe end was already closed",
|
|
)),
|
|
}
|
|
}
|
|
|
|
fn flush(&mut self) -> Result<(), io::Error> {
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl Drop for Pipe {
|
|
fn drop(&mut self) {
|
|
if let Some(read_end) = self.read_end {
|
|
let _ = close(read_end);
|
|
}
|
|
if let Some(write_end) = self.write_end {
|
|
let _ = close(write_end);
|
|
}
|
|
}
|
|
}
|