about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/afl-cc.c91
-rw-r--r--src/afl-common.c16
-rw-r--r--src/afl-forkserver.c21
-rw-r--r--src/afl-fuzz-bitmap.c2
-rw-r--r--src/afl-fuzz-cmplog.c2
-rw-r--r--src/afl-fuzz-init.c19
-rw-r--r--src/afl-fuzz-mutators.c2
-rw-r--r--src/afl-fuzz-run.c35
-rw-r--r--src/afl-fuzz-state.c16
-rw-r--r--src/afl-fuzz.c41
10 files changed, 169 insertions, 76 deletions
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 9197c74b..ed57ca1e 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -315,7 +315,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
   u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0, shared_linking = 0,
      preprocessor_only = 0, have_unroll = 0, have_o = 0, have_pic = 0,
-     have_c = 0, partial_linking = 0;
+     have_c = 0, partial_linking = 0, wasm_linking = 0;
 
   cc_params = ck_alloc((argc + 128) * sizeof(u8 *));
 
@@ -671,22 +671,6 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
     // cc_params[cc_par_cnt++] = "-Qunused-arguments";
 
-    // in case LLVM is installed not via a package manager or "make install"
-    // e.g. compiled download or compiled from github then its ./lib directory
-    // might not be in the search path. Add it if so.
-    u8 *libdir = strdup(LLVM_LIBDIR);
-    if (plusplus_mode && strlen(libdir) && strncmp(libdir, "/usr", 4) &&
-        strncmp(libdir, "/lib", 4)) {
-
-      cc_params[cc_par_cnt++] = "-rpath";
-      cc_params[cc_par_cnt++] = libdir;
-
-    } else {
-
-      free(libdir);
-
-    }
-
     if (lto_mode && argc > 1) {
 
       u32 idx;
@@ -766,14 +750,21 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
       u8 *afllib = find_object("libAFLDriver.a", argv[0]);
 
-      if (!be_quiet)
+      if (!be_quiet) {
+
         OKF("Found '-fsanitize=fuzzer', replacing with libAFLDriver.a");
 
+      }
+
       if (!afllib) {
 
-        WARNF(
-            "Cannot find 'libAFLDriver.a' to replace '-fsanitize=fuzzer' in "
-            "the flags - this will fail!");
+        if (!be_quiet) {
+
+          WARNF(
+              "Cannot find 'libAFLDriver.a' to replace '-fsanitize=fuzzer' in "
+              "the flags - this will fail!");
+
+        }
 
       } else {
 
@@ -806,6 +797,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
     if (!strcmp(cur, "-E")) preprocessor_only = 1;
     if (!strcmp(cur, "-shared")) shared_linking = 1;
     if (!strcmp(cur, "-dynamiclib")) shared_linking = 1;
+    if (!strcmp(cur, "--target=wasm32-wasi")) wasm_linking = 1;
     if (!strcmp(cur, "-Wl,-r")) partial_linking = 1;
     if (!strcmp(cur, "-Wl,-i")) partial_linking = 1;
     if (!strcmp(cur, "-Wl,--relocatable")) partial_linking = 1;
@@ -820,6 +812,22 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
   }
 
+  // in case LLVM is installed not via a package manager or "make install"
+  // e.g. compiled download or compiled from github then its ./lib directory
+  // might not be in the search path. Add it if so.
+  u8 *libdir = strdup(LLVM_LIBDIR);
+  if (plusplus_mode && !wasm_linking && strlen(libdir) &&
+      strncmp(libdir, "/usr", 4) && strncmp(libdir, "/lib", 4)) {
+
+    cc_params[cc_par_cnt++] = "-rpath";
+    cc_params[cc_par_cnt++] = libdir;
+
+  } else {
+
+    free(libdir);
+
+  }
+
   if (getenv("AFL_HARDEN")) {
 
     cc_params[cc_par_cnt++] = "-fstack-protector-all";
@@ -923,7 +931,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
   }
 
-#if defined(USEMMAP) && !defined(__HAIKU__)
+#if defined(USEMMAP) && !defined(__HAIKU__) && !__APPLE__
   if (!have_c) cc_params[cc_par_cnt++] = "-lrt";
 #endif
 
@@ -1056,7 +1064,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
     switch (bit_mode) {
 
       case 0:
-        if (!shared_linking && !partial_linking)
+        if (!shared_linking && !partial_linking && !wasm_linking)
           cc_params[cc_par_cnt++] =
               alloc_printf("%s/afl-compiler-rt.o", obj_path);
         if (lto_mode)
@@ -1065,7 +1073,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
         break;
 
       case 32:
-        if (!shared_linking && !partial_linking) {
+        if (!shared_linking && !partial_linking && !wasm_linking) {
 
           cc_params[cc_par_cnt++] =
               alloc_printf("%s/afl-compiler-rt-32.o", obj_path);
@@ -1086,7 +1094,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
         break;
 
       case 64:
-        if (!shared_linking && !partial_linking) {
+        if (!shared_linking && !partial_linking && !wasm_linking) {
 
           cc_params[cc_par_cnt++] =
               alloc_printf("%s/afl-compiler-rt-64.o", obj_path);
@@ -1109,7 +1117,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
     }
 
   #if !defined(__APPLE__) && !defined(__sun)
-    if (!shared_linking && !partial_linking)
+    if (!shared_linking && !partial_linking && !wasm_linking)
       cc_params[cc_par_cnt++] =
           alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path);
   #endif
@@ -1128,7 +1136,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
   }
 
-  #if defined(USEMMAP) && !defined(__HAIKU__)
+  #if defined(USEMMAP) && !defined(__HAIKU__) && !__APPLE__
   cc_params[cc_par_cnt++] = "-lrt";
   #endif
 
@@ -1248,10 +1256,14 @@ int main(int argc, char **argv, char **envp) {
 
     if (compiler_mode) {
 
-      WARNF(
-          "\"AFL_CC_COMPILER\" is set but a specific compiler was already "
-          "selected by command line parameter or symlink, ignoring the "
-          "environment variable!");
+      if (!be_quiet) {
+
+        WARNF(
+            "\"AFL_CC_COMPILER\" is set but a specific compiler was already "
+            "selected by command line parameter or symlink, ignoring the "
+            "environment variable!");
+
+      }
 
     } else {
 
@@ -1304,11 +1316,14 @@ int main(int argc, char **argv, char **envp) {
 
       }
 
-      if (compiler_mode)
+      if (compiler_mode && !be_quiet) {
+
         WARNF(
             "--afl-... compiler mode supersedes the AFL_CC_COMPILER and "
             "symlink compiler selection!");
 
+      }
+
       ptr = argv[i];
       ptr += 5;
       while (*ptr == '-')
@@ -1390,7 +1405,7 @@ int main(int argc, char **argv, char **envp) {
 
   }
 
-  if (have_instr_env && getenv("AFL_DONT_OPTIMIZE")) {
+  if (have_instr_env && getenv("AFL_DONT_OPTIMIZE") && !be_quiet) {
 
     WARNF(
         "AFL_LLVM_ALLOWLIST/DENYLIST and AFL_DONT_OPTIMIZE cannot be combined "
@@ -1970,10 +1985,13 @@ int main(int argc, char **argv, char **envp) {
 
     } else {
 
-      if (!be_quiet)
+      if (!be_quiet) {
+
         WARNF("afl-clang-lto called with mode %s, using that mode instead",
               instrument_mode_string[instrument_mode]);
 
+      }
+
     }
 
   }
@@ -1985,11 +2003,14 @@ int main(int argc, char **argv, char **envp) {
     if (have_instr_env) {
 
       instrument_mode = INSTRUMENT_AFL;
-      if (!be_quiet)
+      if (!be_quiet) {
+
         WARNF(
             "Switching to classic instrumentation because "
             "AFL_LLVM_ALLOWLIST/DENYLIST does not work with PCGUARD < 10.0.1.");
 
+      }
+
     } else
 
   #endif
diff --git a/src/afl-common.c b/src/afl-common.c
index 7ba3bb74..7c074acc 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -71,11 +71,9 @@ u32 check_binary_signatures(u8 *fn) {
 
   } else if (getenv("AFL_PERSISTENT")) {
 
-    if (!be_quiet) {
-
-      WARNF("AFL_PERSISTENT is no longer supported and may misbehave!");
-
-    }
+    if (!be_quiet) { OKF(cPIN "Persistent mode enforced."); }
+    setenv(PERSIST_ENV_VAR, "1", 1);
+    ret = 1;
 
   } else if (getenv("AFL_FRIDA_PERSISTENT_ADDR")) {
 
@@ -98,11 +96,9 @@ u32 check_binary_signatures(u8 *fn) {
 
   } else if (getenv("AFL_DEFER_FORKSRV")) {
 
-    if (!be_quiet) {
-
-      WARNF("AFL_DEFER_FORKSRV is no longer supported and may misbehave!");
-
-    }
+    if (!be_quiet) { OKF(cPIN "Deferred forkserver enforced."); }
+    setenv(DEFER_ENV_VAR, "1", 1);
+    ret += 2;
 
   }
 
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index ce554170..8997781d 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -59,7 +59,11 @@ static list_t fsrv_list = {.element_prealloc_count = 0};
 
 static void fsrv_exec_child(afl_forkserver_t *fsrv, char **argv) {
 
-  if (fsrv->qemu_mode) { setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); }
+  if (fsrv->qemu_mode || fsrv->cs_mode) {
+
+    setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0);
+
+  }
 
   execv(fsrv->target_path, argv);
 
@@ -281,13 +285,13 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) {
       sigaction(SIGPIPE, &sa, NULL);
 
       signal(SIGCHLD, old_sigchld_handler);
+
       // FORKSRV_FD is for communication with AFL, we don't need it in the
-      // child.
+      // child
       close(FORKSRV_FD);
       close(FORKSRV_FD + 1);
 
-      // TODO: exec...
-
+      // finally: exec...
       execv(fsrv->target_path, argv);
 
       /* Use a distinctive bitmap signature to tell the parent about execv()
@@ -567,6 +571,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
     }
 
+    if (!be_quiet) { ACTF("Using AFL++ faux forkserver..."); }
     fsrv->init_child_func = afl_fauxsrv_execv;
 
   }
@@ -1265,7 +1270,8 @@ u32 afl_fsrv_get_mapsize(afl_forkserver_t *fsrv, char **argv,
 
 /* Delete the current testcase and write the buf to the testcase file */
 
-void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
+void __attribute__((hot))
+afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
 
 #ifdef __linux__
   if (unlikely(fsrv->nyx_mode)) {
@@ -1383,8 +1389,9 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
 /* Execute target application, monitoring for timeouts. Return status
    information. The called program will update afl->fsrv->trace_bits. */
 
-fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
-                                      volatile u8 *stop_soon_p) {
+fsrv_run_result_t __attribute__((hot))
+afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
+                    volatile u8 *stop_soon_p) {
 
   s32 res;
   u32 exec_ms;
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 8d044959..b963caf8 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -633,7 +633,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
       if (afl->fsrv.exec_tmout < afl->hang_tmout) {
 
         u8 new_fault;
-        write_to_testcase(afl, mem, len);
+        len = write_to_testcase(afl, mem, len, 0);
         new_fault = fuzz_run_target(afl, &afl->fsrv, afl->hang_tmout);
         classify_counts(&afl->fsrv);
 
diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c
index ce8f1a83..1a8052a0 100644
--- a/src/afl-fuzz-cmplog.c
+++ b/src/afl-fuzz-cmplog.c
@@ -49,7 +49,7 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
 
   u8 fault;
 
-  write_to_testcase(afl, out_buf, len);
+  len = write_to_testcase(afl, out_buf, len, 0);
 
   fault = fuzz_run_target(afl, &afl->cmplog_fsrv, afl->fsrv.exec_tmout);
 
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 5449460e..05a654c8 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -617,11 +617,10 @@ void read_foreign_testcases(afl_state_t *afl, int first) {
 
         }
 
-        write_to_testcase(afl, mem, st.st_size);
+        u32 len = write_to_testcase(afl, mem, st.st_size, 1);
         fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
         afl->syncing_party = foreign_name;
-        afl->queued_imported +=
-            save_if_interesting(afl, mem, st.st_size, fault);
+        afl->queued_imported += save_if_interesting(afl, mem, len, fault);
         afl->syncing_party = 0;
         munmap(mem, st.st_size);
         close(fd);
@@ -2818,19 +2817,23 @@ void check_binary(afl_state_t *afl, u8 *fname) {
     OKF(cPIN "Persistent mode binary detected.");
     setenv(PERSIST_ENV_VAR, "1", 1);
     afl->persistent_mode = 1;
-
+    afl->fsrv.persistent_mode = 1;
     afl->shmem_testcase_mode = 1;
 
   } else if (getenv("AFL_PERSISTENT")) {
 
-    WARNF("AFL_PERSISTENT is no longer supported and may misbehave!");
+    OKF(cPIN "Persistent mode enforced.");
+    setenv(PERSIST_ENV_VAR, "1", 1);
+    afl->persistent_mode = 1;
+    afl->fsrv.persistent_mode = 1;
+    afl->shmem_testcase_mode = 1;
 
   } else if (getenv("AFL_FRIDA_PERSISTENT_ADDR")) {
 
     OKF("FRIDA Persistent mode configuration options detected.");
     setenv(PERSIST_ENV_VAR, "1", 1);
     afl->persistent_mode = 1;
-
+    afl->fsrv.persistent_mode = 1;
     afl->shmem_testcase_mode = 1;
 
   }
@@ -2844,7 +2847,9 @@ void check_binary(afl_state_t *afl, u8 *fname) {
 
   } else if (getenv("AFL_DEFER_FORKSRV")) {
 
-    WARNF("AFL_DEFER_FORKSRV is no longer supported and may misbehave!");
+    OKF(cPIN "Deferred forkserver enforced.");
+    setenv(DEFER_ENV_VAR, "1", 1);
+    afl->deferred_mode = 1;
 
   }
 
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index 51a43dbd..e78e2dc4 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -428,7 +428,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
 
     if (likely(retlen)) {
 
-      write_to_testcase(afl, retbuf, retlen);
+      retlen = write_to_testcase(afl, retbuf, retlen, 0);
 
       fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
       ++afl->trim_execs;
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index eaa82b19..5da0e583 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -73,8 +73,8 @@ fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv, u32 timeout) {
    old file is unlinked and a new one is created. Otherwise, afl->fsrv.out_fd is
    rewound and truncated. */
 
-void __attribute__((hot))
-write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
+u32 __attribute__((hot))
+write_to_testcase(afl_state_t *afl, void *mem, u32 len, u32 fix) {
 
 #ifdef _AFL_DOCUMENT_MUTATIONS
   s32  doc_fd;
@@ -120,16 +120,39 @@ write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
 
     });
 
+    if (unlikely(new_size < afl->min_length && !fix)) {
+
+      new_size = afl->min_length;
+
+    } else if (unlikely(new_size > afl->max_length)) {
+
+      new_size = afl->max_length;
+
+    }
+
     /* everything as planned. use the potentially new data. */
     afl_fsrv_write_to_testcase(&afl->fsrv, new_mem, new_size);
+    len = new_size;
 
   } else {
 
+    if (unlikely(len < afl->min_length && !fix)) {
+
+      len = afl->min_length;
+
+    } else if (unlikely(len > afl->max_length)) {
+
+      len = afl->max_length;
+
+    }
+
     /* boring uncustom. */
     afl_fsrv_write_to_testcase(&afl->fsrv, mem, len);
 
   }
 
+  return len;
+
 }
 
 /* The same, but with an adjustable gap. Used for trimming. */
@@ -346,7 +369,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
   /* we need a dummy run if this is LTO + cmplog */
   if (unlikely(afl->shm.cmplog_mode)) {
 
-    write_to_testcase(afl, use_mem, q->len);
+    (void)write_to_testcase(afl, use_mem, q->len, 1);
 
     fault = fuzz_run_target(afl, &afl->fsrv, use_tmout);
 
@@ -389,7 +412,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
 
     u64 cksum;
 
-    write_to_testcase(afl, use_mem, q->len);
+    (void)write_to_testcase(afl, use_mem, q->len, 1);
 
     fault = fuzz_run_target(afl, &afl->fsrv, use_tmout);
 
@@ -700,7 +723,7 @@ void sync_fuzzers(afl_state_t *afl) {
         /* See what happens. We rely on save_if_interesting() to catch major
            errors and save the test case. */
 
-        write_to_testcase(afl, mem, st.st_size);
+        (void)write_to_testcase(afl, mem, st.st_size, 1);
 
         fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
 
@@ -943,7 +966,7 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
 
   u8 fault;
 
-  write_to_testcase(afl, out_buf, len);
+  len = write_to_testcase(afl, out_buf, len, 0);
 
   fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
 
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index 69ffa8cf..129e4c8b 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -102,6 +102,8 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
   afl->stats_avg_exec = 0;
   afl->skip_deterministic = 1;
   afl->cmplog_lvl = 2;
+  afl->min_length = 1;
+  afl->max_length = MAX_FILE;
 #ifndef NO_SPLICING
   afl->use_splicing = 1;
 #endif
@@ -480,6 +482,20 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
             afl->afl_env.afl_target_env =
                 (u8 *)get_afl_env(afl_environment_variables[i]);
 
+          } else if (!strncmp(env, "AFL_INPUT_LEN_MIN",
+
+                              afl_environment_variable_len)) {
+
+            afl->min_length =
+                atoi((u8 *)get_afl_env(afl_environment_variables[i]));
+
+          } else if (!strncmp(env, "AFL_INPUT_LEN_MAX",
+
+                              afl_environment_variable_len)) {
+
+            afl->max_length =
+                atoi((u8 *)get_afl_env(afl_environment_variables[i]));
+
           }
 
         } else {
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 9ef2669a..c73ab38b 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -155,6 +155,9 @@ static void usage(u8 *argv0, int more_help) {
       "\n"
 
       "Mutator settings:\n"
+      "  -g minlength  - set min length of generated fuzz input (default: 1)\n"
+      "  -G maxlength  - set max length of generated fuzz input (default: "
+      "%lu)\n"
       "  -D            - enable deterministic fuzzing (once per queue entry)\n"
       "  -L minutes    - use MOpt(imize) mode and set the time limit for "
       "entering the\n"
@@ -198,13 +201,13 @@ static void usage(u8 *argv0, int more_help) {
       "  -I command    - execute this command/script when a new crash is "
       "found\n"
       //"  -B bitmap.txt - mutate a specific test case, use the
-      //out/default/fuzz_bitmap file\n"
+      // out/default/fuzz_bitmap file\n"
       "  -C            - crash exploration mode (the peruvian rabbit thing)\n"
       "  -b cpu_id     - bind the fuzzing process to the specified CPU core "
       "(0-...)\n"
       "  -e ext        - file extension for the fuzz test input file (if "
       "needed)\n\n",
-      argv0, EXEC_TIMEOUT, MEM_LIMIT, FOREIGN_SYNCS_MAX);
+      argv0, EXEC_TIMEOUT, MEM_LIMIT, MAX_FILE, FOREIGN_SYNCS_MAX);
 
   if (more_help > 1) {
 
@@ -253,6 +256,7 @@ static void usage(u8 *argv0, int more_help) {
       "AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n"
       "AFL_IGNORE_PROBLEMS: do not abort fuzzing if an incorrect setup is detected during a run\n"
       "AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
+      "AFL_INPUT_LEN_MIN/AFL_INPUT_LEN_MAX: like -g/-G set min/max fuzz length produced\n"
       "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)\n"
       "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
       "              the target was compiled for\n"
@@ -290,8 +294,10 @@ 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_PERSISTENT: not supported anymore -> no effect, just a warning\n"
-      //"AFL_DEFER_FORKSRV: not supported anymore -> no effect, just a warning\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"
     );
 
@@ -527,13 +533,22 @@ int main(int argc, char **argv_orig, char **envp) {
 
   afl->shmem_testcase_mode = 1;  // we always try to perform shmem fuzzing
 
-  while ((opt = getopt(
-              argc, argv,
-              "+Ab:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNOXYo:p:RQs:S:t:T:UV:Wx:Z")) >
-         0) {
+  while (
+      (opt = getopt(
+           argc, argv,
+           "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:YZ")) >
+      0) {
 
     switch (opt) {
 
+      case 'g':
+        afl->min_length = atoi(optarg);
+        break;
+
+      case 'G':
+        afl->max_length = atoi(optarg);
+        break;
+
       case 'Z':
         afl->old_seed_selection = 1;
         break;
@@ -1622,6 +1637,16 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
+  OKF("Generating fuzz data with a a length of min=%u max=%u", afl->min_length,
+      afl->max_length);
+  u32 min_alloc = MAX(64U, afl->min_length);
+  afl_realloc(AFL_BUF_PARAM(in_scratch), min_alloc);
+  afl_realloc(AFL_BUF_PARAM(in), min_alloc);
+  afl_realloc(AFL_BUF_PARAM(out_scratch), min_alloc);
+  afl_realloc(AFL_BUF_PARAM(out), min_alloc);
+  afl_realloc(AFL_BUF_PARAM(eff), min_alloc);
+  afl_realloc(AFL_BUF_PARAM(ex), min_alloc);
+
   afl->fsrv.use_fauxsrv = afl->non_instrumented_mode == 1 || afl->no_forkserver;
 
   #ifdef __linux__