Add cmplog shared memory mapping method for forkserver (#3200)

This commit is contained in:
EvianZhang 2025-05-07 16:44:44 +08:00 committed by GitHub
parent 3b6a350b24
commit 6dd52722de
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 56 additions and 9 deletions

View File

@ -11,7 +11,7 @@ use clap::{Arg, ArgAction, Command};
use libafl::{
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
events::SimpleEventManager,
executors::forkserver::ForkserverExecutor,
executors::forkserver::{ForkserverExecutor, SHM_CMPLOG_ENV_VAR},
feedback_or,
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback},
fuzzer::{Fuzzer, StdFuzzer},
@ -351,7 +351,7 @@ fn fuzz(
let mut cmplog_shmem = shmem_provider.uninit_on_shmem::<AFLppCmpLogMap>().unwrap();
// let the forkserver know the shmid
unsafe {
cmplog_shmem.write_to_env("__AFL_CMPLOG_SHM_ID").unwrap();
cmplog_shmem.write_to_env(SHM_CMPLOG_ENV_VAR).unwrap();
}
let cmpmap = unsafe { OwnedRefMut::<AFLppCmpLogMap>::from_shmem(&mut cmplog_shmem) };

View File

@ -11,7 +11,7 @@ use clap::{Arg, ArgAction, Command};
use libafl::{
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
events::SimpleEventManager,
executors::forkserver::ForkserverExecutor,
executors::forkserver::{ForkserverExecutor, SHM_CMPLOG_ENV_VAR},
feedback_or,
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback},
fuzzer::{Fuzzer, StdFuzzer},
@ -354,7 +354,7 @@ fn fuzz(
let mut cmplog_shmem = shmem_provider.uninit_on_shmem::<AFLppCmpLogMap>().unwrap();
// let the forkserver know the shmid
unsafe {
cmplog_shmem.write_to_env("__AFL_CMPLOG_SHM_ID").unwrap();
cmplog_shmem.write_to_env(SHM_CMPLOG_ENV_VAR).unwrap();
}
let cmpmap = unsafe { OwnedRefMut::from_shmem(&mut cmplog_shmem) };

View File

@ -11,7 +11,10 @@ use clap::{Arg, ArgAction, Command};
use libafl::{
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
events::SimpleEventManager,
executors::{forkserver::ForkserverExecutor, sand::SANDExecutor},
executors::{
forkserver::{ForkserverExecutor, SHM_CMPLOG_ENV_VAR},
sand::SANDExecutor,
},
feedback_or,
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback},
fuzzer::{Fuzzer, StdFuzzer},
@ -398,7 +401,7 @@ fn fuzz(
let mut cmplog_shmem = shmem_provider.uninit_on_shmem::<AFLppCmpLogMap>().unwrap();
// let the forkserver know the shmid
unsafe {
cmplog_shmem.write_to_env("__AFL_CMPLOG_SHM_ID").unwrap();
cmplog_shmem.write_to_env(SHM_CMPLOG_ENV_VAR).unwrap();
}
let cmpmap = unsafe { OwnedRefMut::<AFLppCmpLogMap>::from_shmem(&mut cmplog_shmem) };

View File

@ -16,7 +16,7 @@ use libafl::monitors::SimpleMonitor;
use libafl::{
corpus::{CachedOnDiskCorpus, Corpus, OnDiskCorpus},
events::ProgressReporter,
executors::forkserver::{ForkserverExecutor, ForkserverExecutorBuilder},
executors::forkserver::{ForkserverExecutor, ForkserverExecutorBuilder, SHM_CMPLOG_ENV_VAR},
feedback_and, feedback_or, feedback_or_fast,
feedbacks::{
CaptureTimeoutFeedback, ConstFeedback, CrashFeedback, MaxMapFeedback, TimeFeedback,
@ -476,7 +476,7 @@ define_run_client!(state, mgr, fuzzer_dir, core_id, opt, is_main_node, {
// Let the Forkserver know the CmpLog shared memory map ID.
unsafe {
cmplog_shmem.write_to_env("__AFL_CMPLOG_SHM_ID").unwrap();
cmplog_shmem.write_to_env(SHM_CMPLOG_ENV_VAR).unwrap();
}
let cmpmap = unsafe { OwnedRefMut::from_shmem(&mut cmplog_shmem) };

View File

@ -147,6 +147,8 @@ const MIN_INPUT_SIZE_DEFAULT: usize = 1;
pub const SHM_FUZZ_ENV_VAR: &str = "__AFL_SHM_FUZZ_ID";
/// Environment variable key for shared memory id for edge map
pub const SHM_ENV_VAR: &str = "__AFL_SHM_ID";
/// Environment variable key for shared memory id for cmplog map
pub const SHM_CMPLOG_ENV_VAR: &str = "__AFL_CMPLOG_SHM_ID";
/// The default signal to use to kill child processes
const KILL_SIGNAL_DEFAULT: Signal = Signal::SIGTERM;

View File

@ -11,7 +11,7 @@ use libafl::{
Error,
executors::forkserver::{
FORKSRV_FD, FS_ERROR_SHM_OPEN, FS_NEW_OPT_AUTODTCT, FS_NEW_OPT_MAPSIZE,
FS_NEW_OPT_SHDMEM_FUZZ, FS_NEW_VERSION_MAX, FS_OPT_ERROR, SHM_ENV_VAR, SHM_FUZZ_ENV_VAR,
FS_NEW_OPT_SHDMEM_FUZZ, FS_NEW_VERSION_MAX, FS_OPT_ERROR, SHM_ENV_VAR, SHM_FUZZ_ENV_VAR, SHM_CMPLOG_ENV_VAR,
},
};
use libafl_bolts::os::{ChildHandle, ForkResult};
@ -22,6 +22,8 @@ use nix::{
};
use crate::coverage::{__afl_map_size, EDGES_MAP_PTR, INPUT_LENGTH_PTR, INPUT_PTR, SHM_FUZZING};
#[cfg(feature = "cmplog")]
use crate::cmps::CMPLOG_MAP_PTR;
#[cfg(any(target_os = "linux", target_vendor = "apple"))]
use crate::coverage::{__token_start, __token_stop};
@ -163,6 +165,46 @@ fn map_input_shared_memory_internal() -> Result<(), Error> {
Ok(())
}
/// Guard [`map_cmplog_shared_memory`] is invoked only once
#[cfg(feature = "cmplog")]
static CMPLOG_SHM_MAP_GUARD: OnceLock<()> = OnceLock::new();
/// Map the cmplog shared memory region.
/// The [`CMPLOG_MAP_PTR`] will be updated.
///
/// If anything failed, the forkserver will be notified with
/// [`FS_ERROR_SHM_OPEN`].
#[cfg(feature = "cmplog")]
pub fn map_cmplog_shared_memory() -> Result<(), Error> {
if CMPLOG_SHM_MAP_GUARD.set(()).is_err() {
return Err(Error::illegal_state("shared memory has been mapped before"));
}
map_cmplog_shared_memory_internal()
}
#[cfg(feature = "cmplog")]
fn map_cmplog_shared_memory_internal() -> Result<(), Error> {
let Ok(id_str) = std::env::var(SHM_CMPLOG_ENV_VAR) else {
write_error_to_forkserver(FS_ERROR_SHM_OPEN)?;
return Err(Error::illegal_argument(
"Error: variable for cmplog shared memory is not set",
));
};
let Ok(shm_id) = id_str.parse() else {
write_error_to_forkserver(FS_ERROR_SHM_OPEN)?;
return Err(Error::illegal_argument("Invalid __AFL_CMPLOG_SHM_ID value"));
};
let map = unsafe { libc::shmat(shm_id, core::ptr::null(), 0) };
if map.is_null() || core::ptr::eq(map, libc::MAP_FAILED) {
write_error_to_forkserver(FS_ERROR_SHM_OPEN)?;
return Err(Error::illegal_state("shmat for map"));
}
unsafe {
CMPLOG_MAP_PTR = map.cast();
}
Ok(())
}
/// Parent to handle all logics with forkserver children
pub trait ForkserverParent {
/// Conduct initializing routine before fuzzing loop.