about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorDominik Maier <domenukk@gmail.com>2020-04-17 11:01:20 +0200
committerDominik Maier <domenukk@gmail.com>2020-04-17 11:01:20 +0200
commit90ff345d733caa51f6d2895dd229104c286b62c4 (patch)
tree9bf965a3e7f447ea0779848a6e09f9b356a0707e /src
parent8fa5d4c313372a337c7facf0428b0339babbe057 (diff)
parent2162fd8e1a1ceb745c1fcf87fb6a1053508591c4 (diff)
downloadafl++-90ff345d733caa51f6d2895dd229104c286b62c4.tar.gz
Merge branch 'dev' of github.com:aflplusplus/aflplusplus into dev
Diffstat (limited to 'src')
-rw-r--r--src/afl-analyze.c26
-rw-r--r--src/afl-common.c8
-rw-r--r--src/afl-forkserver.c21
-rw-r--r--src/afl-fuzz-bitmap.c16
-rw-r--r--src/afl-fuzz-init.c21
-rw-r--r--src/afl-fuzz-python.c2
-rw-r--r--src/afl-fuzz-queue.c9
-rw-r--r--src/afl-fuzz-run.c2
-rw-r--r--src/afl-fuzz-state.c24
-rw-r--r--src/afl-fuzz-stats.c31
-rw-r--r--src/afl-fuzz.c62
-rw-r--r--src/afl-gcc.c9
-rw-r--r--src/afl-showmap.c42
-rw-r--r--src/afl-tmin.c33
14 files changed, 181 insertions, 125 deletions
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index 6f946ed5..8a84b781 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -84,6 +84,7 @@ static volatile u8 stop_soon,          /* Ctrl-C pressed?                   */
 
 static u8 *target_path;
 static u8  qemu_mode;
+static u32 map_size = MAP_SIZE;
 
 /* Constants used for describing byte behavior. */
 
