libafl-fuzz: Introduce Support for QEMU mode (#2481)
* libafl-fuzz: simplify Makefile.toml * Re-introduce support for old AFL++ forkserver * clippy * libafl-fuzz: add support for QEMU mode * libafl-fuzz: simplify Makefile
This commit is contained in:
parent
799c634fef
commit
2287afc59b
@ -13,27 +13,32 @@ LLVM_CONFIG = { value = "llvm-config-18", condition = { env_not_set = [
|
||||
"LLVM_CONFIG",
|
||||
] } }
|
||||
AFL_VERSION = "db23931e7c1727ddac8691a6241c97b2203ec6fc"
|
||||
AFL_DIR_NAME = { value = "./AFLplusplus-${AFL_VERSION}" }
|
||||
AFL_CC_PATH = { value = "${AFL_DIR_NAME}/afl-clang-fast" }
|
||||
AFL_DIR = { value = "./AFLplusplus" }
|
||||
AFL_CC_PATH = { value = "${AFL_DIR}/afl-clang-fast" }
|
||||
CC = { value = "clang" }
|
||||
|
||||
[tasks.build_afl]
|
||||
script_runner = "@shell"
|
||||
script = '''
|
||||
if [ ! -d "$AFL_DIR_NAME" ]; then
|
||||
if [ -f "v${AFL_VERSION}.zip" ]; then
|
||||
rm v${AFL_VERSION}.zip
|
||||
fi
|
||||
wget https://github.com/AFLplusplus/AFLplusplus/archive/${AFL_VERSION}.zip
|
||||
unzip ${AFL_VERSION}.zip
|
||||
cd ${AFL_DIR_NAME}
|
||||
if [ ! -d "$AFL_DIR" ]; then
|
||||
git clone https://github.com/AFLplusplus/AFLplusplus.git
|
||||
cd ${AFL_DIR}
|
||||
git checkout ${AFL_VERSION}
|
||||
LLVM_CONFIG=${LLVM_CONFIG} make
|
||||
cd frida_mode
|
||||
LLVM_CONFIG=${LLVM_CONFIG} make
|
||||
cd ../..
|
||||
fi
|
||||
|
||||
'''
|
||||
|
||||
[tasks.build_qemuafl]
|
||||
script_runner = "@shell"
|
||||
script = '''
|
||||
cd ${AFL_DIR}/qemu_mode
|
||||
./build_qemu_support.sh
|
||||
cd ../..
|
||||
'''
|
||||
dependencies = ["build_afl"]
|
||||
# Test
|
||||
[tasks.test]
|
||||
linux_alias = "test_unix"
|
||||
@ -43,14 +48,22 @@ windows_alias = "unsupported"
|
||||
[tasks.test_unix]
|
||||
script_runner = "@shell"
|
||||
script = "echo done"
|
||||
dependencies = ["build_afl", "test_instr", "test_cmplog", "test_frida"]
|
||||
dependencies = ["build_afl", "test_instr", "test_cmplog", "test_frida", "test_qemu"]
|
||||
|
||||
[tasks.build_libafl_fuzz]
|
||||
script_runner = "@shell"
|
||||
script = "cargo build --profile ${PROFILE}"
|
||||
|
||||
[tasks.test_instr]
|
||||
script_runner = "@shell"
|
||||
script = '''
|
||||
cargo build --profile ${PROFILE}
|
||||
AFL_PATH=${AFL_DIR_NAME} ${AFL_CC_PATH} ./test/test-instr.c -o ./test/out-instr
|
||||
LIBAFL_DEBUG_OUTPUT=1 AFL_CORES=1 AFL_STATS_INTERVAL=1 timeout 5 ${FUZZER} -i ./test/seeds -o ./test/output ./test/out-instr || true
|
||||
AFL_PATH=${AFL_DIR} ${AFL_CC_PATH} ./test/test-instr.c -o ./test/out-instr
|
||||
|
||||
export LIBAFL_DEBUG_OUTPUT=1
|
||||
export AFL_CORES=1
|
||||
export AFL_STATS_INTERVAL=1
|
||||
|
||||
timeout 5 ${FUZZER} -i ./test/seeds -o ./test/output ./test/out-instr || true
|
||||
test -n "$( ls ./test/output/fuzzer_main/queue/id:000002* 2>/dev/null )" || {
|
||||
echo "No new corpus entries found"
|
||||
exit 1
|
||||
@ -72,46 +85,50 @@ test -d "./test/output/fuzzer_main/crashes" || {
|
||||
exit 1
|
||||
}
|
||||
'''
|
||||
dependencies = ["build_afl"]
|
||||
dependencies = ["build_afl", "build_libafl_fuzz"]
|
||||
|
||||
[tasks.test_cmplog]
|
||||
script_runner = "@shell"
|
||||
script = '''
|
||||
cargo build --profile ${PROFILE}
|
||||
# cmplog TODO: AFL_BENCH_UNTIL_CRASH=1 instead of timeout 15s
|
||||
AFL_LLVM_CMPLOG=1 AFL_PATH=${AFL_DIR_NAME} ${AFL_CC_PATH} ./test/test-cmplog.c -o ./test/out-cmplog
|
||||
AFL_LLVM_CMPLOG=1 AFL_PATH=${AFL_DIR} ${AFL_CC_PATH} ./test/test-cmplog.c -o ./test/out-cmplog
|
||||
AFL_CORES=1 timeout 5 ${FUZZER} -Z -l 3 -m 0 -V30 -i ./test/seeds_cmplog -o ./test/output-cmplog -c 0 ./test/out-cmplog || true
|
||||
test -n "$( ls -A ./test/output-cmplog/fuzzer_main/crashes/)" || {
|
||||
echo "No crashes found"
|
||||
exit 1
|
||||
}
|
||||
'''
|
||||
dependencies = ["build_afl"]
|
||||
dependencies = ["build_afl", "build_libafl_fuzz"]
|
||||
|
||||
[tasks.test_frida]
|
||||
script_runner = "@shell"
|
||||
script = '''
|
||||
cargo build --profile ${PROFILE}
|
||||
${CC} -no-pie ./test/test-instr.c -o ./test/out-frida
|
||||
AFL_PATH=${AFL_DIR_NAME} AFL_CORES=1 AFL_STATS_INTERVAL=1 timeout 5 ${FUZZER} -m 0 -V07 -O -i ./test/seeds-frida -o ./test/output-frida -- ./test/out-frida || true
|
||||
|
||||
export AFL_PATH=${AFL_DIR}
|
||||
export AFL_CORES=1
|
||||
export AFL_STATS_INTERVAL=1
|
||||
|
||||
timeout 5 ${FUZZER} -m 0 -V07 -O -i ./test/seeds_frida -o ./test/output-frida -- ./test/out-frida || true
|
||||
test -n "$( ls ./test/output-frida/fuzzer_main/queue/id:000002* 2>/dev/null )" || {
|
||||
echo "No new corpus entries found for FRIDA mode"
|
||||
exit 1
|
||||
}
|
||||
|
||||
${CC} ./test/test-cmpcov.c -o ./test/out-frida-cmpcov
|
||||
AFL_PATH=${AFL_DIR_NAME} LIBAFL_DEBUG_OUTPUT=1 AFL_DEBUG=1 AFL_CORES=1 AFL_FRIDA_VERBOSE=1 timeout 10 ${FUZZER} -m 0 -V07 -O -c 0 -l 3 -i ./test/seeds-frida -o ./test/output-frida-cmpcov -- ./test/out-frida-cmpcov || true
|
||||
AFL_FRIDA_VERBOSE=1 timeout 10 ${FUZZER} -m 0 -V07 -O -c 0 -l 3 -i ./test/seeds_frida -o ./test/output-frida-cmpcov -- ./test/out-frida-cmpcov || true
|
||||
test -n "$( ls ./test/output-frida-cmpcov/fuzzer_main/queue/id:000003* 2>/dev/null )" || {
|
||||
echo "No new corpus entries found for FRIDA cmplog mode"
|
||||
exit 1
|
||||
}
|
||||
export AFL_FRIDA_PERSISTENT_ADDR=0x`nm ./test/out-frida | grep -Ei "T _main|T main" | awk '{print $1}'`
|
||||
AFL_PATH=${AFL_DIR_NAME} AFL_STATS_INTERVAL=1 AFL_CORES=1 timeout 5 ${FUZZER} -m 0 -V07 -O -i ./test/seeds-frida -o ./test/output-frida-persistent -- ./test/out-frida || true
|
||||
# TODO: change it to id:000003* once persistent mode is fixed
|
||||
timeout 5 ${FUZZER} -m 0 -V07 -O -i ./test/seeds_frida -o ./test/output-frida-persistent -- ./test/out-frida || true
|
||||
|
||||
test -n "$( ls ./test/output-frida-persistent/fuzzer_main/queue/id:000002* 2>/dev/null )" || {
|
||||
echo "No new corpus entries found for FRIDA persistent mode"
|
||||
exit 1
|
||||
}
|
||||
|
||||
RUNTIME_PERSISTENT=`grep execs_done ./test/output-frida-persistent/fuzzer_main/fuzzer_stats | awk '{print$3}'`
|
||||
RUNTIME=`grep execs_done ./test/output-frida/fuzzer_main/fuzzer_stats | awk '{print$3}'`
|
||||
test -n "$RUNTIME" -a -n "$RUNTIME_PERSISTENT" && {
|
||||
@ -125,8 +142,44 @@ test -n "$RUNTIME" -a -n "$RUNTIME_PERSISTENT" && {
|
||||
} || {
|
||||
echo "we got no data on executions performed? weird!"
|
||||
}
|
||||
|
||||
unset AFL_FRIDA_PERSISTENT_ADDR
|
||||
'''
|
||||
dependencies = ["build_afl"]
|
||||
dependencies = ["build_afl", "build_libafl_fuzz"]
|
||||
|
||||
[tasks.test_qemu]
|
||||
script_runner = "@shell"
|
||||
script = '''
|
||||
${CC} -pie -fPIE ./test/test-instr.c -o ./test/out-qemu
|
||||
${CC} -o ./test/out-qemu-cmpcov ./test/test-cmpcov.c
|
||||
|
||||
export AFL_PATH=${AFL_DIR}
|
||||
export AFL_CORES=1
|
||||
export AFL_STATS_INTERVAL=1
|
||||
|
||||
timeout 5 ${FUZZER} -m 0 -V07 -Q -i ./test/seeds_qemu -o ./test/output-qemu -- ./test/out-qemu || true
|
||||
test -n "$( ls ./test/output-qemu/fuzzer_main/queue/id:000002* 2>/dev/null )" || {
|
||||
echo "No new corpus entries found for QEMU mode"
|
||||
exit 1
|
||||
}
|
||||
|
||||
export AFL_ENTRYPOINT=`printf 1 | AFL_DEBUG=1 ${AFL_DIR}/afl-qemu-trace ./test/out-qemu 2>&1 >/dev/null | awk '/forkserver/{print $4; exit}'`
|
||||
timeout 5 ${FUZZER} -m 0 -V2 -Q -i ./test/seeds_qemu -o ./test/output-qemu-entrypoint -- ./test/out-qemu || true
|
||||
test -n "$( ls ./test/output-qemu-entrypoint/fuzzer_main/queue/id:000002* 2>/dev/null )" || {
|
||||
echo "No new corpus entries found for QEMU mode with AFL_ENTRYPOINT"
|
||||
exit 1
|
||||
}
|
||||
unset AFL_ENTRYPOINT
|
||||
|
||||
export AFL_PRELOAD=${AFL_DIR}/libcompcov.so
|
||||
export AFL_COMPCOV_LEVEL=2
|
||||
timeout 5 ${FUZZER} -V07 -Q -i ./test/seeds_qemu -o ./test/output-qemu-cmpcov -- ./test/out-qemu-cmpcov || true
|
||||
test -n "$( ls ./test/output-qemu-cmpcov/fuzzer_main/queue/id:000002* 2>/dev/null )" || {
|
||||
echo "No new corpus entries found for QEMU mode"
|
||||
exit 1
|
||||
}
|
||||
'''
|
||||
dependencies = ["build_afl", "build_qemuafl","build_libafl_fuzz"]
|
||||
|
||||
[tasks.clean]
|
||||
linux_alias = "clean_unix"
|
||||
@ -136,14 +189,12 @@ windows_alias = "unsupported"
|
||||
[tasks.clean_unix]
|
||||
script_runner = "@shell"
|
||||
script = '''
|
||||
rm -rf AFLplusplus-${AFL_VERSION}
|
||||
rm ${AFL_VERSION}.zip
|
||||
rm -rf AFLplusplus
|
||||
rm -rf ./test/out-instr
|
||||
rm -rf ./test/output
|
||||
rm -rf ./test/cmplog-output
|
||||
rm -rf ./test/output-frida
|
||||
rm -rf ./test/output-frida-cmpcov
|
||||
rm -rf ./test/output-frida-persistent
|
||||
rm -rf ./test/output-frida*
|
||||
rm -rf ./test/output-cmplog
|
||||
rm -rf ./test/output-qemu*
|
||||
rm ./test/out-*
|
||||
'''
|
||||
|
@ -117,7 +117,8 @@ pub fn check_binary(opt: &mut Opt, shmem_env_var: &str) -> Result<(), Error> {
|
||||
));
|
||||
}
|
||||
|
||||
if opt.forkserver_cs || opt.qemu_mode || opt.frida_mode && is_instrumented(&mmap, shmem_env_var)
|
||||
if (opt.forkserver_cs || opt.qemu_mode || opt.frida_mode)
|
||||
&& is_instrumented(&mmap, shmem_env_var)
|
||||
{
|
||||
return Err(Error::illegal_argument(
|
||||
"Instrumentation found in -Q/-O mode",
|
||||
|
@ -1,4 +1,4 @@
|
||||
use std::{borrow::Cow, marker::PhantomData, path::PathBuf, time::Duration};
|
||||
use std::{borrow::Cow, env, marker::PhantomData, path::PathBuf, time::Duration};
|
||||
|
||||
use libafl::{
|
||||
corpus::{CachedOnDiskCorpus, Corpus, OnDiskCorpus},
|
||||
@ -426,12 +426,26 @@ fn base_executor<'a>(
|
||||
if let Some(kill_signal) = opt.kill_signal {
|
||||
executor = executor.kill_signal(kill_signal);
|
||||
}
|
||||
if opt.is_persistent {
|
||||
if opt.is_persistent || opt.qemu_mode {
|
||||
executor = executor.shmem_provider(shmem_provider);
|
||||
}
|
||||
if let Some(harness_input_type) = &opt.harness_input_type {
|
||||
executor = executor.parse_afl_cmdline([harness_input_type]);
|
||||
}
|
||||
if opt.qemu_mode {
|
||||
let exec = opt.executable.display().to_string();
|
||||
executor = executor.program(
|
||||
find_afl_binary("afl-qemu-trace", Some(opt.executable.clone()))
|
||||
.expect("to find afl-qemu-trace"),
|
||||
);
|
||||
// we skip all libafl-fuzz arguments.
|
||||
let (skip, _) = env::args()
|
||||
.enumerate()
|
||||
.find(|i| i.1 == exec)
|
||||
.expect("invariant; should never occur");
|
||||
let args = env::args().skip(skip);
|
||||
executor = executor.args(args);
|
||||
}
|
||||
executor
|
||||
}
|
||||
|
||||
|
1
fuzzers/others/libafl-fuzz/test/seeds_frida/init
Normal file
1
fuzzers/others/libafl-fuzz/test/seeds_frida/init
Normal file
@ -0,0 +1 @@
|
||||
00000
|
1
fuzzers/others/libafl-fuzz/test/seeds_qemu/init
Normal file
1
fuzzers/others/libafl-fuzz/test/seeds_qemu/init
Normal file
@ -0,0 +1 @@
|
||||
00000
|
@ -53,12 +53,24 @@ const FS_NEW_ERROR: i32 = 0xeffe0000_u32 as i32;
|
||||
|
||||
const FS_NEW_VERSION_MIN: u32 = 1;
|
||||
const FS_NEW_VERSION_MAX: u32 = 1;
|
||||
|
||||
#[allow(clippy::cast_possible_wrap)]
|
||||
const FS_OPT_ENABLED: i32 = 0x80000001_u32 as i32;
|
||||
|
||||
#[allow(clippy::cast_possible_wrap)]
|
||||
const FS_NEW_OPT_MAPSIZE: i32 = 1_u32 as i32;
|
||||
#[allow(clippy::cast_possible_wrap)]
|
||||
const FS_OPT_MAPSIZE: i32 = 0x40000000_u32 as i32;
|
||||
|
||||
#[allow(clippy::cast_possible_wrap)]
|
||||
const FS_OPT_SHDMEM_FUZZ: i32 = 0x01000000_u32 as i32;
|
||||
#[allow(clippy::cast_possible_wrap)]
|
||||
const FS_NEW_OPT_SHDMEM_FUZZ: i32 = 2_u32 as i32;
|
||||
|
||||
#[allow(clippy::cast_possible_wrap)]
|
||||
const FS_NEW_OPT_AUTODICT: i32 = 0x00000800_u32 as i32;
|
||||
#[allow(clippy::cast_possible_wrap)]
|
||||
const FS_OPT_AUTODICT: i32 = 0x10000000_u32 as i32;
|
||||
|
||||
#[allow(clippy::cast_possible_wrap)]
|
||||
const FS_ERROR_MAP_SIZE: i32 = 1_u32 as i32;
|
||||
@ -280,6 +292,10 @@ impl Drop for Forkserver {
|
||||
}
|
||||
}
|
||||
|
||||
const fn fs_opt_get_mapsize(x: i32) -> i32 {
|
||||
((x & 0x00fffffe) >> 1) + 1
|
||||
}
|
||||
|
||||
#[allow(clippy::fn_params_excessive_bools)]
|
||||
impl Forkserver {
|
||||
/// Create a new [`Forkserver`]
|
||||
@ -343,7 +359,6 @@ impl Forkserver {
|
||||
};
|
||||
|
||||
let mut command = Command::new(target);
|
||||
|
||||
// Setup args, stdio
|
||||
command
|
||||
.args(args)
|
||||
@ -627,7 +642,10 @@ pub struct ForkserverExecutorBuilder<'a, SP> {
|
||||
crash_exitcode: Option<i8>,
|
||||
}
|
||||
|
||||
impl<'a, SP> ForkserverExecutorBuilder<'a, SP> {
|
||||
impl<'a, SP> ForkserverExecutorBuilder<'a, SP>
|
||||
where
|
||||
SP: ShMemProvider,
|
||||
{
|
||||
/// Builds `ForkserverExecutor`.
|
||||
/// This Forkserver will attempt to provide inputs over shared mem when `shmem_provider` is given.
|
||||
/// Else this forkserver will pass the input to the target via `stdin`
|
||||
@ -814,27 +832,47 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> {
|
||||
report_error_and_exit(version_status & 0x0000ffff)?;
|
||||
}
|
||||
|
||||
let keep = version_status;
|
||||
let version: u32 = version_status as u32 - 0x41464c00_u32;
|
||||
if (0x41464c00..=0x41464cff).contains(&version_status) {
|
||||
match version {
|
||||
0 => {
|
||||
return Err(Error::unknown("Fork server version is not assigned, this should not happen. Recompile target."));
|
||||
}
|
||||
FS_NEW_VERSION_MIN..=FS_NEW_VERSION_MAX => {
|
||||
// good, do nothing
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::unknown(
|
||||
"Fork server version is not supported. Recompile the target.",
|
||||
));
|
||||
}
|
||||
if Self::is_old_forkserver(version_status) {
|
||||
log::info!("Old fork server model is used by the target, this still works though.");
|
||||
self.initialize_old_forkserver(version_status, &map, &mut forkserver)?;
|
||||
} else {
|
||||
self.initialize_forkserver(version_status, &map, &mut forkserver)?;
|
||||
}
|
||||
Ok((forkserver, input_file, map))
|
||||
}
|
||||
|
||||
fn is_old_forkserver(version_status: i32) -> bool {
|
||||
!(0x41464c00..0x41464cff).contains(&version_status)
|
||||
}
|
||||
|
||||
/// Intialize forkserver > v4.20c
|
||||
#[allow(clippy::cast_possible_wrap)]
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
fn initialize_forkserver(
|
||||
&mut self,
|
||||
status: i32,
|
||||
map: &Option<SP::ShMem>,
|
||||
forkserver: &mut Forkserver,
|
||||
) -> Result<(), Error> {
|
||||
let keep = status;
|
||||
let version: u32 = status as u32 - 0x41464c00_u32;
|
||||
match version {
|
||||
0 => {
|
||||
return Err(Error::unknown("Fork server version is not assigned, this should not happen. Recompile target."));
|
||||
}
|
||||
FS_NEW_VERSION_MIN..=FS_NEW_VERSION_MAX => {
|
||||
// good, do nothing
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::unknown(
|
||||
"Fork server version is not supported. Recompile the target.",
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let xored_version_status = (version_status as u32 ^ 0xffffffff) as i32;
|
||||
let xored_status = (status as u32 ^ 0xffffffff) as i32;
|
||||
|
||||
let send_len = forkserver.write_ctl(xored_version_status)?;
|
||||
let send_len = forkserver.write_ctl(xored_status)?;
|
||||
if send_len != 4 {
|
||||
return Err(Error::unknown("Writing to forkserver failed.".to_string()));
|
||||
}
|
||||
@ -852,29 +890,13 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> {
|
||||
}
|
||||
|
||||
if status & FS_NEW_OPT_MAPSIZE == FS_NEW_OPT_MAPSIZE {
|
||||
// When 0, we assume that map_size was filled by the user or const
|
||||
/* TODO autofill map size from the observer
|
||||
|
||||
if map_size > 0 {
|
||||
self.map_size = Some(map_size as usize);
|
||||
}
|
||||
*/
|
||||
let (read_len, mut map_size) = forkserver.read_st()?;
|
||||
let (read_len, fsrv_map_size) = forkserver.read_st()?;
|
||||
if read_len != 4 {
|
||||
return Err(Error::unknown(
|
||||
"Failed to read map size from forkserver".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
if map_size % 64 != 0 {
|
||||
map_size = ((map_size + 63) >> 6) << 6;
|
||||
}
|
||||
|
||||
// TODO set AFL_MAP_SIZE
|
||||
assert!(self.map_size.is_none() || map_size as usize <= self.map_size.unwrap());
|
||||
|
||||
// we'll use this later when we truncate the observer
|
||||
self.map_size = Some(map_size as usize);
|
||||
self.set_map_size(fsrv_map_size);
|
||||
}
|
||||
|
||||
if status & FS_NEW_OPT_SHDMEM_FUZZ != 0 {
|
||||
@ -921,14 +943,111 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> {
|
||||
return Err(Error::unknown("Reading from forkserver failed".to_string()));
|
||||
}
|
||||
|
||||
if aflx != version_status {
|
||||
if aflx != keep {
|
||||
return Err(Error::unknown(format!(
|
||||
"Error in forkserver communication ({:x}=>{:x})",
|
||||
keep, aflx
|
||||
"Error in forkserver communication ({aflx:?}=>{keep:?})",
|
||||
)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Ok((forkserver, input_file, map))
|
||||
/// Intialize old forkserver. < v4.20c
|
||||
#[allow(clippy::cast_possible_wrap)]
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
fn initialize_old_forkserver(
|
||||
&mut self,
|
||||
status: i32,
|
||||
map: &Option<SP::ShMem>,
|
||||
forkserver: &mut Forkserver,
|
||||
) -> Result<(), Error> {
|
||||
if status & FS_OPT_ENABLED == FS_OPT_ENABLED && status & FS_OPT_MAPSIZE == FS_OPT_MAPSIZE {
|
||||
let fsrv_map_size = fs_opt_get_mapsize(status);
|
||||
self.set_map_size(fsrv_map_size);
|
||||
}
|
||||
|
||||
// Only with SHMEM or AUTODICT we can send send_status back or it breaks!
|
||||
// If forkserver is responding, we then check if there's any option enabled.
|
||||
// We'll send 4-bytes message back to the forkserver to tell which features to use
|
||||
// The forkserver is listening to our response if either shmem fuzzing is enabled or auto dict is enabled
|
||||
// <https://github.com/AFLplusplus/AFLplusplus/blob/147654f8715d237fe45c1657c87b2fe36c4db22a/instrumentation/afl-compiler-rt.o.c#L1026>
|
||||
if status & FS_OPT_ENABLED == FS_OPT_ENABLED
|
||||
&& (status & FS_OPT_SHDMEM_FUZZ == FS_OPT_SHDMEM_FUZZ
|
||||
|| status & FS_OPT_AUTODICT == FS_OPT_AUTODICT)
|
||||
{
|
||||
let mut send_status = FS_OPT_ENABLED;
|
||||
|
||||
if (status & FS_OPT_SHDMEM_FUZZ == FS_OPT_SHDMEM_FUZZ) && map.is_some() {
|
||||
log::info!("Using SHARED MEMORY FUZZING feature.");
|
||||
send_status |= FS_OPT_SHDMEM_FUZZ;
|
||||
self.uses_shmem_testcase = true;
|
||||
}
|
||||
|
||||
if (status & FS_OPT_AUTODICT == FS_OPT_AUTODICT) && self.autotokens.is_some() {
|
||||
log::info!("Using AUTODICT feature");
|
||||
send_status |= FS_OPT_AUTODICT;
|
||||
}
|
||||
|
||||
if send_status != FS_OPT_ENABLED {
|
||||
// if send_status is not changed (Options are available but we didn't use any), then don't send the next write_ctl message.
|
||||
// This is important
|
||||
|
||||
let send_len = forkserver.write_ctl(send_status)?;
|
||||
if send_len != 4 {
|
||||
return Err(Error::unknown("Writing to forkserver failed.".to_string()));
|
||||
}
|
||||
|
||||
if (send_status & FS_OPT_AUTODICT) == FS_OPT_AUTODICT {
|
||||
let (read_len, dict_size) = forkserver.read_st()?;
|
||||
if read_len != 4 {
|
||||
return Err(Error::unknown(
|
||||
"Reading from forkserver failed.".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
if !(2..=0xffffff).contains(&dict_size) {
|
||||
return Err(Error::illegal_state(
|
||||
"Dictionary has an illegal size".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
log::info!("Autodict size {dict_size:x}");
|
||||
|
||||
let (rlen, buf) = forkserver.read_st_size(dict_size as usize)?;
|
||||
|
||||
if rlen != dict_size as usize {
|
||||
return Err(Error::unknown("Failed to load autodictionary".to_string()));
|
||||
}
|
||||
if let Some(t) = &mut self.autotokens {
|
||||
t.parse_autodict(&buf, dict_size as usize);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log::warn!("Forkserver Options are not available.");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
fn set_map_size(&mut self, fsrv_map_size: i32) {
|
||||
// When 0, we assume that map_size was filled by the user or const
|
||||
/* TODO autofill map size from the observer
|
||||
|
||||
if fsrv_map_size > 0 {
|
||||
self.map_size = Some(fsrv_map_size as usize);
|
||||
}
|
||||
*/
|
||||
let mut map_size = fsrv_map_size;
|
||||
if map_size % 64 != 0 {
|
||||
map_size = ((map_size + 63) >> 6) << 6;
|
||||
}
|
||||
|
||||
// TODO set AFL_MAP_SIZE
|
||||
assert!(self.map_size.is_none() || map_size as usize <= self.map_size.unwrap());
|
||||
|
||||
// we'll use this later when we truncate the observer
|
||||
self.map_size = Some(map_size as usize);
|
||||
}
|
||||
|
||||
/// Use autodict?
|
||||
|
Loading…
x
Reference in New Issue
Block a user