mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-11 09:41:35 +00:00
add AFL_OLD_FORKSERVER feature
This commit is contained in:
parent
f6bfa96a96
commit
50ae95cee4
@ -20,6 +20,10 @@
|
||||
- AFL_FRIDA_DEBUG_MAPS now works as expected
|
||||
- custom mutators:
|
||||
- custom_send_tcp custom mutator added, thanks to @dergoegge
|
||||
- afl-cc
|
||||
- new runtime (!) variable: `AFL_OLD_FORKSERVER` to use the old vanilla
|
||||
AFL type forkserver. Useful for symcc/symqemu/nautilus/etc. with
|
||||
AFL_LLVM_INSTRUMENT=CLASSIC
|
||||
|
||||
|
||||
### Version ++4.21c (release)
|
||||
|
@ -331,7 +331,26 @@ mode.
|
||||
the target performs only a few loops, then this will give a small
|
||||
performance boost.
|
||||
|
||||
## 4) Settings for afl-fuzz
|
||||
## 4) Runtime settings
|
||||
|
||||
The following environment variables are for a compiled AFL++ target.
|
||||
|
||||
- Setting `AFL_DUMP_MAP_SIZE` when executing the target directly will
|
||||
dump the map size of the target and exit.
|
||||
|
||||
- Setting `AFL_OLD_FORKSERVER` will use the old AFL vanilla forkserver.
|
||||
This makes only sense when you
|
||||
a) compile in a classic colliding coverage mode (e.g.
|
||||
AFL_LLVM_INSTRUMENT=CLASSIC) or if the map size of the target is
|
||||
below MAP_SIZE (65536 by default), AND
|
||||
b) you want to use this compiled AFL++ target with a different tool
|
||||
that expects vanilla AFL behaviour, e.g. symcc, symqemu, nautilus, etc.
|
||||
You would use this option together with the target fuzzing application.
|
||||
|
||||
- Setting `AFL_DISABLE_LLVM_INSTRUMENTATION` will disable collecting
|
||||
instrumentation. (More of an internal option.)
|
||||
|
||||
## 5) Settings for afl-fuzz
|
||||
|
||||
The main fuzzer binary accepts several options that disable a couple of sanity
|
||||
checks or alter some of the more exotic semantics of the tool:
|
||||
@ -642,7 +661,7 @@ checks or alter some of the more exotic semantics of the tool:
|
||||
Note that will not be exact and with slow targets it can take seconds
|
||||
until there is a slice for the time test.
|
||||
|
||||
## 5) Settings for afl-qemu-trace
|
||||
## 6) Settings for afl-qemu-trace
|
||||
|
||||
The QEMU wrapper used to instrument binary-only code supports several settings:
|
||||
|
||||
@ -714,7 +733,7 @@ The QEMU wrapper used to instrument binary-only code supports several settings:
|
||||
crash is found. Setting `AFL_NO_CRASH_README` will prevent this. Useful when
|
||||
counting crashes based on a file count in that directory.
|
||||
|
||||
## 7) Settings for afl-frida-trace
|
||||
## 8) Settings for afl-frida-trace
|
||||
|
||||
The FRIDA wrapper used to instrument binary-only code supports many of the same
|
||||
options as `afl-qemu-trace`, but also has a number of additional advanced
|
||||
@ -804,7 +823,7 @@ support.
|
||||
dump you must set a sufficient timeout (using `-t`) to avoid `afl-fuzz`
|
||||
killing the process whilst it is being dumped.
|
||||
|
||||
## 8) Settings for afl-cmin
|
||||
## 9) Settings for afl-cmin
|
||||
|
||||
The corpus minimization script offers very little customization:
|
||||
|
||||
@ -822,7 +841,7 @@ The corpus minimization script offers very little customization:
|
||||
- `AFL_PRINT_FILENAMES` prints each filename to stdout, as it gets processed.
|
||||
This can help when embedding `afl-cmin` or `afl-showmap` in other scripts.
|
||||
|
||||
## 9) Settings for afl-tmin
|
||||
## 10) Settings for afl-tmin
|
||||
|
||||
Virtually nothing to play with. Well, in QEMU mode (`-Q`), `AFL_PATH` will be
|
||||
searched for afl-qemu-trace. In addition to this, `TMPDIR` may be used if a
|
||||
@ -833,12 +852,12 @@ to match when minimizing crashes. This will make minimization less useful, but
|
||||
may prevent the tool from "jumping" from one crashing condition to another in
|
||||
very buggy software. You probably want to combine it with the `-e` flag.
|
||||
|
||||
## 10) Settings for afl-analyze
|
||||
## 11) Settings for afl-analyze
|
||||
|
||||
You can set `AFL_ANALYZE_HEX` to get file offsets printed as hexadecimal instead
|
||||
of decimal.
|
||||
|
||||
## 11) Settings for libdislocator
|
||||
## 12) Settings for libdislocator
|
||||
|
||||
The library honors these environment variables:
|
||||
|
||||
@ -860,12 +879,12 @@ The library honors these environment variables:
|
||||
- `AFL_LD_VERBOSE` causes the library to output some diagnostic messages that
|
||||
may be useful for pinpointing the cause of any observed issues.
|
||||
|
||||
## 11) Settings for libtokencap
|
||||
## 13) Settings for libtokencap
|
||||
|
||||
This library accepts `AFL_TOKEN_FILE` to indicate the location to which the
|
||||
discovered tokens should be written.
|
||||
|
||||
## 12) Third-party variables set by afl-fuzz & other tools
|
||||
## 14) Third-party variables set by afl-fuzz & other tools
|
||||
|
||||
Several variables are not directly interpreted by afl-fuzz, but are set to
|
||||
optimal values if not already present in the environment:
|
||||
|
@ -40,8 +40,7 @@ static char *afl_environment_variables[] = {
|
||||
"AFL_FRIDA_INST_INSN", "AFL_FRIDA_INST_JIT", "AFL_FRIDA_INST_NO_CACHE",
|
||||
"AFL_FRIDA_INST_NO_DYNAMIC_LOAD", "AFL_FRIDA_INST_NO_OPTIMIZE",
|
||||
"AFL_FRIDA_INST_NO_PREFETCH", "AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH",
|
||||
"AFL_FRIDA_INST_NO_SUPPRESS"
|
||||
"AFL_FRIDA_INST_RANGES",
|
||||
"AFL_FRIDA_INST_NO_SUPPRESS", "AFL_FRIDA_INST_RANGES",
|
||||
"AFL_FRIDA_INST_REGS_FILE", "AFL_FRIDA_INST_SEED", "AFL_FRIDA_INST_TRACE",
|
||||
"AFL_FRIDA_INST_TRACE_UNIQUE", "AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE",
|
||||
"AFL_FRIDA_JS_SCRIPT", "AFL_FRIDA_OUTPUT_STDOUT", "AFL_FRIDA_OUTPUT_STDERR",
|
||||
@ -50,7 +49,7 @@ static char *afl_environment_variables[] = {
|
||||
"AFL_FRIDA_PERSISTENT_RET", "AFL_FRIDA_STALKER_ADJACENT_BLOCKS",
|
||||
"AFL_FRIDA_STALKER_IC_ENTRIES", "AFL_FRIDA_STALKER_NO_BACKPATCH",
|
||||
"AFL_FRIDA_STATS_FILE", "AFL_FRIDA_STATS_INTERVAL", "AFL_FRIDA_TRACEABLE",
|
||||
"AFL_FRIDA_VERBOSE",
|
||||
"AFL_FRIDA_VERBOSE", "AFL_OLD_FORKSERVER",
|
||||
"AFL_FUZZER_ARGS", // oss-fuzz
|
||||
"AFL_FUZZER_STATS_UPDATE_INTERVAL", "AFL_GDB", "AFL_GCC_ALLOWLIST",
|
||||
"AFL_GCC_DENYLIST", "AFL_GCC_BLOCKLIST", "AFL_GCC_INSTRUMENT_FILE",
|
||||
|
@ -118,6 +118,7 @@ u32 __afl_map_size = MAP_SIZE;
|
||||
u32 __afl_dictionary_len;
|
||||
u64 __afl_map_addr;
|
||||
u32 __afl_first_final_loc;
|
||||
u32 __afl_old_forkserver;
|
||||
|
||||
#ifdef __AFL_CODE_COVERAGE
|
||||
typedef struct afl_module_info_t afl_module_info_t;
|
||||
@ -616,7 +617,7 @@ static void __afl_map_shm(void) {
|
||||
fprintf(stderr,
|
||||
"DEBUG: (2) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, "
|
||||
"__afl_area_ptr_dummy %p, __afl_map_addr 0x%llx, MAP_SIZE "
|
||||
"%u, __afl_final_loc %u, __afl_map_size %u",
|
||||
"%u, __afl_final_loc %u, __afl_map_size %u\n",
|
||||
id_str == NULL ? "<null>" : id_str, __afl_area_ptr,
|
||||
__afl_area_initial, __afl_area_ptr_dummy, __afl_map_addr, MAP_SIZE,
|
||||
__afl_final_loc, __afl_map_size);
|
||||
@ -856,7 +857,7 @@ static void __afl_start_forkserver(void) {
|
||||
signal(SIGTERM, at_exit);
|
||||
|
||||
u32 already_read_first = 0;
|
||||
u32 was_killed;
|
||||
u32 was_killed = 0;
|
||||
u32 version = 0x41464c00 + FS_NEW_VERSION_MAX;
|
||||
u32 tmp = version ^ 0xffffffff, status2, status = version;
|
||||
u8 *msg = (u8 *)&status;
|
||||
@ -866,75 +867,95 @@ static void __afl_start_forkserver(void) {
|
||||
|
||||
void (*old_sigchld_handler)(int) = signal(SIGCHLD, SIG_DFL);
|
||||
|
||||
if (getenv("AFL_OLD_FORKSERVER")) {
|
||||
|
||||
__afl_old_forkserver = 1;
|
||||
status = 0;
|
||||
|
||||
if (__afl_final_loc && __afl_final_loc > MAP_SIZE) {
|
||||
|
||||
fprintf(stderr,
|
||||
"Warning: AFL_OLD_FORKSERVER is used with a target compiled with "
|
||||
"non-colliding coverage instead of AFL_LLVM_INSTRUMENT=CLASSIC - "
|
||||
"this target may crash!\n");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Phone home and tell the parent that we're OK. If parent isn't there,
|
||||
assume we're not running in forkserver mode and just execute program. */
|
||||
|
||||
// return because possible non-forkserver usage
|
||||
if (write(FORKSRV_FD + 1, msg, 4) != 4) { return; }
|
||||
|
||||
if (read(FORKSRV_FD, reply, 4) != 4) { _exit(1); }
|
||||
if (tmp != status2) {
|
||||
if (!__afl_old_forkserver) {
|
||||
|
||||
write_error("wrong forkserver message from AFL++ tool");
|
||||
_exit(1);
|
||||
if (read(FORKSRV_FD, reply, 4) != 4) { _exit(1); }
|
||||
if (tmp != status2) {
|
||||
|
||||
}
|
||||
|
||||
// send the set/requested options to forkserver
|
||||
status = FS_NEW_OPT_MAPSIZE; // we always send the map size
|
||||
if (__afl_sharedmem_fuzzing) { status |= FS_NEW_OPT_SHDMEM_FUZZ; }
|
||||
if (__afl_dictionary_len && __afl_dictionary) {
|
||||
|
||||
status |= FS_NEW_OPT_AUTODICT;
|
||||
|
||||
}
|
||||
|
||||
if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); }
|
||||
|
||||
// Now send the parameters for the set options, increasing by option number
|
||||
|
||||
// FS_NEW_OPT_MAPSIZE - we always send the map size
|
||||
status = __afl_map_size;
|
||||
if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); }
|
||||
|
||||
// FS_NEW_OPT_SHDMEM_FUZZ - no data
|
||||
|
||||
// FS_NEW_OPT_AUTODICT - send autodictionary
|
||||
if (__afl_dictionary_len && __afl_dictionary) {
|
||||
|
||||
// pass the dictionary through the forkserver FD
|
||||
u32 len = __afl_dictionary_len, offset = 0;
|
||||
|
||||
if (write(FORKSRV_FD + 1, &len, 4) != 4) {
|
||||
|
||||
write(2, "Error: could not send dictionary len\n",
|
||||
strlen("Error: could not send dictionary len\n"));
|
||||
write_error("wrong forkserver message from AFL++ tool");
|
||||
_exit(1);
|
||||
|
||||
}
|
||||
|
||||
while (len != 0) {
|
||||
// send the set/requested options to forkserver
|
||||
status = FS_NEW_OPT_MAPSIZE; // we always send the map size
|
||||
if (__afl_sharedmem_fuzzing) { status |= FS_NEW_OPT_SHDMEM_FUZZ; }
|
||||
if (__afl_dictionary_len && __afl_dictionary) {
|
||||
|
||||
s32 ret;
|
||||
ret = write(FORKSRV_FD + 1, __afl_dictionary + offset, len);
|
||||
status |= FS_NEW_OPT_AUTODICT;
|
||||
|
||||
if (ret < 1) {
|
||||
}
|
||||
|
||||
write_error("could not send dictionary");
|
||||
if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); }
|
||||
|
||||
// Now send the parameters for the set options, increasing by option number
|
||||
|
||||
// FS_NEW_OPT_MAPSIZE - we always send the map size
|
||||
status = __afl_map_size;
|
||||
if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); }
|
||||
|
||||
// FS_NEW_OPT_SHDMEM_FUZZ - no data
|
||||
|
||||
// FS_NEW_OPT_AUTODICT - send autodictionary
|
||||
if (__afl_dictionary_len && __afl_dictionary) {
|
||||
|
||||
// pass the dictionary through the forkserver FD
|
||||
u32 len = __afl_dictionary_len, offset = 0;
|
||||
|
||||
if (write(FORKSRV_FD + 1, &len, 4) != 4) {
|
||||
|
||||
write(2, "Error: could not send dictionary len\n",
|
||||
strlen("Error: could not send dictionary len\n"));
|
||||
_exit(1);
|
||||
|
||||
}
|
||||
|
||||
len -= ret;
|
||||
offset += ret;
|
||||
while (len != 0) {
|
||||
|
||||
s32 ret;
|
||||
ret = write(FORKSRV_FD + 1, __afl_dictionary + offset, len);
|
||||
|
||||
if (ret < 1) {
|
||||
|
||||
write_error("could not send dictionary");
|
||||
_exit(1);
|
||||
|
||||
}
|
||||
|
||||
len -= ret;
|
||||
offset += ret;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// send welcome message as final message
|
||||
status = version;
|
||||
if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); }
|
||||
|
||||
// send welcome message as final message
|
||||
status = version;
|
||||
if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); }
|
||||
}
|
||||
|
||||
// END forkserver handshake
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user