LetForkserverExecutor
being Send
(#3242)
* Implement `Send` for `Shm` it is safe because we take the ownership of the inner map pointer. Only potential violation is deref the underlying pointer but that’s already unsafe. Therefore, the properties of Send still hold within the safe world. * Bump 1.87 * use std::io::pipe so that they are `Send` * clippy * upgrade * Avoid phantomdata to make ForkserverExecutor !Send * Missing gates * Fix nostd * bump in Dockerfile * use dtolnay/rust-toolchain@stable instead * setup latest toolchain on non Linux * Fix typo
This commit is contained in:
parent
ba93e9d2ea
commit
0e9dfd62ee
4
.github/workflows/build_and_test.yml
vendored
4
.github/workflows/build_and_test.yml
vendored
@ -42,6 +42,8 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- if: runner.os == 'Linux'
|
||||
uses: ./.github/workflows/ubuntu-prepare
|
||||
- if: runner.os != 'Linux'
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
- name: Install LLVM
|
||||
if: runner.os == 'MacOS'
|
||||
run: brew install llvm@${{env.MAIN_LLVM_VERSION}}
|
||||
@ -227,8 +229,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- uses: taiki-e/install-action@cargo-hack
|
||||
- run: rustup upgrade
|
||||
# Note: We currently only specify minimum rust versions for the default workspace members
|
||||
- run: cargo hack check --rust-version -p libafl -p libafl_bolts -p libafl_derive -p libafl_cc -p libafl_targets
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# syntax=docker/dockerfile:1.2
|
||||
FROM rust:1.85.0 AS libafl
|
||||
FROM rust:1.87.0 AS libafl
|
||||
LABEL "maintainer"="afl++ team <afl@aflplus.plus>"
|
||||
LABEL "about"="LibAFL Docker image"
|
||||
|
||||
|
@ -12,7 +12,7 @@ readme = "../../README.md"
|
||||
license = "MIT OR Apache-2.0"
|
||||
keywords = ["fuzzing", "testing", "security"]
|
||||
edition = "2024"
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.87"
|
||||
categories = [
|
||||
"development-tools::testing",
|
||||
"emulators",
|
||||
|
@ -671,7 +671,7 @@ pub struct ForkserverExecutor<I, OT, S, SHM> {
|
||||
forkserver: Forkserver,
|
||||
observers: OT,
|
||||
map: Option<SHM>,
|
||||
phantom: PhantomData<(I, S)>,
|
||||
phantom: PhantomData<fn() -> (I, S)>, // For Send/Sync
|
||||
map_size: Option<usize>,
|
||||
min_input_size: usize,
|
||||
max_input_size: usize,
|
||||
|
@ -12,7 +12,7 @@ readme = "./README.md"
|
||||
license = "MIT OR Apache-2.0"
|
||||
keywords = ["fuzzing", "testing", "security"]
|
||||
edition = "2024"
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.87"
|
||||
categories = [
|
||||
"development-tools::testing",
|
||||
"emulators",
|
||||
|
@ -1,41 +1,55 @@
|
||||
//! Unix `pipe` wrapper for `LibAFL`
|
||||
#[cfg(feature = "std")]
|
||||
use alloc::rc::Rc;
|
||||
#[cfg(feature = "std")]
|
||||
use core::{borrow::Borrow, cell::RefCell};
|
||||
#[cfg(feature = "std")]
|
||||
use std::{
|
||||
io::{self, ErrorKind, Read, Write},
|
||||
os::{
|
||||
fd::{AsFd, AsRawFd, OwnedFd},
|
||||
unix::io::RawFd,
|
||||
},
|
||||
io::{self, ErrorKind, PipeReader, PipeWriter, Read, Write},
|
||||
os::unix::io::RawFd,
|
||||
};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use nix::unistd::{pipe, read, write};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use crate::Error;
|
||||
|
||||
/// A unix pipe wrapper for `LibAFL`
|
||||
#[cfg(feature = "std")]
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug)]
|
||||
pub struct Pipe {
|
||||
/// The read end of the pipe
|
||||
read_end: Option<Rc<RefCell<OwnedFd>>>,
|
||||
read_end: Option<PipeReader>,
|
||||
/// The write end of the pipe
|
||||
write_end: Option<Rc<RefCell<OwnedFd>>>,
|
||||
write_end: Option<PipeWriter>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Clone for Pipe {
|
||||
fn clone(&self) -> Self {
|
||||
// try_clone only fails if we run out of fds (dup2) so this should be rather safe
|
||||
let read_end = self
|
||||
.read_end
|
||||
.as_ref()
|
||||
.map(PipeReader::try_clone)
|
||||
.transpose()
|
||||
.expect("fail to clone read_end");
|
||||
let write_end = self
|
||||
.write_end
|
||||
.as_ref()
|
||||
.map(PipeWriter::try_clone)
|
||||
.transpose()
|
||||
.expect("fail to clone read_end");
|
||||
|
||||
Self {
|
||||
read_end,
|
||||
write_end,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Pipe {
|
||||
/// Create a new `Unix` pipe
|
||||
pub fn new() -> Result<Self, Error> {
|
||||
let (read_end, write_end) = pipe()?;
|
||||
let (read_end, write_end) = io::pipe()?;
|
||||
Ok(Self {
|
||||
read_end: Some(Rc::new(RefCell::new(read_end))),
|
||||
write_end: Some(Rc::new(RefCell::new(write_end))),
|
||||
read_end: Some(read_end),
|
||||
write_end: Some(write_end),
|
||||
})
|
||||
}
|
||||
|
||||
@ -54,19 +68,13 @@ impl Pipe {
|
||||
/// The read end
|
||||
#[must_use]
|
||||
pub fn read_end(&self) -> Option<RawFd> {
|
||||
self.read_end.as_ref().map(|fd| {
|
||||
let borrowed: &RefCell<OwnedFd> = fd.borrow();
|
||||
borrowed.borrow().as_raw_fd()
|
||||
})
|
||||
self.read_end.as_ref().map(std::os::fd::AsRawFd::as_raw_fd)
|
||||
}
|
||||
|
||||
/// The write end
|
||||
#[must_use]
|
||||
pub fn write_end(&self) -> Option<RawFd> {
|
||||
self.write_end.as_ref().map(|fd| {
|
||||
let borrowed: &RefCell<OwnedFd> = fd.borrow();
|
||||
borrowed.borrow().as_raw_fd()
|
||||
})
|
||||
self.write_end.as_ref().map(std::os::fd::AsRawFd::as_raw_fd)
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,11 +82,8 @@ impl Pipe {
|
||||
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 i32)),
|
||||
},
|
||||
match self.read_end.as_mut() {
|
||||
Some(read_end) => read_end.read(buf),
|
||||
None => Err(io::Error::new(
|
||||
ErrorKind::BrokenPipe,
|
||||
"Read pipe end was already closed",
|
||||
@ -91,14 +96,8 @@ impl Read for Pipe {
|
||||
impl Write for Pipe {
|
||||
/// Writes a few bytes
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
|
||||
match self.write_end.as_ref() {
|
||||
Some(write_end) => {
|
||||
let borrowed: &RefCell<OwnedFd> = write_end;
|
||||
match write((*borrowed).borrow().as_fd(), buf) {
|
||||
Ok(res) => Ok(res),
|
||||
Err(e) => Err(io::Error::from_raw_os_error(e as i32)),
|
||||
}
|
||||
}
|
||||
match self.write_end.as_mut() {
|
||||
Some(write_end) => Ok(write_end.write(buf)?),
|
||||
None => Err(io::Error::new(
|
||||
ErrorKind::BrokenPipe,
|
||||
"Write pipe end was already closed",
|
||||
|
@ -715,6 +715,8 @@ pub mod unix_shmem {
|
||||
shm_fd: c_int,
|
||||
}
|
||||
|
||||
unsafe impl Send for MmapShMem {}
|
||||
|
||||
impl MmapShMem {
|
||||
/// Create a new [`MmapShMem`]
|
||||
///
|
||||
@ -1036,6 +1038,8 @@ pub mod unix_shmem {
|
||||
map_size: usize,
|
||||
}
|
||||
|
||||
unsafe impl Send for CommonUnixShMem {}
|
||||
|
||||
impl CommonUnixShMem {
|
||||
/// Create a new shared memory mapping, using shmget/shmat
|
||||
pub fn new(map_size: usize) -> Result<Self, Error> {
|
||||
@ -1189,6 +1193,8 @@ pub mod unix_shmem {
|
||||
map_size: usize,
|
||||
}
|
||||
|
||||
unsafe impl Send for AshmemShMem {}
|
||||
|
||||
#[allow(non_camel_case_types)] // expect somehow breaks here
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
@ -1409,6 +1415,8 @@ pub mod unix_shmem {
|
||||
map_size: usize,
|
||||
}
|
||||
|
||||
unsafe impl Send for MemfdShMem {}
|
||||
|
||||
impl MemfdShMem {
|
||||
/// Create a new shared memory mapping, using shmget/shmat
|
||||
pub fn new(map_size: usize) -> Result<Self, Error> {
|
||||
@ -1612,6 +1620,8 @@ pub mod win32_shmem {
|
||||
map_size: usize,
|
||||
}
|
||||
|
||||
unsafe impl Send for Win32ShMem {}
|
||||
|
||||
impl Debug for Win32ShMem {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Win32ShMem")
|
||||
|
@ -9,7 +9,7 @@ readme = "README.md"
|
||||
license = "MIT OR Apache-2.0"
|
||||
keywords = ["fuzzing", "testing", "compiler"]
|
||||
edition = "2024"
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.87"
|
||||
categories = [
|
||||
"development-tools::testing",
|
||||
"emulators",
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "runtime_test"
|
||||
version.workspace = true
|
||||
edition = "2024"
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.87"
|
||||
authors = ["Julius Hohnerlein <julihoh@users.noreply.github.com>"]
|
||||
description = "Runtime test of LibAFL fuzzing with symbolic execution"
|
||||
documentation = "https://docs.rs/libafl"
|
||||
|
@ -9,7 +9,7 @@ readme = "../README.md"
|
||||
license = "MIT OR Apache-2.0"
|
||||
keywords = ["fuzzing", "testing"]
|
||||
edition = "2024"
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.87"
|
||||
categories = [
|
||||
"development-tools::testing",
|
||||
"emulators",
|
||||
|
@ -7,7 +7,7 @@ readme = "../README.md"
|
||||
license = "MIT OR Apache-2.0"
|
||||
keywords = ["fuzzing", "testing", "security"]
|
||||
edition = "2024"
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.87"
|
||||
categories = ["development-tools::testing"]
|
||||
|
||||
include = [
|
||||
|
@ -6,7 +6,7 @@ resolver = "2"
|
||||
version = "0.15.2"
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2024"
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.87"
|
||||
|
||||
[profile.dev]
|
||||
panic = "abort"
|
||||
|
@ -9,7 +9,7 @@ readme = "../README.md"
|
||||
license = "MIT OR Apache-2.0"
|
||||
keywords = ["fuzzing", "testing"]
|
||||
edition = "2024"
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.87"
|
||||
categories = [
|
||||
"development-tools::testing",
|
||||
"emulators",
|
||||
|
Loading…
x
Reference in New Issue
Block a user