about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2020-12-01 13:13:11 +0100
committervan Hauser <vh@thc.org>2020-12-01 13:13:11 +0100
commit8584f9d2b5de9687c518c672e471f4f8cd9166fa (patch)
tree568533382f57e7d631962b94fb5d1742c0377112
parentf7d8643dc4531a9aa8849d4acf2a96b0d8ae5c3c (diff)
downloadafl++-8584f9d2b5de9687c518c672e471f4f8cd9166fa.tar.gz
added AFL_NO_AUTODICT
-rw-r--r--docs/Changelog.md1
-rw-r--r--docs/env_variables.md3
-rw-r--r--include/envs.h1
-rw-r--r--instrumentation/README.lto.md33
-rw-r--r--src/afl-forkserver.c125
-rw-r--r--src/afl-fuzz.c1
6 files changed, 95 insertions, 69 deletions
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 3c20f8bd..7fa7ff53 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -34,6 +34,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
     - crashing seeds are now not prohibiting a run anymore but are
       skipped. They are used for splicing though.
     - update MOpt for expanded havoc modes
+    - setting the env var AFL_NO_AUTODICT will not load an LTO autodictionary
     - added NO_SPLICING compile option and makefile define
     - added INTROSPECTION make target that writes all mutations to
       out/NAME/introspection.txt
diff --git a/docs/env_variables.md b/docs/env_variables.md
index 04ba032a..f7b4c994 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -294,6 +294,9 @@ checks or alter some of the more exotic semantics of the tool:
     on Linux systems. This slows things down, but lets you run more instances
     of afl-fuzz than would be prudent (if you really want to).
 
+  - Setting `AFL_NO_AUTODICT` will not load an LTO generated auto dictionary
+    that is compiled into the target.
+
   - `AFL_SKIP_CRASHES` causes AFL++ to tolerate crashing files in the input
     queue. This can help with rare situations where a program crashes only
     intermittently, but it's not really recommended under normal operating
diff --git a/include/envs.h b/include/envs.h
index 8255cf4f..3aa05cb5 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -100,6 +100,7 @@ static char *afl_environment_variables[] = {
     "AFL_LLVM_LTO_STARTID",
     "AFL_LLVM_LTO_DONTWRITEID",
     "AFL_NO_ARITH",
+    "AFL_NO_AUTODICT",
     "AFL_NO_BUILTIN",
     "AFL_NO_CPU_RED",
     "AFL_NO_FORKSRV",
diff --git a/instrumentation/README.lto.md b/instrumentation/README.lto.md
index abdbd2ac..62e98902 100644
--- a/instrumentation/README.lto.md
+++ b/instrumentation/README.lto.md
@@ -60,7 +60,12 @@ AUTODICTIONARY: 11 strings found
 
 ## Getting llvm 11+
 
-### Installing llvm from the llvm repository (version 11)
+### Installing llvm version 11
+
+llvm 11 should be available in all current Linux repository.
+If you use an outdated Linux distribution read the next section.
+
+### Installing llvm from the llvm repository (version 12)
 
 Installing the llvm snapshot builds is easy and mostly painless:
 
@@ -73,11 +78,11 @@ then add the pgp key of llvm and install the packages:
 ```
 wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - 
 apt-get update && apt-get upgrade -y
-apt-get install -y clang-11 clang-tools-11 libc++1-11 libc++-11-dev \
-    libc++abi1-11 libc++abi-11-dev libclang1-11 libclang-11-dev \
-    libclang-common-11-dev libclang-cpp11 libclang-cpp11-dev liblld-11 \
-    liblld-11-dev liblldb-11 liblldb-11-dev libllvm11 libomp-11-dev \
-    libomp5-11 lld-11 lldb-11 llvm-11 llvm-11-dev llvm-11-runtime llvm-11-tools
+apt-get install -y clang-12 clang-tools-12 libc++1-12 libc++-12-dev \
+    libc++abi1-12 libc++abi-12-dev libclang1-12 libclang-12-dev \
+    libclang-common-12-dev libclang-cpp11 libclang-cpp11-dev liblld-12 \
+    liblld-12-dev liblldb-12 liblldb-12-dev libllvm11 libomp-12-dev \
+    libomp5-12 lld-12 lldb-12 llvm-12 llvm-12-dev llvm-12-runtime llvm-12-tools
 ```
 
 ### Building llvm yourself (version 12)
@@ -120,16 +125,22 @@ While compiling, a dictionary based on string comparisons is automatically
 generated and put into the target binary. This dictionary is transfered to afl-fuzz
 on start. This improves coverage statistically by 5-10% :)
 
