add AFL_EARLY_FORKSERVER support
MODIFY
docs/Changelog.md
docs/Changelog.md
@@ -17,6 +17,9 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- reintroduced AFL_PERSISTENT and AFL_DEFER_FORKSRV to allow
persistent mode and manual forkserver support if these are not
in the target binary (e.g. are in a shared library)
+ - add AFL_EARY_FORKSERVER to install the forkserver as earliest as
+ possible in the target (for afl-gcc-fast/afl-clang-fast/
+ afl-clang-lto)
- frida_mode:
- update to new frida release, handles now c++ throw/catch

MODIFY
docs/env_variables.md
docs/env_variables.md
@@ -540,6 +540,10 @@ checks or alter some of the more exotic semantics of the tool:
- `AFL_PERSISTENT` enforces persistent mode even if none was detected
in the target binary
+ - If you need an early forkserver in your target because of early
+ constructors in your target you can set `AFL_EARLY_FORKSERVER`.
+ Note that is is not a compile time option but a runtime option :-)
+
## 5) Settings for afl-qemu-trace
The QEMU wrapper used to instrument binary-only code supports several settings:

MODIFY
include/envs.h
include/envs.h
@@ -47,6 +47,7 @@ static char *afl_environment_variables[] = {
"AFL_DONT_OPTIMIZE",
"AFL_DRIVER_STDERR_DUPLICATE_FILENAME",
"AFL_DUMB_FORKSRV",
+ "AFL_EARLY_FORKSERVER",
"AFL_ENTRYPOINT",
"AFL_EXIT_WHEN_DONE",
"AFL_EXIT_ON_TIME",

MODIFY
instrumentation/afl-compiler-rt.o.c
instrumentation/afl-compiler-rt.o.c
#endif
#define CTOR_PRIO 3
+#define EARLY_FS_PRIO 5
#include <sys/mman.h>
#include <fcntl.h>
@@ -145,6 +146,7 @@ u32 __afl_already_initialized_shm;
u32 __afl_already_initialized_forkserver;
u32 __afl_already_initialized_first;
u32 __afl_already_initialized_second;
+u32 __afl_already_initialized_init;
/* Dummy pipe for area_is_valid() */
@@ -1253,6 +1255,8 @@ void __afl_manual_init(void) {
__attribute__((constructor())) void __afl_auto_init(void) {
+ if (__afl_already_initialized_init) { return; }
+
#ifdef __ANDROID__
// Disable handlers in linker/debuggerd, check include/debuggerd/handler.h
signal(SIGABRT, SIG_DFL);
@@ -1265,6 +1269,8 @@ __attribute__((constructor())) void __afl_auto_init(void) {
signal(SIGTRAP, SIG_DFL);
#endif
+ __afl_already_initialized_init = 1;
+
if (getenv("AFL_DISABLE_LLVM_INSTRUMENTATION")) return;
if (getenv(DEFER_ENV_VAR)) return;
@@ -1273,6 +1279,14 @@ __attribute__((constructor())) void __afl_auto_init(void) {
}
+/* Optionally run an early forkserver */
+
+__attribute__((constructor(EARLY_FS_PRIO))) void __early_forkserver(void) {
+
+ if (getenv("AFL_EARLY_FORKSERVER")) { __afl_auto_init(); }
+
+}
+
/* Initialization of the shmem - earliest possible because of LTO fixed mem. */
__attribute__((constructor(CTOR_PRIO))) void __afl_auto_early(void) {

MODIFY
src/afl-fuzz.c
src/afl-fuzz.c
@@ -294,6 +294,8 @@ static void usage(u8 *argv0, int more_help) {
" 'signalfx' and 'influxdb'\n"
"AFL_TESTCACHE_SIZE: use a cache for testcases, improves performance (in MB)\n"
"AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n"
+ "AFL_EARLY_FORKSERVER: force an early forkserver in an afl-clang-fast/\n"
+ " afl-clang-lto/afl-gcc-fast target\n"
"AFL_PERSISTENT: enforce persistent mode (if __AFL_LOOP is in a shared lib\n"
"AFL_DEFER_FORKSRV: enforced deferred forkserver (__AFL_INIT is in a .so\n"
"\n"

add AFL_EARLY_FORKSERVER support