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
|
- uses: actions/checkout@v4
|
||||||
- if: runner.os == 'Linux'
|
- if: runner.os == 'Linux'
|
||||||
uses: ./.github/workflows/ubuntu-prepare
|
uses: ./.github/workflows/ubuntu-prepare
|
||||||
|
- if: runner.os != 'Linux'
|
||||||
|
uses: dtolnay/rust-toolchain@stable
|
||||||
- name: Install LLVM
|
- name: Install LLVM
|
||||||
if: runner.os == 'MacOS'
|
if: runner.os == 'MacOS'
|
||||||
run: brew install llvm@${{env.MAIN_LLVM_VERSION}}
|
run: brew install llvm@${{env.MAIN_LLVM_VERSION}}
|
||||||
@ -227,8 +229,8 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
- uses: taiki-e/install-action@cargo-hack
|
- uses: taiki-e/install-action@cargo-hack
|
||||||
- run: rustup upgrade
|
|
||||||
# Note: We currently only specify minimum rust versions for the default workspace members
|
# 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
|
- 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
|
# 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 "maintainer"="afl++ team <afl@aflplus.plus>"
|
||||||
LABEL "about"="LibAFL Docker image"
|
LABEL "about"="LibAFL Docker image"
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ readme = "../../README.md"
|
|||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
keywords = ["fuzzing", "testing", "security"]
|
keywords = ["fuzzing", "testing", "security"]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
rust-version = "1.85"
|
rust-version = "1.87"
|
||||||
categories = [
|
categories = [
|
||||||
"development-tools::testing",
|
"development-tools::testing",
|
||||||
"emulators",
|
"emulators",
|
||||||
|
@ -671,7 +671,7 @@ pub struct ForkserverExecutor<I, OT, S, SHM> {
|
|||||||
forkserver: Forkserver,
|
forkserver: Forkserver,
|
||||||
observers: OT,
|
observers: OT,
|
||||||
map: Option<SHM>,
|
map: Option<SHM>,
|
||||||
phantom: PhantomData<(I, S)>,
|
phantom: PhantomData<fn() -> (I, S)>, // For Send/Sync
|
||||||
map_size: Option<usize>,
|
map_size: Option<usize>,
|
||||||
min_input_size: usize,
|
min_input_size: usize,
|
||||||
max_input_size: usize,
|
max_input_size: usize,
|
||||||
|
@ -12,7 +12,7 @@ readme = "./README.md"
|
|||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
keywords = ["fuzzing", "testing", "security"]
|
keywords = ["fuzzing", "testing", "security"]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
rust-version = "1.85"
|
rust-version = "1.87"
|
||||||
categories = [
|
categories = [
|
||||||
"development-tools::testing",
|
"development-tools::testing",
|
||||||
"emulators",
|
"emulators",
|
||||||
|
@ -1,41 +1,55 @@
|
|||||||
//! Unix `pipe` wrapper for `LibAFL`
|
//! Unix `pipe` wrapper for `LibAFL`
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use alloc::rc::Rc;
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
use core::{borrow::Borrow, cell::RefCell};
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
use std::{
|
use std::{
|
||||||
io::{self, ErrorKind, Read, Write},
|
io::{self, ErrorKind, PipeReader, PipeWriter, Read, Write},
|
||||||
os::{
|
os::unix::io::RawFd,
|
||||||
fd::{AsFd, AsRawFd, OwnedFd},
|
|
||||||
unix::io::RawFd,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
use nix::unistd::{pipe, read, write};
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
|
|
||||||
/// A unix pipe wrapper for `LibAFL`
|
/// A unix pipe wrapper for `LibAFL`
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub struct Pipe {
|
pub struct Pipe {
|
||||||
/// The read end of the pipe
|
/// The read end of the pipe
|
||||||
read_end: Option<Rc<RefCell<OwnedFd>>>,
|
read_end: Option<PipeReader>,
|
||||||
/// The write end of the pipe
|
/// 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")]
|
#[cfg(feature = "std")]
|
||||||
impl Pipe {
|
impl Pipe {
|
||||||
/// Create a new `Unix` pipe
|
/// Create a new `Unix` pipe
|
||||||
pub fn new() -> Result<Self, Error> {
|
pub fn new() -> Result<Self, Error> {
|
||||||
let (read_end, write_end) = pipe()?;
|
let (read_end, write_end) = io::pipe()?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
read_end: Some(Rc::new(RefCell::new(read_end))),
|
read_end: Some(read_end),
|
||||||
write_end: Some(Rc::new(RefCell::new(write_end))),
|
write_end: Some(write_end),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,19 +68,13 @@ impl Pipe {
|
|||||||
/// The read end
|
/// The read end
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn read_end(&self) -> Option<RawFd> {
|
pub fn read_end(&self) -> Option<RawFd> {
|
||||||
self.read_end.as_ref().map(|fd| {
|
self.read_end.as_ref().map(std::os::fd::AsRawFd::as_raw_fd)
|
||||||
let borrowed: &RefCell<OwnedFd> = fd.borrow();
|
|
||||||
borrowed.borrow().as_raw_fd()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The write end
|
/// The write end
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn write_end(&self) -> Option<RawFd> {
|
pub fn write_end(&self) -> Option<RawFd> {
|
||||||
self.write_end.as_ref().map(|fd| {
|
self.write_end.as_ref().map(std::os::fd::AsRawFd::as_raw_fd)
|
||||||
let borrowed: &RefCell<OwnedFd> = fd.borrow();
|
|
||||||
borrowed.borrow().as_raw_fd()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,11 +82,8 @@ impl Pipe {
|
|||||||
impl Read for Pipe {
|
impl Read for Pipe {
|
||||||
/// Reads a few bytes
|
/// Reads a few bytes
|
||||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
|
||||||
match self.read_end() {
|
match self.read_end.as_mut() {
|
||||||
Some(read_end) => match read(read_end, buf) {
|
Some(read_end) => read_end.read(buf),
|
||||||
Ok(res) => Ok(res),
|
|
||||||
Err(e) => Err(io::Error::from_raw_os_error(e as i32)),
|
|
||||||
},
|
|
||||||
None => Err(io::Error::new(
|
None => Err(io::Error::new(
|
||||||
ErrorKind::BrokenPipe,
|
ErrorKind::BrokenPipe,
|
||||||
"Read pipe end was already closed",
|
"Read pipe end was already closed",
|
||||||
@ -91,14 +96,8 @@ impl Read for Pipe {
|
|||||||
impl Write for Pipe {
|
impl Write for Pipe {
|
||||||
/// Writes a few bytes
|
/// Writes a few bytes
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
|
fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
|
||||||
match self.write_end.as_ref() {
|
match self.write_end.as_mut() {
|
||||||
Some(write_end) => {
|
Some(write_end) => Ok(write_end.write(buf)?),
|
||||||
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)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => Err(io::Error::new(
|
None => Err(io::Error::new(
|
||||||
ErrorKind::BrokenPipe,
|
ErrorKind::BrokenPipe,
|
||||||
"Write pipe end was already closed",
|
"Write pipe end was already closed",
|
||||||
|
@ -715,6 +715,8 @@ pub mod unix_shmem {
|
|||||||
shm_fd: c_int,
|
shm_fd: c_int,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for MmapShMem {}
|
||||||
|
|
||||||
impl MmapShMem {
|
impl MmapShMem {
|
||||||
/// Create a new [`MmapShMem`]
|
/// Create a new [`MmapShMem`]
|
||||||
///
|
///
|
||||||
@ -1036,6 +1038,8 @@ pub mod unix_shmem {
|
|||||||
map_size: usize,
|
map_size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for CommonUnixShMem {}
|
||||||
|
|
||||||
impl CommonUnixShMem {
|
impl CommonUnixShMem {
|
||||||
/// Create a new shared memory mapping, using shmget/shmat
|
/// Create a new shared memory mapping, using shmget/shmat
|
||||||
pub fn new(map_size: usize) -> Result<Self, Error> {
|
pub fn new(map_size: usize) -> Result<Self, Error> {
|
||||||
@ -1189,6 +1193,8 @@ pub mod unix_shmem {
|
|||||||
map_size: usize,
|
map_size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for AshmemShMem {}
|
||||||
|
|
||||||
#[allow(non_camel_case_types)] // expect somehow breaks here
|
#[allow(non_camel_case_types)] // expect somehow breaks here
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -1409,6 +1415,8 @@ pub mod unix_shmem {
|
|||||||
map_size: usize,
|
map_size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for MemfdShMem {}
|
||||||
|
|
||||||
impl MemfdShMem {
|
impl MemfdShMem {
|
||||||
/// Create a new shared memory mapping, using shmget/shmat
|
/// Create a new shared memory mapping, using shmget/shmat
|
||||||
pub fn new(map_size: usize) -> Result<Self, Error> {
|
pub fn new(map_size: usize) -> Result<Self, Error> {
|
||||||
@ -1612,6 +1620,8 @@ pub mod win32_shmem {
|
|||||||
map_size: usize,
|
map_size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for Win32ShMem {}
|
||||||
|
|
||||||
impl Debug for Win32ShMem {
|
impl Debug for Win32ShMem {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("Win32ShMem")
|
f.debug_struct("Win32ShMem")
|
||||||
|
@ -9,7 +9,7 @@ readme = "README.md"
|
|||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
keywords = ["fuzzing", "testing", "compiler"]
|
keywords = ["fuzzing", "testing", "compiler"]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
rust-version = "1.85"
|
rust-version = "1.87"
|
||||||
categories = [
|
categories = [
|
||||||
"development-tools::testing",
|
"development-tools::testing",
|
||||||
"emulators",
|
"emulators",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
name = "runtime_test"
|
name = "runtime_test"
|
||||||
version.workspace = true
|
version.workspace = true
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
rust-version = "1.85"
|
rust-version = "1.87"
|
||||||
authors = ["Julius Hohnerlein <julihoh@users.noreply.github.com>"]
|
authors = ["Julius Hohnerlein <julihoh@users.noreply.github.com>"]
|
||||||
description = "Runtime test of LibAFL fuzzing with symbolic execution"
|
description = "Runtime test of LibAFL fuzzing with symbolic execution"
|
||||||
documentation = "https://docs.rs/libafl"
|
documentation = "https://docs.rs/libafl"
|
||||||
|
@ -9,7 +9,7 @@ readme = "../README.md"
|
|||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
keywords = ["fuzzing", "testing"]
|
keywords = ["fuzzing", "testing"]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
rust-version = "1.85"
|
rust-version = "1.87"
|
||||||
categories = [
|
categories = [
|
||||||
"development-tools::testing",
|
"development-tools::testing",
|
||||||
"emulators",
|
"emulators",
|
||||||
|
@ -7,7 +7,7 @@ readme = "../README.md"
|
|||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
keywords = ["fuzzing", "testing", "security"]
|
keywords = ["fuzzing", "testing", "security"]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
rust-version = "1.85"
|
rust-version = "1.87"
|
||||||
categories = ["development-tools::testing"]
|
categories = ["development-tools::testing"]
|
||||||
|
|
||||||
include = [
|
include = [
|
||||||
|
@ -6,7 +6,7 @@ resolver = "2"
|
|||||||
version = "0.15.2"
|
version = "0.15.2"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
rust-version = "1.85"
|
rust-version = "1.87"
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
@ -9,7 +9,7 @@ readme = "../README.md"
|
|||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
keywords = ["fuzzing", "testing"]
|
keywords = ["fuzzing", "testing"]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
rust-version = "1.85"
|
rust-version = "1.87"
|
||||||
categories = [
|
categories = [
|
||||||
"development-tools::testing",
|
"development-tools::testing",
|
||||||
"emulators",
|
"emulators",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user