@@ -115,7 +116,7 @@ static u8 count_class_lookup[256] = {
 
 static void classify_counts(u8 *mem) {
 
-  u32 i = MAP_SIZE;
+  u32 i = map_size;
 
   if (edges_only) {
 
@@ -144,7 +145,7 @@ static void classify_counts(u8 *mem) {
 static inline u8 anything_set(void) {
 
   u32 *ptr = (u32 *)trace_bits;
-  u32  i = (MAP_SIZE >> 2);
+  u32  i = (map_size >> 2);
 
   while (i--)
     if (*(ptr++)) return 1;
@@ -217,7 +218,7 @@ static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
   s32 prog_in_fd;
   u32 cksum;
 
-  memset(trace_bits, 0, MAP_SIZE);
+  memset(trace_bits, 0, map_size);
   MEM_BARRIER();
 
   prog_in_fd = write_to_file(prog_in, mem, len);
@@ -311,7 +312,7 @@ static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
 
   }
 
-  cksum = hash32(trace_bits, MAP_SIZE, HASH_CONST);
+  cksum = hash32(trace_bits, map_size, HASH_CONST);
 
   /* We don't actually care if the target is crashing or not,
      except that when it does, the checksum should be different. */
@@ -795,8 +796,10 @@ static void usage(u8 *argv0) {
       "              (must contain abort_on_error=1 and symbolize=0)\n"
       "MSAN_OPTIONS: custom settings for MSAN\n"
       "              (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n"
-      "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
       "AFL_ANALYZE_HEX: print file offsets in hexadecimal instead of decimal\n"
+      "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
+      "              the target was compiled for\n"
+      "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
       "AFL_SKIP_BIN_CHECK: skip checking the location of and the target\n"
 
       , argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
@@ -811,7 +814,7 @@ int main(int argc, char **argv, char **envp) {
 
   s32    opt;
   u8     mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0;
-  char **use_argv;
+  char **use_argv, *ptr;
 
   doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
 
@@ -931,12 +934,21 @@ int main(int argc, char **argv, char **envp) {
 
   if (optind == argc || !in_file) usage(argv[0]);
 
+  if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) {
+
+    map_size = atoi(ptr);
+    if (map_size < 8 || map_size > (1 << 29))
+      FATAL("illegal AFL_MAP_SIZE %u, must be between 2^3 and 2^30", map_size);
+    if (map_size % 8) map_size = (((map_size >> 3) + 1) << 3);
+
+  }
+
   use_hex_offsets = !!get_afl_env("AFL_ANALYZE_HEX");
 
   check_environment_vars(envp);
 
   sharedmem_t shm = {0};
-  trace_bits = afl_shm_init(&shm, MAP_SIZE, 0);
+  trace_bits = afl_shm_init(&shm, map_size, 0);
   atexit(at_exit_handler);
   setup_signal_handlers();
 
diff --git a/src/afl-common.c b/src/afl-common.c
index 48efff2c..45868271 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -72,7 +72,7 @@ char *afl_environment_variables[] = {
     "AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", "AFL_NO_BUILTIN",
     "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI",
     "AFL_NO_X86",  // not really an env but we dont want to warn on it
-    "AFL_PATH", "AFL_PERFORMANCE_FILE",
+    "AFL_MAP_SIZE", "AFL_MAPSIZE", "AFL_PATH", "AFL_PERFORMANCE_FILE",
     //"AFL_PERSISTENT", // not implemented anymore, so warn additionally
     "AFL_POST_LIBRARY", "AFL_PRELOAD", "AFL_PYTHON_MODULE", "AFL_QEMU_COMPCOV",
     "AFL_QEMU_COMPCOV_DEBUG", "AFL_QEMU_DEBUG_MAPS", "AFL_QEMU_DISABLE_CACHE",
@@ -376,9 +376,13 @@ u8 *find_binary(u8 *fname) {
     target_path = ck_strdup(fname);
 
     if (stat(target_path, &st) || !S_ISREG(st.st_mode) ||
-        !(st.st_mode & 0111) || st.st_size < 4)
+        !(st.st_mode & 0111) || st.st_size < 4) {
+
+      free(target_path);
       FATAL("Program '%s' not found or not executable", fname);
 
+    }
+
   } else {
 
     while (env_path) {
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 006764d9..9b915a7a 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -407,21 +407,26 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
       if ((status & FS_OPT_MAPSIZE) == FS_OPT_MAPSIZE) {
 
-        fsrv->map_size = FS_OPT_GET_MAPSIZE(status);
-        if (unlikely(fsrv->map_size % 8)) {
+        u32 tmp_map_size = FS_OPT_GET_MAPSIZE(status);
+
+        if (!fsrv->map_size) fsrv->map_size = MAP_SIZE;
+
+        if (unlikely(tmp_map_size % 8)) {
 
           // should not happen
-          WARNF("Target reported non-aligned map size of %ud", fsrv->map_size);
-          fsrv->map_size = (((fsrv->map_size + 8) >> 3) << 3);
+          WARNF("Target reported non-aligned map size of %ud", tmp_map_size);
+          tmp_map_size = (((tmp_map_size + 8) >> 3) << 3);
 
         }
 
-        if (!be_quiet) ACTF("Target map size: %u", fsrv->map_size);
-        if (fsrv->map_size > MAP_SIZE)
+        if (!be_quiet) ACTF("Target map size: %u", tmp_map_size);
+        if (tmp_map_size > fsrv->map_size)
           FATAL(
               "Target's coverage map size of %u is larger than the one this "
-              "afl++ is compiled with (%u) (change MAP_SIZE and recompile)\n",
-              fsrv->map_size, MAP_SIZE);
+              "afl++ is set with (%u) (change MAP_SIZE_POW2 in config.h and "
+              "recompile or set AFL_MAP_SIZE)\n",
+              tmp_map_size, fsrv->map_size);
+        fsrv->map_size = tmp_map_size;
 
       }
 
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index be8f504e..0823deed 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -43,7 +43,7 @@ void write_bitmap(afl_state_t *afl) {
 
   if (fd < 0) PFATAL("Unable to open '%s'", fname);
 
-  ck_write(fd, afl->virgin_bits, MAP_SIZE, fname);
+  ck_write(fd, afl->virgin_bits, afl->fsrv.map_size, fname);
 
   close(fd);
 
@@ -145,8 +145,6 @@ u32 count_bits(afl_state_t *afl, u8 *mem) {
   u32  i = (afl->fsrv.map_size >> 2);
   u32  ret = 0;
 
-  if (i == 0) i = 1;
-
   while (i--) {
 
     u32 v = *(ptr++);
@@ -181,8 +179,6 @@ u32 count_bytes(afl_state_t *afl, u8 *mem) {
   u32  i = (afl->fsrv.map_size >> 2);
   u32  ret = 0;
 
-  if (i == 0) i = 1;
-
   while (i--) {
 
     u32 v = *(ptr++);
@@ -208,8 +204,6 @@ u32 count_non_255_bytes(afl_state_t *afl, u8 *mem) {
   u32  i = (afl->fsrv.map_size >> 2);
   u32  ret = 0;
 
-  if (i == 0) i = 1;
-
   while (i--) {
 
     u32 v = *(ptr++);
@@ -246,8 +240,6 @@ void simplify_trace(afl_state_t *afl, u64 *mem) {
 
   u32 i = (afl->fsrv.map_size >> 3);
 
-  if (i == 0) i = 1;
-
   while (i--) {
 
     /* Optimize for sparse bitmaps. */
@@ -281,8 +273,6 @@ void simplify_trace(afl_state_t *afl, u32 *mem) {
 
   u32 i = (afl->fsrv.map_size >> 2);
 
-  if (i == 0) i = 1;
-
   while (i--) {
 
     /* Optimize for sparse bitmaps. */
@@ -347,8 +337,6 @@ void classify_counts(afl_forkserver_t *fsrv) {
 
   u32 i = (fsrv->map_size >> 3);
 
-  if (i == 0) i = 1;
-
   while (i--) {
 
     /* Optimize for sparse bitmaps. */
@@ -378,8 +366,6 @@ void classify_counts(afl_forkserver_t *fsrv) {
 
   u32 i = (fsrv->map_size >> 2);
 
-  if (i == 0) i = 1;
-
   while (i--) {
 
     /* Optimize for sparse bitmaps. */
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 55f7ce53..3da348d2 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -442,23 +442,6 @@ void read_testcases(afl_state_t *afl) {
 
 }
 
-/* Examine map coverage. Called once, for first test case. */
-
-static void check_map_coverage(afl_state_t *afl) {
-
-  u32 i;
-
-  if (count_bytes(afl, afl->fsrv.trace_bits) < 100) return;
-
-  for (i = (1 << (MAP_SIZE_POW2 - 1)); i < MAP_SIZE; ++i)
-    if (afl->fsrv.trace_bits[i]) return;
-
-  if (afl->fsrv.map_size != MAP_SIZE) return;
-
-  WARNF("Recompile binary with newer version of afl to improve coverage!");
-
-}
-
 /* Perform dry run of all test cases to confirm that the app is working as
    expected. This is done only for the initial inputs, and only once. */
 
@@ -501,8 +484,6 @@ void perform_dry_run(afl_state_t *afl) {
 
       case FSRV_RUN_OK:
 
-        if (q == afl->queue) check_map_coverage(afl);
-
         if (afl->crash_mode) FATAL("Test case '%s' does *NOT* crash", fn);
 
         break;
@@ -1419,6 +1400,8 @@ void setup_dirs_fds(afl_state_t *afl) {
           "# unix_time, cycles_done, cur_path, paths_total, "
           "pending_total, pending_favs, map_size, unique_crashes, "
           "unique_hangs, max_depth, execs_per_sec\n");
+  fflush(afl->fsrv.plot_file);
+
   /* ignore errors */
 
 }
diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c
index 33f01797..d4519c6d 100644
--- a/src/afl-fuzz-python.c
+++ b/src/afl-fuzz-python.c
@@ -42,7 +42,7 @@ it just fills in `&py_mutator->something_buf, &py_mutator->something_size`. */
       &((py_mutator_t *)py_mutator)->name##_size
 
 static size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf,
-               u8 *add_buf, size_t add_buf_size, size_t max_size) {
+                      u8 *add_buf, size_t add_buf_size, size_t max_size) {
 
   size_t    mutated_size;
   PyObject *py_args, *py_value;
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index d05eee08..373f12d8 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -249,7 +249,6 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
       if (!q->trace_mini) {
 
         u32 len = (afl->fsrv.map_size >> 3);
-        if (len == 0) len = 1;
         q->trace_mini = ck_alloc(len);
         minimize_bits(afl, q->trace_mini, afl->fsrv.trace_bits);
 
@@ -272,12 +271,12 @@ void cull_queue(afl_state_t *afl) {
   struct queue_entry *q;
   u32                 len = (afl->fsrv.map_size >> 3);
   u32                 i;
-  u8                  temp_v[MAP_SIZE >> 3];
-
-  if (len == 0) len = 1;
+  u8 *                temp_v;
 
   if (afl->dumb_mode || !afl->score_changed) return;
 
+  temp_v = ck_alloc(afl->fsrv.map_size >> 3);
+
   afl->score_changed = 0;
 
   memset(temp_v, 255, len);
@@ -325,6 +324,8 @@ void cull_queue(afl_state_t *afl) {
 
   }
 
+  ck_free(temp_v);
+
 }
 
 /* Calculate case desirability score to adjust the length of havoc fuzzing.
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index 6ad6444a..30ba0e65 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -34,7 +34,7 @@
    information. The called program will update afl->fsrv->trace_bits. */
 
 fsrv_run_result_t fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv,
-                             u32 timeout) {
+                                  u32 timeout) {
 
   fsrv_run_result_t res = afl_fsrv_run_target(fsrv, timeout, &afl->stop_soon);
   // TODO: Don't classify for faults?
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index 7664c521..7d068258 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -99,7 +99,11 @@ void afl_state_init(afl_state_t *afl) {
 
   afl->fsrv.use_stdin = 1;
 
-  afl->fsrv.map_size = MAP_SIZE;
+  if (afl->afl_env.map_size > 8 && afl->afl_env.map_size <= (1 << 29))
+    afl->fsrv.map_size = afl->afl_env.map_size;
+  else
+    afl->fsrv.map_size = MAP_SIZE;
+
   afl->fsrv.function_opt = (u8 *)afl;
   afl->fsrv.function_ptr = &maybe_add_auto;
 
@@ -324,6 +328,24 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
             afl->afl_env.afl_path =
                 (u8 *)get_afl_env(afl_environment_variables[i]);
 
+          } else if (!strncmp(env, "AFL_MAP_SIZE",
+
+                              afl_environment_variable_len) ||
+                     !strncmp(env, "AFL_MAPSIZE",
+                              afl_environment_variable_len)) {
+
+            afl->afl_env.map_size =
+                atoi((u8 *)get_afl_env(afl_environment_variables[i]));
+
+            if (afl->afl_env.map_size < 8 || afl->afl_env.map_size > (1 << 29))
+              FATAL(
+                  "the specified AFL_MAP_SIZE size is illegal and must be "
+                  "between 2^3 and 2^30: %u\n",
+                  afl->afl_env.map_size);
+
+            if (afl->afl_env.map_size % 8)
+              afl->afl_env.map_size = (((afl->afl_env.map_size >> 3) + 1) << 3);
+
           } else if (!strncmp(env, "AFL_PRELOAD",
 
                               afl_environment_variable_len)) {
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 7cc9b920..c507b7f7 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -145,14 +145,15 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
 
 void maybe_update_plot_file(afl_state_t *afl, double bitmap_cvg, double eps) {
 
-  if (afl->plot_prev_qp == afl->queued_paths &&
-      afl->plot_prev_pf == afl->pending_favored &&
-      afl->plot_prev_pnf == afl->pending_not_fuzzed &&
-      afl->plot_prev_ce == afl->current_entry &&
-      afl->plot_prev_qc == afl->queue_cycle &&
-      afl->plot_prev_uc == afl->unique_crashes &&
-      afl->plot_prev_uh == afl->unique_hangs &&
-      afl->plot_prev_md == afl->max_depth)
+  if (unlikely(afl->plot_prev_qp == afl->queued_paths &&
+               afl->plot_prev_pf == afl->pending_favored &&
+               afl->plot_prev_pnf == afl->pending_not_fuzzed &&
+               afl->plot_prev_ce == afl->current_entry &&
+               afl->plot_prev_qc == afl->queue_cycle &&
+               afl->plot_prev_uc == afl->unique_crashes &&
+               afl->plot_prev_uh == afl->unique_hangs &&
+               afl->plot_prev_md == afl->max_depth) ||
+      unlikely(!afl->queue_cycle))
     return;
 
   afl->plot_prev_qp = afl->queued_paths;
@@ -388,9 +389,9 @@ void show_stats(afl_state_t *afl) {
 
   /* Lord, forgive me this. */
 
-  SAYF(SET_G1 bSTG bLT bH bSTOP                         cCYA
+  SAYF(SET_G1 bSTG bLT bH bSTOP cCYA
        " process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA
-       " overall results " bSTG bH2 bH2                 bRT "\n");
+       " overall results " bSTG bH2 bH2 bRT "\n");
 
   if (afl->dumb_mode) {
 
@@ -472,9 +473,9 @@ void show_stats(afl_state_t *afl) {
                 "   uniq hangs : " cRST "%-6s" bSTG         bV "\n",
        time_tmp, tmp);
 
-  SAYF(bVR bH bSTOP                                          cCYA
+  SAYF(bVR bH bSTOP            cCYA
        " cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA
-       " map coverage " bSTG bH bHT bH20 bH2                 bVL "\n");
+       " map coverage " bSTG bH bHT bH20 bH2 bVL "\n");
 
   /* This gets funny because we want to print several variable-length variables
      together, but then cram them into a fixed-width field - so we need to
@@ -504,9 +505,9 @@ void show_stats(afl_state_t *afl) {
 
   SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp);
 
-  SAYF(bVR bH bSTOP                                         cCYA
+  SAYF(bVR bH bSTOP            cCYA
        " stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA
-       " findings in depth " bSTG bH10 bH5 bH2 bH2          bVL "\n");
+       " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n");
 
   sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored),
           ((double)afl->queued_favored) * 100 / afl->queued_paths);
@@ -580,7 +581,7 @@ void show_stats(afl_state_t *afl) {
 
   /* Aaaalmost there... hold on! */
 
-  SAYF(bVR bH cCYA                                                     bSTOP
+  SAYF(bVR bH cCYA                      bSTOP
        " fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA
        " path geometry " bSTG bH5 bH2 bVL "\n");
 
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 925dbb1a..2a1387a9 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -150,44 +150,46 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
   if (more_help > 1)
     SAYF(
       "Environment variables used:\n"
-      "AFL_PATH: path to AFL support binaries\n"
-      "AFL_QUIET: suppress forkserver status messages\n"
-      "AFL_DEBUG_CHILD_OUTPUT: do not suppress stdout/stderr from target\n"
       "LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n"
+      "ASAN_OPTIONS: custom settings for ASAN\n"
+      "              (must contain abort_on_error=1 and symbolize=0)\n"
+      "MSAN_OPTIONS: custom settings for MSAN\n"
+      "              (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n"
+      "AFL_AUTORESUME: resume fuzzing if directory specified by -o already exists\n"
       "AFL_BENCH_JUST_ONE: run the target just once\n"
-      "AFL_DUMB_FORKSRV: use fork server without feedback from target\n"
+      "AFL_BENCH_UNTIL_CRASH: exit soon when the first crashing input has been found\n"
       "AFL_CUSTOM_MUTATOR_LIBRARY: lib with afl_custom_fuzz() to mutate inputs\n"
       "AFL_CUSTOM_MUTATOR_ONLY: avoid AFL++'s internal mutators\n"
-      "AFL_PYTHON_MODULE: mutate and trim inputs with the specified Python module\n"
       "AFL_DEBUG: extra debugging output for Python mode trimming\n"
+      "AFL_DEBUG_CHILD_OUTPUT: do not suppress stdout/stderr from target\n"
       "AFL_DISABLE_TRIM: disable the trimming of test cases\n"
-      "AFL_NO_UI: switch status screen off\n"
-      "AFL_FORCE_UI: force showing the status screen (for virtual consoles)\n"
-      "AFL_NO_CPU_RED: avoid red color for showing very high cpu usage\n"
-      "AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n"
-      "AFL_NO_SNAPSHOT: do not use the snapshot feature (if the snapshot lkm is loaded)\n"
-      "AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n"
-      "AFL_NO_ARITH: skip arithmetic mutations in deterministic stage\n"
-      "AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n"
+      "AFL_DUMB_FORKSRV: use fork server without feedback from target\n"
+      "AFL_EXIT_WHEN_DONE: exit when all inputs are run and no new finds are found\n"
       "AFL_FAST_CAL: limit the calibration stage to three cycles for speedup\n"
+      "AFL_FORCE_UI: force showing the status screen (for virtual consoles)\n"
       "AFL_HANG_TMOUT: override timeout value (in milliseconds)\n"
-      "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
-      "AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n"
+      "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n"
       "AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
+      "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
+      "              the target was compiled for\n"
       "AFL_NO_AFFINITY: do not check for an unused cpu core to use for fuzzing\n"
+      "AFL_NO_ARITH: skip arithmetic mutations in deterministic stage\n"
+      "AFL_NO_CPU_RED: avoid red color for showing very high cpu usage\n"
+      "AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n"
+      "AFL_NO_SNAPSHOT: do not use the snapshot feature (if the snapshot lkm is loaded)\n"
+      "AFL_NO_UI: switch status screen off\n"
+      "AFL_PATH: path to AFL support binaries\n"
       "AFL_POST_LIBRARY: postprocess generated test cases before use as target input\n"
-      "AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs\n"
-      "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n"
-      "ASAN_OPTIONS: custom settings for ASAN\n"
-      "              (must contain abort_on_error=1 and symbolize=0)\n"
-      "MSAN_OPTIONS: custom settings for MSAN\n"
-      "              (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n"
+      "AFL_PYTHON_MODULE: mutate and trim inputs with the specified Python module\n"
+      "AFL_QUIET: suppress forkserver status messages\n"
+      "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
+      "AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n"
       "AFL_SKIP_BIN_CHECK: skip the check, if the target is an excutable\n"
+      "AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n"
+      "AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs\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_EXIT_WHEN_DONE: exit when all inputs are run and no new finds are found\n"
-      "AFL_BENCH_UNTIL_CRASH: exit soon when the first crashing input has been found\n"
-      "AFL_AUTORESUME: resume fuzzing if directory specified by -o already exists\n"
       "\n"
     );
   else
@@ -249,6 +251,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
   if (get_afl_env("AFL_DEBUG")) afl->debug = 1;
   read_afl_environment(afl, envp);
+  if (afl->afl_env.map_size) afl->fsrv.map_size = afl->afl_env.map_size;
   exit_1 = !!afl->afl_env.afl_bench_just_one;
 
   SAYF(cCYA "afl-fuzz" VERSION cRST
@@ -476,7 +479,7 @@ int main(int argc, char **argv_orig, char **envp) {
         if (afl->in_bitmap) FATAL("Multiple -B options not supported");
 
         afl->in_bitmap = optarg;
-        read_bitmap(afl->in_bitmap, afl->virgin_bits, MAP_SIZE);
+        read_bitmap(afl->in_bitmap, afl->virgin_bits, afl->fsrv.map_size);
         break;
 
       case 'C':                                               /* crash mode */
@@ -910,13 +913,14 @@ int main(int argc, char **argv_orig, char **envp) {
   check_crash_handling();
   check_cpu_governor(afl);
 
-  afl->fsrv.trace_bits = afl_shm_init(&afl->shm, MAP_SIZE, afl->dumb_mode);
+  afl->fsrv.trace_bits =
+      afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->dumb_mode);
 
   setup_post(afl);
 
-  if (!afl->in_bitmap) memset(afl->virgin_bits, 255, MAP_SIZE);
-  memset(afl->virgin_tmout, 255, MAP_SIZE);
-  memset(afl->virgin_crash, 255, MAP_SIZE);
+  if (!afl->in_bitmap) memset(afl->virgin_bits, 255, afl->fsrv.map_size);
+  memset(afl->virgin_tmout, 255, afl->fsrv.map_size);
+  memset(afl->virgin_crash, 255, afl->fsrv.map_size);
 
   init_count_class16();
 
diff --git a/src/afl-gcc.c b/src/afl-gcc.c
index 32cd36cb..1ae10975 100644
--- a/src/afl-gcc.c
+++ b/src/afl-gcc.c
@@ -411,6 +411,15 @@ int main(int argc, char **argv) {
 
   }
 
+  u8 *ptr;
+  if (!be_quiet &&
+      ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE")))) {
+
+    u32 map_size = atoi(ptr);
+    if (map_size != MAP_SIZE) FATAL("AFL_MAP_SIZE is not supported by afl-gcc");
+
+  }
+
   find_as(argv[0]);
 
   edit_params(argc, argv);
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 61c1754f..a11c128a 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -72,6 +72,8 @@ static u32 total, highest;             /* tuple content information         */
 static u32 in_len,                     /* Input data length                 */
     arg_offset;                        /* Total number of execs             */
 
+static u32 map_size = MAP_SIZE;
+
 static u8 quiet_mode,                  /* Hide non-essential messages?      */
     edges_only,                        /* Ignore hit counts?                */
     raw_instr_output,                  /* Do not apply AFL filters          */
@@ -112,7 +114,7 @@ static void classify_counts(afl_forkserver_t *fsrv) {
   u8 *      mem = fsrv->trace_bits;
   const u8 *map = binary_mode ? count_class_binary : count_class_human;
 
-  u32 i = MAP_SIZE;
+  u32 i = map_size;
 
   if (edges_only) {
 
@@ -175,10 +177,10 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
 
   if (binary_mode) {
 
-    for (i = 0; i < MAP_SIZE; i++)
+    for (i = 0; i < map_size; i++)
       if (fsrv->trace_bits[i]) ret++;
 
-    ck_write(fd, fsrv->trace_bits, MAP_SIZE, outfile);
+    ck_write(fd, fsrv->trace_bits, map_size, outfile);
     close(fd);
 
   } else {
@@ -187,7 +189,7 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
 
     if (!f) PFATAL("fdopen() failed");
 
-    for (i = 0; i < MAP_SIZE; i++) {
+    for (i = 0; i < map_size; i++) {
 
       if (!fsrv->trace_bits[i]) continue;
       ret++;
@@ -218,8 +220,8 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
 
 /* Execute target application. */
 
-static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, char **argv, u8 *mem,
-                           u32 len) {
+static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, char **argv,
+                                          u8 *mem, u32 len) {
 
   afl_fsrv_write_to_testcase(fsrv, mem, len);
 
@@ -513,14 +515,17 @@ static void usage(u8 *argv0) {
       "For additional help, consult %s/README.md.\n\n"
 
       "Environment variables used:\n"
-      "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
-      "AFL_DEBUG: enable extra developer output\n"
-      "AFL_QUIET: do not print extra informational output"
+      "LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n",
       "AFL_CMIN_CRASHES_ONLY: (cmin_mode) only write tuples for crashing "
       "inputs\n"
       "AFL_CMIN_ALLOW_ANY: (cmin_mode) write tuples for crashing inputs also\n"
-      "LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n",
-      argv0, MEM_LIMIT, doc_path);
+      "AFL_DEBUG: enable extra developer output\n"
+      "AFL_MAP_SIZE: the shared memory size for that target. must be >= the "
+      "size\n"
+      "              the target was compiled for\n"
+      "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
+      "AFL_QUIET: do not print extra informational output" argv0,
+      MEM_LIMIT, doc_path);
 
   exit(1);
 
@@ -535,7 +540,7 @@ int main(int argc, char **argv_orig, char **envp) {
   s32    opt, i;
   u8     mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0;
   u32    tcnt = 0;
-  char **use_argv;
+  char **use_argv, *ptr;
 
   char **argv = argv_cpy_dup(argc, argv_orig);
 
@@ -543,6 +548,16 @@ int main(int argc, char **argv_orig, char **envp) {
   afl_forkserver_t *fsrv = &fsrv_var;
   afl_fsrv_init(fsrv);
 
+  if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) {
+
+    map_size = atoi(ptr);
+    if (map_size < 8 || map_size > (1 << 29))
+      FATAL("illegal AFL_MAP_SIZE %u, must be between 2^3 and 2^30", map_size);
+    if (map_size % 8) map_size = (((map_size >> 3) + 1) << 3);
+    fsrv->map_size = map_size;
+
+  }
+
   doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
 
   if (getenv("AFL_QUIET") != NULL) be_quiet = 1;
@@ -715,7 +730,7 @@ int main(int argc, char **argv_orig, char **envp) {
   check_environment_vars(envp);
 
   sharedmem_t shm = {0};
-  fsrv->trace_bits = afl_shm_init(&shm, MAP_SIZE, 0);
+  fsrv->trace_bits = afl_shm_init(&shm, map_size, 0);
   setup_signal_handlers();
 
   set_up_environment(fsrv);
@@ -877,6 +892,7 @@ int main(int argc, char **argv_orig, char **envp) {
   if (stdin_file) ck_free(stdin_file);
 
   argv_cpy_free(argv);
+  if (fsrv->qemu_mode) free(use_argv[2]);
 
   exit(ret);
 
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index 431ff0c4..ad7d70c7 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -70,7 +70,8 @@ static u32 in_len,                     /* Input data length                 */
     orig_cksum,                        /* Original checksum                 */
     missed_hangs,                      /* Misses due to hangs               */
     missed_crashes,                    /* Misses due to crashes             */
-    missed_paths;                      /* Misses due to exec path diffs     */
+    missed_paths,                      /* Misses due to exec path diffs     */
+    map_size = MAP_SIZE;
 
 static u8 crash_mode,                  /* Crash-centric mode?               */
     hang_mode,                         /* Minimize as long as it hangs      */
@@ -105,7 +106,7 @@ static const u8 count_class_lookup[256] = {
 
 static void apply_mask(u32 *mem, u32 *mask) {
 
-  u32 i = (MAP_SIZE >> 2);
+  u32 i = (map_size >> 2);
 
   if (!mask) return;
 
@@ -122,7 +123,7 @@ static void apply_mask(u32 *mem, u32 *mask) {
 static void classify_counts(afl_forkserver_t *fsrv) {
 
   u8 *mem = fsrv->trace_bits;
-  u32 i = MAP_SIZE;
+  u32 i = map_size;
 
   if (edges_only) {
 
@@ -151,7 +152,7 @@ static void classify_counts(afl_forkserver_t *fsrv) {
 static inline u8 anything_set(afl_forkserver_t *fsrv) {
 
   u32 *ptr = (u32 *)fsrv->trace_bits;
-  u32  i = (MAP_SIZE >> 2);
+  u32  i = (map_size >> 2);
 
   while (i--)
     if (*(ptr++)) return 1;
@@ -215,7 +216,7 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
    1 if they should be kept. */
 
 static u8 tmin_run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
-                     u8 first_run) {
+                          u8 first_run) {
 
   afl_fsrv_write_to_testcase(fsrv, mem, len);
 
@@ -740,7 +741,9 @@ static void usage(u8 *argv0) {
       "              (must contain abort_on_error=1 and symbolize=0)\n"
       "MSAN_OPTIONS: custom settings for MSAN\n"
       "              (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n"
-      "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
+      "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
+      "              the target was compiled for\n"
+      "AFL_PRELOAD:  LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
       "AFL_TMIN_EXACT: require execution paths to match for crashing inputs\n"
 
       , argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
@@ -755,7 +758,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
   s32    opt;
   u8     mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0;
-  char **use_argv;
+  char **use_argv, *ptr;
 
   char **argv = argv_cpy_dup(argc, argv_orig);
 
@@ -763,6 +766,16 @@ int main(int argc, char **argv_orig, char **envp) {
   afl_forkserver_t *fsrv = &fsrv_var;
   afl_fsrv_init(fsrv);
 
+  if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) {
+
+    map_size = atoi(ptr);
+    if (map_size < 8 || map_size > (1 << 29))
+      FATAL("illegal AFL_MAP_SIZE %u, must be between 2^3 and 2^30", map_size);
+    if (map_size % 8) map_size = (((map_size >> 3) + 1) << 3);
+    fsrv->map_size = map_size;
+
+  }
+
   doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
 
   SAYF(cCYA "afl-tmin" VERSION cRST " by Michal Zalewski\n");
@@ -910,8 +923,8 @@ int main(int argc, char **argv_orig, char **envp) {
            to be useful. */
 
         if (mask_bitmap) FATAL("Multiple -B options not supported");
-        mask_bitmap = ck_alloc(MAP_SIZE);
-        read_bitmap(optarg, mask_bitmap, MAP_SIZE);
+        mask_bitmap = ck_alloc(map_size);
+        read_bitmap(optarg, mask_bitmap, map_size);
         break;
 
       case 'h':
@@ -928,7 +941,7 @@ int main(int argc, char **argv_orig, char **envp) {
   check_environment_vars(envp);
 
   sharedmem_t shm = {0};
-  fsrv->trace_bits = afl_shm_init(&shm, MAP_SIZE, 0);
+  fsrv->trace_bits = afl_shm_init(&shm, map_size, 0);
 
   atexit(at_exit_handler);
   setup_signal_handlers();