Add cmplog shared memory mapping method for forkserver (#3200)
This commit is contained in:
parent
3b6a350b24
commit
6dd52722de
@ -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) };
|
||||
|
||||
|
@ -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) };
|
||||
|
||||
|
@ -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) };
|
||||
|
||||
|
@ -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) };
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user