Better SigInt handler (#1710)
* fix simd * better exit * chg * more * more * use * change to proper name * w * aaaaaaa * delete * just separate them * shell check
This commit is contained in:
parent
210315da0f
commit
fad59987d9
78
.github/workflows/build_and_test.yml
vendored
78
.github/workflows/build_and_test.yml
vendored
@ -282,40 +282,84 @@ jobs:
|
||||
if: runner.os == 'macOS' # use bash v4
|
||||
run: /usr/local/bin/bash -c 'RUN_ON_CI=1 ./scripts/test_all_fuzzers.sh'
|
||||
|
||||
executions-check:
|
||||
qemu_fuzzers:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
- name: Fix python (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: rm /usr/local/bin/2to3* /usr/local/bin/idle3* /usr/local/bin/pydoc3* /usr/local/bin/python3*
|
||||
- name: Remove obsolete llvm (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: brew remove --force llvm clang
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
if: runner.os == 'Linux'
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
with:
|
||||
# this might remove tools that are actually needed,
|
||||
# if set to "true" but frees about 6 GB
|
||||
tool-cache: false
|
||||
|
||||
# all of these default to true, but feel free to set to
|
||||
# "false" if necessary for your workflow
|
||||
android: true
|
||||
dotnet: true
|
||||
haskell: true
|
||||
large-packages: false
|
||||
docker-images: true
|
||||
swap-storage: true
|
||||
- name: Add nightly rustfmt and clippy
|
||||
run: rustup toolchain install nightly --component rustfmt --component clippy --allow-downgrade
|
||||
- name: Add no_std toolchain
|
||||
run: rustup toolchain install nightly-x86_64-unknown-linux-gnu ; rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
|
||||
- name: Add wasm target
|
||||
run: rustup target add wasm32-unknown-unknown
|
||||
- name: Install ucd-generate
|
||||
run: cargo install -f ucd-generate
|
||||
- name: Remove obsolete llvm (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
run: sudo apt purge llvm* clang*
|
||||
- uses: lyricwulf/abc@v1
|
||||
with:
|
||||
linux: llvm-15 llvm-15-dev clang-15
|
||||
macos: python@3.11 llvm@15 bash coreutils
|
||||
with:
|
||||
linux: llvm-15 llvm-15-dev clang-15 nasm ninja-build gcc-arm-linux-gnueabi g++-arm-linux-gnueabi gcc-aarch64-linux-gnu g++-aarch64-linux-gnu gcc-mipsel-linux-gnu g++-mipsel-linux-gnu gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc6-dev-i386-cross libc6-dev libc6-dev-i386 lib32gcc-11-dev lib32stdc++-11-dev libgtk-3-dev pax-utils libz3-dev
|
||||
# update bash for macos to support `declare -A` command`
|
||||
macos: llvm@15 libpng nasm coreutils z3 bash wget
|
||||
- name: Set clang version
|
||||
if: runner.os == 'Linux'
|
||||
run: sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-15 100
|
||||
- name: Set clang++ version
|
||||
if: runner.os == 'Linux'
|
||||
run: sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-15 100
|
||||
- name: pip install
|
||||
run: python3 -m pip install msgpack jinja2 find_libpython
|
||||
# Note that nproc needs to have coreutils installed on macOS, so the order of CI commands matters.
|
||||
- name: enable mult-thread for `make`
|
||||
run: export MAKEFLAGS="-j$(expr $(nproc) \+ 1)"
|
||||
- name: install cargo-make
|
||||
uses: baptiste0928/cargo-install@v1.3.0
|
||||
with:
|
||||
crate: cargo-make
|
||||
- name: install wasm-pack
|
||||
uses: baptiste0928/cargo-install@v1.3.0
|
||||
with:
|
||||
crate: wasm-pack
|
||||
- name: install chrome
|
||||
uses: browser-actions/setup-chrome@v1
|
||||
with:
|
||||
chrome-version: stable
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true # recursively checkout submodules
|
||||
fetch-depth: 0
|
||||
fetch-depth: 0 # to diff with origin/main
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: Build and run libfuzzer_libpng (Linux)
|
||||
- name: Symlink Headers
|
||||
if: runner.os == 'Linux'
|
||||
run: ./scripts/executions-check.sh
|
||||
- name: Build and run libfuzzer_libpng (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: /usr/local/bin/bash -c './scripts/executions-check.sh'
|
||||
# We can't install gcc-multilib which would usually do this for us due to collisions with other packages
|
||||
run: sudo ln -s /usr/include/asm-generic /usr/include/asm
|
||||
- name: Build and run example fuzzers (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
run: RUN_ON_CI=1 RUN_QEMU_FUZZER=1 LLVM_CONFIG=llvm-config-15 ./scripts/test_all_fuzzers.sh
|
||||
|
||||
|
||||
nostd-build:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -44,7 +44,10 @@ use typed_builder::TypedBuilder;
|
||||
use crate::events::{CentralizedEventManager, CentralizedLlmpEventBroker};
|
||||
#[cfg(feature = "std")]
|
||||
use crate::{
|
||||
events::{EventConfig, LlmpRestartingEventManager, ManagerKind, RestartingMgr},
|
||||
events::{
|
||||
llmp::{LlmpRestartingEventManager, ManagerKind, RestartingMgr},
|
||||
EventConfig,
|
||||
},
|
||||
monitors::Monitor,
|
||||
state::{HasExecutions, State},
|
||||
Error,
|
||||
|
@ -41,7 +41,7 @@ use typed_builder::TypedBuilder;
|
||||
|
||||
use super::{CustomBufEventResult, CustomBufHandlerFn};
|
||||
#[cfg(all(unix, feature = "std"))]
|
||||
use crate::events::{shutdown_handler, SHUTDOWN_SIGHANDLER_DATA};
|
||||
use crate::events::EVENTMGR_SIGHANDLER_STATE;
|
||||
use crate::{
|
||||
events::{
|
||||
BrokerEventResult, Event, EventConfig, EventFirer, EventManager, EventManagerId,
|
||||
@ -1155,6 +1155,19 @@ where
|
||||
S: State + HasExecutions,
|
||||
MT: Monitor + Clone,
|
||||
{
|
||||
/// Internal function, returns true when shuttdown is requested by a `SIGINT` signal
|
||||
#[inline]
|
||||
#[allow(clippy::unused_self)]
|
||||
fn is_shutting_down() -> bool {
|
||||
#[cfg(unix)]
|
||||
unsafe {
|
||||
core::ptr::read_volatile(core::ptr::addr_of!(EVENTMGR_SIGHANDLER_STATE.shutting_down))
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
false
|
||||
}
|
||||
|
||||
/// Launch the restarting manager
|
||||
pub fn launch(&mut self) -> Result<(Option<S>, LlmpRestartingEventManager<S, SP>), Error> {
|
||||
// We start ourself as child process to actually fuzz
|
||||
@ -1235,7 +1248,7 @@ where
|
||||
|
||||
// First, create a channel from the current fuzzer to the next to store state between restarts.
|
||||
#[cfg(unix)]
|
||||
let mut staterestorer: StateRestorer<SP> =
|
||||
let staterestorer: StateRestorer<SP> =
|
||||
StateRestorer::new(self.shmem_provider.new_shmem(256 * 1024 * 1024)?);
|
||||
|
||||
#[cfg(not(unix))]
|
||||
@ -1244,21 +1257,9 @@ where
|
||||
// Store the information to a map.
|
||||
staterestorer.write_to_env(_ENV_FUZZER_SENDER)?;
|
||||
|
||||
#[cfg(unix)]
|
||||
unsafe {
|
||||
let data = &mut SHUTDOWN_SIGHANDLER_DATA;
|
||||
// Write the pointer to staterestorer so we can release its shmem later
|
||||
core::ptr::write_volatile(
|
||||
&mut data.staterestorer_ptr,
|
||||
&mut staterestorer as *mut _ as *mut std::ffi::c_void,
|
||||
);
|
||||
data.allocator_pid = std::process::id() as usize;
|
||||
data.shutdown_handler = shutdown_handler::<SP> as *const std::ffi::c_void;
|
||||
}
|
||||
|
||||
// We setup signal handlers to clean up shmem segments used by state restorer
|
||||
#[cfg(all(unix, not(miri)))]
|
||||
if let Err(_e) = unsafe { setup_signal_handler(&mut SHUTDOWN_SIGHANDLER_DATA) } {
|
||||
if let Err(_e) = unsafe { setup_signal_handler(&mut EVENTMGR_SIGHANDLER_STATE) } {
|
||||
// We can live without a proper ctrl+c signal handler. Print and ignore.
|
||||
log::error!("Failed to setup signal handlers: {_e}");
|
||||
}
|
||||
@ -1305,7 +1306,7 @@ where
|
||||
panic!("Fuzzer-respawner: Storing state in crashed fuzzer instance did not work, no point to spawn the next client! This can happen if the child calls `exit()`, in that case make sure it uses `abort()`, if it got killed unrecoverable (OOM), or if there is a bug in the fuzzer itself. (Child exited with: {child_status})");
|
||||
}
|
||||
|
||||
if staterestorer.wants_to_exit() {
|
||||
if staterestorer.wants_to_exit() || Self::is_shutting_down() {
|
||||
return Err(Error::shutting_down());
|
||||
}
|
||||
|
||||
@ -1739,7 +1740,7 @@ mod tests {
|
||||
|
||||
use crate::{
|
||||
corpus::{Corpus, InMemoryCorpus, Testcase},
|
||||
events::{llmp::_ENV_FUZZER_SENDER, LlmpEventManager},
|
||||
events::llmp::{LlmpEventManager, _ENV_FUZZER_SENDER},
|
||||
executors::{ExitKind, InProcessExecutor},
|
||||
feedbacks::ConstFeedback,
|
||||
fuzzer::Fuzzer,
|
||||
|
@ -18,8 +18,6 @@ pub mod tcp;
|
||||
#[cfg(feature = "scalability_introspection")]
|
||||
use alloc::string::ToString;
|
||||
use alloc::{boxed::Box, string::String, vec::Vec};
|
||||
#[cfg(all(unix, feature = "std"))]
|
||||
use core::ffi::c_void;
|
||||
use core::{
|
||||
fmt,
|
||||
hash::{BuildHasher, Hasher},
|
||||
@ -33,8 +31,6 @@ pub use launcher::*;
|
||||
#[cfg(all(unix, feature = "std"))]
|
||||
use libafl_bolts::os::unix_signals::{siginfo_t, ucontext_t, Handler, Signal};
|
||||
use libafl_bolts::{current_time, ClientId};
|
||||
#[cfg(all(unix, feature = "std"))]
|
||||
use libafl_bolts::{shmem::ShMemProvider, staterestore::StateRestorer};
|
||||
pub use llmp::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
#[cfg(feature = "std")]
|
||||
@ -58,10 +54,8 @@ use crate::{
|
||||
|
||||
/// Check if ctrl-c is sent with this struct
|
||||
#[cfg(all(unix, feature = "std"))]
|
||||
pub static mut SHUTDOWN_SIGHANDLER_DATA: ShutdownSignalData = ShutdownSignalData {
|
||||
allocator_pid: 0,
|
||||
staterestorer_ptr: core::ptr::null_mut(),
|
||||
shutdown_handler: core::ptr::null(),
|
||||
pub static mut EVENTMGR_SIGHANDLER_STATE: ShutdownSignalData = ShutdownSignalData {
|
||||
shutting_down: false,
|
||||
};
|
||||
|
||||
/// A signal handler for releasing `StateRestore` `ShMem`
|
||||
@ -69,60 +63,21 @@ pub static mut SHUTDOWN_SIGHANDLER_DATA: ShutdownSignalData = ShutdownSignalData
|
||||
#[cfg(all(unix, feature = "std"))]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ShutdownSignalData {
|
||||
allocator_pid: usize,
|
||||
staterestorer_ptr: *mut c_void,
|
||||
shutdown_handler: *const c_void,
|
||||
shutting_down: bool,
|
||||
}
|
||||
|
||||
/// Type for shutdown handler
|
||||
#[cfg(all(unix, feature = "std"))]
|
||||
pub type ShutdownFuncPtr =
|
||||
unsafe fn(Signal, &mut siginfo_t, Option<&mut ucontext_t>, data: &mut ShutdownSignalData);
|
||||
|
||||
/// Shutdown handler. `SigTerm`, `SigInterrupt`, `SigQuit` call this
|
||||
/// We can't handle SIGKILL in the signal handler, this means that you shouldn't kill your fuzzer with `kill -9` because then the shmem segments are never freed
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This will acceess `data` and write to the global `data.staterestorer_ptr` if it's not null.
|
||||
#[cfg(all(unix, feature = "std"))]
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
pub unsafe fn shutdown_handler<SP>(
|
||||
signal: Signal,
|
||||
_info: &mut siginfo_t,
|
||||
_context: Option<&mut ucontext_t>,
|
||||
data: &ShutdownSignalData,
|
||||
) where
|
||||
SP: ShMemProvider,
|
||||
{
|
||||
log::info!(
|
||||
"Fuzzer shutdown by Signal: {} Pid: {}",
|
||||
signal,
|
||||
std::process::id()
|
||||
);
|
||||
|
||||
let ptr = data.staterestorer_ptr;
|
||||
if ptr.is_null() || data.allocator_pid != std::process::id() as usize {
|
||||
// Do nothing
|
||||
} else {
|
||||
// The process allocated the staterestorer map must take care of it
|
||||
let sr = (ptr as *mut StateRestorer<SP>).as_mut().unwrap();
|
||||
// log::trace!("{:#?}", sr);
|
||||
std::ptr::drop_in_place(sr);
|
||||
}
|
||||
log::info!("Bye!");
|
||||
libc::_exit(0);
|
||||
}
|
||||
|
||||
#[cfg(all(unix, feature = "std"))]
|
||||
impl Handler for ShutdownSignalData {
|
||||
fn handle(&mut self, signal: Signal, info: &mut siginfo_t, context: Option<&mut ucontext_t>) {
|
||||
fn handle(
|
||||
&mut self,
|
||||
_signal: Signal,
|
||||
_info: &mut siginfo_t,
|
||||
_context: Option<&mut ucontext_t>,
|
||||
) {
|
||||
unsafe {
|
||||
let data = &mut SHUTDOWN_SIGHANDLER_DATA;
|
||||
if !data.shutdown_handler.is_null() {
|
||||
let func: ShutdownFuncPtr = std::mem::transmute(data.shutdown_handler);
|
||||
(func)(signal, info, context, data);
|
||||
}
|
||||
core::ptr::write_volatile(core::ptr::addr_of_mut!(self.shutting_down), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,10 +5,6 @@ use alloc::{
|
||||
string::{String, ToString},
|
||||
vec::Vec,
|
||||
};
|
||||
#[cfg(all(unix, feature = "std"))]
|
||||
use core::ffi::c_void;
|
||||
#[cfg(all(unix, feature = "std"))]
|
||||
use core::ptr::write_volatile;
|
||||
use core::{fmt::Debug, marker::PhantomData};
|
||||
#[cfg(feature = "std")]
|
||||
use core::{
|
||||
@ -30,7 +26,7 @@ use serde::{de::DeserializeOwned, Serialize};
|
||||
|
||||
use super::{CustomBufEventResult, CustomBufHandlerFn, HasCustomBufHandlers, ProgressReporter};
|
||||
#[cfg(all(unix, feature = "std"))]
|
||||
use crate::events::{shutdown_handler, SHUTDOWN_SIGHANDLER_DATA};
|
||||
use crate::events::EVENTMGR_SIGHANDLER_STATE;
|
||||
use crate::{
|
||||
events::{
|
||||
BrokerEventResult, Event, EventFirer, EventManager, EventManagerId, EventProcessor,
|
||||
@ -450,6 +446,19 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Internal function, returns true when shuttdown is requested by a `SIGINT` signal
|
||||
#[inline]
|
||||
#[allow(clippy::unused_self)]
|
||||
fn is_shutting_down() -> bool {
|
||||
#[cfg(unix)]
|
||||
unsafe {
|
||||
core::ptr::read_volatile(core::ptr::addr_of!(EVENTMGR_SIGHANDLER_STATE.shutting_down))
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
false
|
||||
}
|
||||
|
||||
/// Launch the simple restarting manager.
|
||||
/// This [`EventManager`] is simple and single threaded,
|
||||
/// but can still used shared maps to recover from crashes and timeouts.
|
||||
@ -463,7 +472,7 @@ where
|
||||
let mut staterestorer = if std::env::var(_ENV_FUZZER_SENDER).is_err() {
|
||||
// First, create a place to store state in, for restarts.
|
||||
#[cfg(unix)]
|
||||
let mut staterestorer: StateRestorer<SP> =
|
||||
let staterestorer: StateRestorer<SP> =
|
||||
StateRestorer::new(shmem_provider.new_shmem(256 * 1024 * 1024)?);
|
||||
#[cfg(not(unix))]
|
||||
let staterestorer: StateRestorer<SP> =
|
||||
@ -472,21 +481,9 @@ where
|
||||
//let staterestorer = { LlmpSender::new(shmem_provider.clone(), 0, false)? };
|
||||
staterestorer.write_to_env(_ENV_FUZZER_SENDER)?;
|
||||
|
||||
#[cfg(unix)]
|
||||
unsafe {
|
||||
let data = &mut SHUTDOWN_SIGHANDLER_DATA;
|
||||
// Write the pointer to staterestorer so we can release its shmem later
|
||||
write_volatile(
|
||||
&mut data.staterestorer_ptr,
|
||||
&mut staterestorer as *mut _ as *mut c_void,
|
||||
);
|
||||
data.allocator_pid = std::process::id() as usize;
|
||||
data.shutdown_handler = shutdown_handler::<SP> as *const c_void;
|
||||
}
|
||||
|
||||
// We setup signal handlers to clean up shmem segments used by state restorer
|
||||
#[cfg(all(unix, not(miri)))]
|
||||
if let Err(_e) = unsafe { setup_signal_handler(&mut SHUTDOWN_SIGHANDLER_DATA) } {
|
||||
if let Err(_e) = unsafe { setup_signal_handler(&mut EVENTMGR_SIGHANDLER_STATE) } {
|
||||
// We can live without a proper ctrl+c signal handler. Print and ignore.
|
||||
log::error!("Failed to setup signal handlers: {_e}");
|
||||
}
|
||||
@ -520,7 +517,7 @@ where
|
||||
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
|
||||
if staterestorer.wants_to_exit() {
|
||||
if staterestorer.wants_to_exit() || Self::is_shutting_down() {
|
||||
return Err(Error::shutting_down());
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ use typed_builder::TypedBuilder;
|
||||
|
||||
use super::{CustomBufEventResult, CustomBufHandlerFn};
|
||||
#[cfg(all(unix, feature = "std"))]
|
||||
use crate::events::{shutdown_handler, SHUTDOWN_SIGHANDLER_DATA};
|
||||
use crate::events::EVENTMGR_SIGHANDLER_STATE;
|
||||
use crate::{
|
||||
events::{
|
||||
BrokerEventResult, Event, EventConfig, EventFirer, EventManager, EventManagerId,
|
||||
@ -953,7 +953,7 @@ where
|
||||
/// The kind of manager we're creating right now
|
||||
#[cfg(feature = "std")]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum ManagerKind {
|
||||
pub enum TcpManagerKind {
|
||||
/// Any kind will do
|
||||
Any,
|
||||
/// A client, getting messages from a local broker.
|
||||
@ -979,7 +979,7 @@ where
|
||||
MT: Monitor + Clone,
|
||||
S: State + HasExecutions,
|
||||
{
|
||||
RestartingMgr::builder()
|
||||
TcpRestartingMgr::builder()
|
||||
.shmem_provider(StdShMemProvider::new()?)
|
||||
.monitor(Some(monitor))
|
||||
.broker_port(broker_port)
|
||||
@ -988,13 +988,13 @@ where
|
||||
.launch()
|
||||
}
|
||||
|
||||
/// Provides a `builder` which can be used to build a [`RestartingMgr`], which is a combination of a
|
||||
/// Provides a `builder` which can be used to build a [`TcpRestartingMgr`], which is a combination of a
|
||||
/// `restarter` and `runner`, that can be used on systems both with and without `fork` support. The
|
||||
/// `restarter` will start a new process each time the child crashes or times out.
|
||||
#[cfg(feature = "std")]
|
||||
#[allow(clippy::default_trait_access, clippy::ignored_unit_patterns)]
|
||||
#[derive(TypedBuilder, Debug)]
|
||||
pub struct RestartingMgr<MT, S, SP>
|
||||
pub struct TcpRestartingMgr<MT, S, SP>
|
||||
where
|
||||
S: UsesInput + DeserializeOwned,
|
||||
SP: ShMemProvider + 'static,
|
||||
@ -1016,8 +1016,8 @@ where
|
||||
#[builder(default = None)]
|
||||
remote_broker_addr: Option<SocketAddr>,
|
||||
/// The type of manager to build
|
||||
#[builder(default = ManagerKind::Any)]
|
||||
kind: ManagerKind,
|
||||
#[builder(default = TcpManagerKind::Any)]
|
||||
kind: TcpManagerKind,
|
||||
/// The amount of external clients that should have connected (not counting our own tcp client)
|
||||
/// before this broker quits _after the last client exited_.
|
||||
/// If `None`, the broker will never quit when the last client exits, but run forever.
|
||||
@ -1035,12 +1035,21 @@ where
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[allow(clippy::type_complexity, clippy::too_many_lines)]
|
||||
impl<MT, S, SP> RestartingMgr<MT, S, SP>
|
||||
impl<MT, S, SP> TcpRestartingMgr<MT, S, SP>
|
||||
where
|
||||
SP: ShMemProvider,
|
||||
S: State + HasExecutions,
|
||||
MT: Monitor + Clone,
|
||||
{
|
||||
/// Internal function, returns true when shuttdown is requested by a `SIGINT` signal
|
||||
#[inline]
|
||||
#[allow(clippy::unused_self)]
|
||||
fn is_shutting_down() -> bool {
|
||||
unsafe {
|
||||
core::ptr::read_volatile(core::ptr::addr_of!(EVENTMGR_SIGHANDLER_STATE.shutting_down))
|
||||
}
|
||||
}
|
||||
|
||||
/// Launch the restarting manager
|
||||
pub fn launch(&mut self) -> Result<(Option<S>, TcpRestartingEventManager<S, SP>), Error> {
|
||||
// We start ourself as child process to actually fuzz
|
||||
@ -1057,7 +1066,7 @@ where
|
||||
|
||||
// We get here if we are on Unix, or we are a broker on Windows (or without forks).
|
||||
let (mgr, core_id) = match self.kind {
|
||||
ManagerKind::Any => {
|
||||
TcpManagerKind::Any => {
|
||||
let connection = create_nonblocking_listener(("127.0.0.1", self.broker_port));
|
||||
match connection {
|
||||
Ok(listener) => {
|
||||
@ -1088,7 +1097,7 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
ManagerKind::Broker => {
|
||||
TcpManagerKind::Broker => {
|
||||
let event_broker = TcpEventBroker::<S::Input, MT>::new(
|
||||
format!("127.0.0.1:{}", self.broker_port),
|
||||
self.monitor.take().unwrap(),
|
||||
@ -1097,7 +1106,7 @@ where
|
||||
broker_things(event_broker, self.remote_broker_addr)?;
|
||||
unreachable!("The broker may never return normally, only on errors or when shutting down.");
|
||||
}
|
||||
ManagerKind::Client { cpu_core } => {
|
||||
TcpManagerKind::Client { cpu_core } => {
|
||||
// We are a client
|
||||
let mgr = TcpEventManager::<S>::on_port(self.broker_port, self.configuration)?;
|
||||
|
||||
@ -1116,7 +1125,7 @@ where
|
||||
|
||||
// First, create a channel from the current fuzzer to the next to store state between restarts.
|
||||
#[cfg(unix)]
|
||||
let mut staterestorer: StateRestorer<SP> =
|
||||
let staterestorer: StateRestorer<SP> =
|
||||
StateRestorer::new(self.shmem_provider.new_shmem(256 * 1024 * 1024)?);
|
||||
|
||||
#[cfg(not(unix))]
|
||||
@ -1125,21 +1134,9 @@ where
|
||||
// Store the information to a map.
|
||||
staterestorer.write_to_env(_ENV_FUZZER_SENDER)?;
|
||||
|
||||
#[cfg(unix)]
|
||||
unsafe {
|
||||
let data = &mut SHUTDOWN_SIGHANDLER_DATA;
|
||||
// Write the pointer to staterestorer so we can release its shmem later
|
||||
core::ptr::write_volatile(
|
||||
&mut data.staterestorer_ptr,
|
||||
&mut staterestorer as *mut _ as *mut std::ffi::c_void,
|
||||
);
|
||||
data.allocator_pid = std::process::id() as usize;
|
||||
data.shutdown_handler = shutdown_handler::<SP> as *const std::ffi::c_void;
|
||||
}
|
||||
|
||||
// We setup signal handlers to clean up shmem segments used by state restorer
|
||||
#[cfg(all(unix, not(miri)))]
|
||||
if let Err(_e) = unsafe { setup_signal_handler(&mut SHUTDOWN_SIGHANDLER_DATA) } {
|
||||
if let Err(_e) = unsafe { setup_signal_handler(&mut EVENTMGR_SIGHANDLER_STATE) } {
|
||||
// We can live without a proper ctrl+c signal handler. Print and ignore.
|
||||
log::error!("Failed to setup signal handlers: {_e}");
|
||||
}
|
||||
@ -1187,7 +1184,7 @@ where
|
||||
panic!("Fuzzer-respawner: Storing state in crashed fuzzer instance did not work, no point to spawn the next client! This can happen if the child calls `exit()`, in that case make sure it uses `abort()`, if it got killed unrecoverable (OOM), or if there is a bug in the fuzzer itself. (Child exited with: {child_status})");
|
||||
}
|
||||
|
||||
if staterestorer.wants_to_exit() {
|
||||
if staterestorer.wants_to_exit() || Self::is_shutting_down() {
|
||||
return Err(Error::shutting_down());
|
||||
}
|
||||
|
||||
|
@ -1977,7 +1977,7 @@ impl Handler for LlmpShutdownSignalHandler {
|
||||
_context: Option<&mut ucontext_t>,
|
||||
) {
|
||||
unsafe {
|
||||
ptr::write_volatile(&mut self.shutting_down, true);
|
||||
ptr::write_volatile(ptr::addr_of_mut!(self.shutting_down), true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2245,7 +2245,7 @@ where
|
||||
#[cfg(unix)]
|
||||
#[allow(clippy::unused_self)]
|
||||
fn is_shutting_down(&self) -> bool {
|
||||
unsafe { ptr::read_volatile(&LLMP_SIGHANDLER_STATE.shutting_down) }
|
||||
unsafe { ptr::read_volatile(ptr::addr_of!(LLMP_SIGHANDLER_STATE.shutting_down)) }
|
||||
}
|
||||
|
||||
/// Always returns true on platforms, where no shutdown signal handlers are supported
|
||||
|
@ -1,56 +0,0 @@
|
||||
#!/bin/bash
|
||||
install_libpng() {
|
||||
cd ./fuzzers/libfuzzer_libpng && wget https://deac-fra.dl.sourceforge.net/project/libpng/libpng16/1.6.37/libpng-1.6.37.tar.xz
|
||||
tar -xvf libpng-1.6.37.tar.xz || echo "Failed to download libpng"
|
||||
cd libpng-1.6.37 && ./configure --enable-shared=no --with-pic=yes --enable-hardware-optimizations=yes && cd ..
|
||||
}
|
||||
|
||||
build_libpng(){
|
||||
cargo build --release || echo "ERROR: Failed to build libfuzzer_libpng"
|
||||
|
||||
cd libpng-1.6.37 && make CC="$(pwd)/../target/release/libafl_cc" CXX="$(pwd)/../target/release/ libafl_cxx" -j "$(nproc)" && cd ..
|
||||
}
|
||||
|
||||
git_checkout(){
|
||||
git reset --hard HEAD^
|
||||
}
|
||||
|
||||
build_run_fuzzer(){
|
||||
./target/release/libafl_cxx ./harness.cc libpng-1.6.37/.libs/libpng16.a -I libpng-1.6.37/ -o fuzzer_libpng -lz -lm || exit 2
|
||||
|
||||
./fuzzer_libpng > log.txt &
|
||||
|
||||
# wait that fuzzer_libpng become the broker
|
||||
sleep 1
|
||||
|
||||
timeout 5m ./fuzzer_libpng > /dev/null 2>&1 &
|
||||
|
||||
while true; do
|
||||
if grep -q "Broker" log.txt ; then
|
||||
pkill -9 "fuzzer_libpng"
|
||||
executions=$(grep -m 1 "Broker" log.txt | awk '{print $14}')
|
||||
rm -rf ./libafl_unix_shmem_server
|
||||
echo "${executions%,}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
main(){
|
||||
install_libpng
|
||||
|
||||
build_libpng
|
||||
echo "start to run the new fuzzer"
|
||||
new_executions=$(build_run_fuzzer)
|
||||
|
||||
git_checkout
|
||||
|
||||
build_libpng
|
||||
echo "start to run the last fuzzer"
|
||||
last_executions=$(build_run_fuzzer)
|
||||
|
||||
echo "the execution count of the new fuzzer is $new_executions"
|
||||
echo "the execution count of the last fuzzer is $last_executions"
|
||||
}
|
||||
|
||||
main
|
@ -15,6 +15,19 @@ else
|
||||
export PROFILE_DIR=debug
|
||||
fi
|
||||
|
||||
|
||||
if [[ -z "${RUN_ON_CI}" ]]; then
|
||||
:
|
||||
else
|
||||
if [[ -z "${RUN_QEMU_FUZZER}" ]]; then
|
||||
fuzzers=$(echo "$fuzzers" | tr ' ' '\n' | grep -v "qemu")
|
||||
backtrace_fuzzers=$(echo "$backtrace_fuzzers" | tr ' ' '\n' | grep "qemu")
|
||||
else
|
||||
fuzzers=$(echo "$fuzzers" | tr ' ' '\n' | grep "qemu")
|
||||
backtrace_fuzzers=$(echo "$backtrace_fuzzers" | tr ' ' '\n' | grep -v "qemu")
|
||||
fi
|
||||
fi
|
||||
|
||||
libafl=$(pwd)
|
||||
|
||||
# build with a shared target dir for all fuzzers. this should speed up
|
||||
|
Loading…
x
Reference in New Issue
Block a user