about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--docs/Changelog.md3
-rw-r--r--docs/env_variables.md4
-rw-r--r--include/envs.h1
-rw-r--r--instrumentation/afl-compiler-rt.o.c14
-rw-r--r--src/afl-fuzz.c2
5 files changed, 24 insertions, 0 deletions
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 142b85b3..f4ae0e43 100644
--- a/docs/Changelog.md
+++ b/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
 
diff --git a/docs/env_variables.md b/docs/env_variables.md
index 06c08f31..4fa3f051 100644
--- a/docs/env_variables.md
+++ b/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:
diff --git a/include/envs.h b/include/envs.h
index 538ea3a8..f4327d8c 100644
--- a/include/envs.h
+++ b/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",
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 9a12831e..db7ac7b0 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -68,6 +68,7 @@
 #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) {
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index c923cc9d..c73ab38b 100644
--- a/src/afl-fuzz.c
+++ b/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"