+Note that if for any reason you do not want to use the autodictionary feature
+then just set the environment variable `AFL_NO_AUTODICT` when starting afl-fuzz.
+
 ## Fixed memory map
 
-To speed up fuzzing, it is possible to set a fixed shared memory map.
+To speed up fuzzing a little bit more, it is possible to set a fixed shared
+memory map.
 Recommended is the value 0x10000.
+
 In most cases this will work without any problems. However if a target uses
 early constructors, ifuncs or a deferred forkserver this can crash the target.
-On unusual operating systems/processors/kernels or weird libraries this might
-fail so to change the fixed address at compile time set
-AFL_LLVM_MAP_ADDR with a better value (a value of 0 or empty sets the map address
-to be dynamic - the original afl way, which is slower).
+
+Also on unusual operating systems/processors/kernels or weird libraries the
+recommended 0x10000 address might not work, so then change the fixed address.
+
+To enable this feature set AFL_LLVM_MAP_ADDR with the address.
 
 ## Document edge IDs
 
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 3814a77e..01ef1d9e 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -348,9 +348,10 @@ static void report_error_and_exit(int error) {
 void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
                     volatile u8 *stop_soon_p, u8 debug_child_output) {
 
-  int st_pipe[2], ctl_pipe[2];
-  s32 status;
-  s32 rlen;
+  int   st_pipe[2], ctl_pipe[2];
+  s32   status;
+  s32   rlen;
+  char *ignore_autodict = getenv("AFL_NO_AUTODICT");
 
   if (!be_quiet) { ACTF("Spinning up the fork server..."); }
 
@@ -607,7 +608,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
           fsrv->use_shmem_fuzz = 1;
           if (!be_quiet) { ACTF("Using SHARED MEMORY FUZZING feature."); }
 
-          if ((status & FS_OPT_AUTODICT) == 0) {
+          if ((status & FS_OPT_AUTODICT) == 0 || ignore_autodict) {
 
             u32 send_status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ);
             if (write(fsrv->fsrv_ctl_fd, &send_status, 4) != 4) {
@@ -660,101 +661,109 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
       if ((status & FS_OPT_AUTODICT) == FS_OPT_AUTODICT) {
 
-        if (fsrv->add_extra_func == NULL || fsrv->afl_ptr == NULL) {
+        if (ignore_autodict) {
 
-          // this is not afl-fuzz - or it is cmplog - we deny and return
-          if (fsrv->use_shmem_fuzz) {
+          if (!be_quiet) { WARNF("Ignoring offered AUTODICT feature."); }
 
-            status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ);
+        } else {
 
-          } else {
+          if (fsrv->add_extra_func == NULL || fsrv->afl_ptr == NULL) {
 
-            status = (FS_OPT_ENABLED);
+            // this is not afl-fuzz - or it is cmplog - we deny and return
+            if (fsrv->use_shmem_fuzz) {
 
-          }
+              status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ);
 
-          if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) {
+            } else {
 
-            FATAL("Writing to forkserver failed.");
+              status = (FS_OPT_ENABLED);
 
-          }
+            }
 
-          return;
+            if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) {
 
-        }
+              FATAL("Writing to forkserver failed.");
 
-        if (!be_quiet) { ACTF("Using AUTODICT feature."); }
+            }
 
-        if (fsrv->use_shmem_fuzz) {
+            return;
 
-          status = (FS_OPT_ENABLED | FS_OPT_AUTODICT | FS_OPT_SHDMEM_FUZZ);
+          }
 
-        } else {
+          if (!be_quiet) { ACTF("Using AUTODICT feature."); }
 
-          status = (FS_OPT_ENABLED | FS_OPT_AUTODICT);
+          if (fsrv->use_shmem_fuzz) {
 
-        }
+            status = (FS_OPT_ENABLED | FS_OPT_AUTODICT | FS_OPT_SHDMEM_FUZZ);
 
-        if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) {
+          } else {
 
-          FATAL("Writing to forkserver failed.");
+            status = (FS_OPT_ENABLED | FS_OPT_AUTODICT);
 
-        }
+          }
 
-        if (read(fsrv->fsrv_st_fd, &status, 4) != 4) {
+          if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) {
 
-          FATAL("Reading from forkserver failed.");
+            FATAL("Writing to forkserver failed.");
 
-        }
+          }
 
-        if (status < 2 || (u32)status > 0xffffff) {
+          if (read(fsrv->fsrv_st_fd, &status, 4) != 4) {
 
-          FATAL("Dictionary has an illegal size: %d", status);
+            FATAL("Reading from forkserver failed.");
 
-        }
+          }
 
-        u32 offset = 0, count = 0;
-        u32 len = status;
-        u8 *dict = ck_alloc(len);
-        if (dict == NULL) {
+          if (status < 2 || (u32)status > 0xffffff) {
 
-          FATAL("Could not allocate %u bytes of autodictionary memory", len);
+            FATAL("Dictionary has an illegal size: %d", status);
 
-        }
+          }
 
-        while (len != 0) {
+          u32 offset = 0, count = 0;
+          u32 len = status;
+          u8 *dict = ck_alloc(len);
+          if (dict == NULL) {
 
-          rlen = read(fsrv->fsrv_st_fd, dict + offset, len);
-          if (rlen > 0) {
+            FATAL("Could not allocate %u bytes of autodictionary memory", len);
 
-            len -= rlen;
-            offset += rlen;
+          }
 
-          } else {
+          while (len != 0) {
 
-            FATAL(
-                "Reading autodictionary fail at position %u with %u bytes "
-                "left.",
-                offset, len);
+            rlen = read(fsrv->fsrv_st_fd, dict + offset, len);
+            if (rlen > 0) {
+
+              len -= rlen;
+              offset += rlen;
+
+            } else {
+
+              FATAL(
+                  "Reading autodictionary fail at position %u with %u bytes "
+                  "left.",
+                  offset, len);
+
+            }
 
           }
 
-        }
+          offset = 0;
+          while (offset < (u32)status &&
+                 (u8)dict[offset] + offset < (u32)status) {
+
+            fsrv->add_extra_func(fsrv->afl_ptr, dict + offset + 1,
+                                 (u8)dict[offset]);
+            offset += (1 + dict[offset]);
+            count++;
 
-        offset = 0;
-        while (offset < (u32)status &&
-               (u8)dict[offset] + offset < (u32)status) {
+          }
 
-          fsrv->add_extra_func(fsrv->afl_ptr, dict + offset + 1,
-                               (u8)dict[offset]);
-          offset += (1 + dict[offset]);
-          count++;
+          if (!be_quiet) { ACTF("Loaded %u autodictionary entries", count); }
+          ck_free(dict);
 
         }
 
-        if (!be_quiet) { ACTF("Loaded %u autodictionary entries", count); }
-        ck_free(dict);
-
       }
 
     }
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index b60908da..b91d862d 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -187,6 +187,7 @@ static void usage(u8 *argv0, int more_help) {
       "                    used. Defaults to 200.\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_AUTODICT: do not load an offered auto dictionary compiled into a target\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"