about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2024-09-24 11:57:36 +0300
committerGitHub <noreply@github.com>2024-09-24 11:57:36 +0300
commitd21fb1a558b25c4f46692fa999c0028dfe0eecc0 (patch)
treec503336edd8dc0ee4f8385c0fbc91a5e818ffcfb
parent75d8c47a6b8ae94cd7ded2f0574e4d35a2021ab7 (diff)
parent2e6c74f9b9d3bc70ef9474eb08592b9cd151d3c7 (diff)
downloadafl++-d21fb1a558b25c4f46692fa999c0028dfe0eecc0.tar.gz
Merge pull request #2214 from AFLplusplus/dev
push to stable
-rw-r--r--.github/workflows/ci.yml42
-rw-r--r--CONTRIBUTING.md4
-rw-r--r--benchmark/COMPARISON.md1
-rw-r--r--docs/env_variables.md2
-rw-r--r--docs/fuzzing_in_depth.md2
-rw-r--r--include/forkserver.h11
-rw-r--r--nyx_mode/LIBNYX_VERSION2
-rw-r--r--nyx_mode/PACKER_VERSION2
m---------nyx_mode/libnyx0
m---------nyx_mode/packer0
-rw-r--r--qemu_mode/QEMUAFL_VERSION2
-rw-r--r--qemu_mode/README.persistent.md15
m---------qemu_mode/qemuafl0
-rw-r--r--src/afl-forkserver.c16
-rw-r--r--src/afl-fuzz-init.c47
-rw-r--r--src/afl-fuzz-stats.c11
-rw-r--r--src/afl-fuzz.c19
-rwxr-xr-xtest/test-llvm.sh8
18 files changed, 125 insertions, 59 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ed382fbb..187ed011 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -34,23 +34,25 @@ jobs:
         run: export NO_NYX=1; export ASAN_BUILD=1; export LLVM_CONFIG=llvm-config-12; make ASAN_BUILD=1 NO_NYX=1 LLVM_CONFIG=llvm-config-12 distrib
       - name: run tests
         run: sudo -E ./afl-system-config; make tests
- # macos:
- #   runs-on: macOS-latest
- #   env:
- #     AFL_MAP_SIZE: 65536
- #     AFL_SKIP_CPUFREQ: 1
- #     AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
- #   steps:
- #     - uses: actions/checkout@v3
- #     - name: install
- #       run: brew install make gcc llvm
- #     - name: fix install
- #       run: cd /usr/local/bin; ln -s gcc-11 gcc; ln -s g++-11 g++; which gcc; gcc -v
- #     - name: build
- #       run: export PATH=/usr/local/Cellar/llvm/*/":$PATH"; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; sudo -E ./afl-system-config; gmake ASAN_BUILD=1
- #     - name: frida
- #       run: export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; cd frida_mode; gmake
- #     - name: run tests
- #       run: sudo -E ./afl-system-config; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export PATH=/usr/local/Cellar/llvm/*/":/usr/local/bin:$PATH"; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; gmake tests
- #     - name: force frida test for MacOS
- #       run: export AFL_PATH=`pwd`; /usr/local/bin/gcc -o test-instr test-instr.c; mkdir in; echo > in/in; AFL_NO_UI=1 ./afl-fuzz -O -i in -o out -V 5 -- ./test-instr
+  macos:
+    runs-on: macOS-latest
+    env:
+      AFL_MAP_SIZE: 65536
+      AFL_SKIP_CPUFREQ: 1
+      AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
+    steps:
+      - uses: actions/checkout@v3
+      - name: install
+        run: brew install make gcc llvm
+#     - name: fix install
+#       run: cd /usr/local/bin; ln -s gcc-11 gcc; ln -s g++-11 g++; which gcc; gcc -v
+#      - name: build
+#        run: export PATH=/usr/local/Cellar/llvm/*/":$PATH"; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; sudo -E ./afl-system-config; gmake ASAN_BUILD=1 afl-fuzz
+      - name: build
+        run: sudo -E ./afl-system-config; gmake ASAN_BUILD=1 afl-fuzz
+#     - name: frida
+#       run: export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; cd frida_mode; gmake
+#     - name: run tests
+#       run: sudo -E ./afl-system-config; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export PATH=/usr/local/Cellar/llvm/*/":/usr/local/bin:$PATH"; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; gmake tests
+#     - name: force frida test for MacOS
+#       run: export AFL_PATH=`pwd`; /usr/local/bin/gcc -o test-instr test-instr.c; mkdir in; echo > in/in; AFL_NO_UI=1 ./afl-fuzz -O -i in -o out -V 5 -- ./test-instr
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8b4dcb6d..40f11ce8 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -48,7 +48,7 @@ When working on the docs, please keep the following guidelines in mind:
   * Don't: fuzzing-network-service.md
 * Use a maximum of 80 characters per line to make reading in a console easier.
 * Make all pull requests against `dev`, see
-  [#how-to-submit-a-pull-request-to-afl](#how-to-submit-a-pull-request-to-afl).
+  [#how-to-submit-a-pull-request](#how-to-submit-a-pull-request).
 
 And finally, here are some best practices for writing docs content:
 
@@ -57,4 +57,4 @@ And finally, here are some best practices for writing docs content:
 * Use bulleted lists to present similar content in a way that makes it easy to
   scan.
 * Use numbered lists for procedures or prioritizing.
-* Link to related content, for example, prerequisites or in-depth discussions.
\ No newline at end of file
+* Link to related content, for example, prerequisites or in-depth discussions.
diff --git a/benchmark/COMPARISON.md b/benchmark/COMPARISON.md
index e16ef213..92b6be28 100644
--- a/benchmark/COMPARISON.md
+++ b/benchmark/COMPARISON.md
@@ -11,3 +11,4 @@
 |AMD Ryzen 9 6900HS with Radeon Graphics             | 4745  | 16      | 135501     | 991133    | both         |
 |AMD Ryzen 9 7950X3D 16-Core Processor               | 5400  | 32      | 71566      | 1566279   | system       |
 |AMD Ryzen 9 7950X3D 16-Core Processor               | 5478  | 32      | 161960     | 2173959   | both         |
+|Ampere Altra Q80-30                                 | 0     | 80      | 54477      | 1604482   | system       |
diff --git a/docs/env_variables.md b/docs/env_variables.md
index 8c2d5848..3db46b36 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -610,7 +610,7 @@ checks or alter some of the more exotic semantics of the tool:
     see [rpc_statsd.md](rpc_statsd.md).
 
   - `AFL_SYNC_TIME` allows you to specify a different minimal time (in minutes)
-    between fuzzing instances synchronization. Default sync time is 30 minutes,
+    between fuzzing instances synchronization. Default sync time is 20 minutes,
     note that time is halved for -M main nodes.
 
   - `AFL_NO_SYNC` disables any syncing whatsoever and takes priority on all
diff --git a/docs/fuzzing_in_depth.md b/docs/fuzzing_in_depth.md
index 82437807..79d0500d 100644
--- a/docs/fuzzing_in_depth.md
+++ b/docs/fuzzing_in_depth.md
@@ -632,7 +632,7 @@ crash or timeout during startup.
 
 Also, it is recommended to set `export AFL_IMPORT_FIRST=1` to load test cases
 from other fuzzers in the campaign first. But note that can slow down the start
-of the first fuzz by quite a lot of you have many fuzzers and/or many seeds.
+of the first fuzz by quite a lot if you have many fuzzers and/or many seeds.
 
 If you have a large corpus, a corpus from a previous run or are fuzzing in a CI,
 then also set `export AFL_CMPLOG_ONLY_NEW=1` and `export AFL_FAST_CAL=1`.
diff --git a/include/forkserver.h b/include/forkserver.h
index 6c649528..db1832c4 100644
--- a/include/forkserver.h
+++ b/include/forkserver.h
@@ -89,11 +89,14 @@ typedef struct {
   bool (*nyx_config_set_aux_buffer_size)(void    *config,
                                          uint32_t aux_buffer_size);
 
+  uint64_t (*nyx_get_target_hash64)(void *config);
+
+  void (*nyx_config_free)(void *config);
+
 } nyx_plugin_handler_t;
 
 /* Imports helper functions to enable Nyx mode (Linux only )*/
 nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary);
-
 #endif
 
 typedef struct afl_forkserver {
@@ -204,6 +207,7 @@ typedef struct afl_forkserver {
   bool                  nyx_use_tmp_workdir;
   char                 *nyx_tmp_workdir_path;
   s32                   nyx_log_fd;
+  u64                   nyx_target_hash64;
 #endif
 
 #ifdef __AFL_CODE_COVERAGE
@@ -241,6 +245,11 @@ void              afl_fsrv_killall(void);
 void              afl_fsrv_deinit(afl_forkserver_t *fsrv);
 void              afl_fsrv_kill(afl_forkserver_t *fsrv);
 
+#ifdef __linux__
+void nyx_load_target_hash(afl_forkserver_t *fsrv);
+#endif
+
+
 #ifdef __APPLE__
   #define MSG_FORK_ON_APPLE                                                    \
     "    - On MacOS X, the semantics of fork() syscalls are non-standard and " \
diff --git a/nyx_mode/LIBNYX_VERSION b/nyx_mode/LIBNYX_VERSION
index 9aae19be..5f7c9a5b 100644
--- a/nyx_mode/LIBNYX_VERSION
+++ b/nyx_mode/LIBNYX_VERSION
@@ -1 +1 @@
-6833d23
+ea6ceb9
\ No newline at end of file
diff --git a/nyx_mode/PACKER_VERSION b/nyx_mode/PACKER_VERSION
index cc20a3b6..0b9e5d4e 100644
--- a/nyx_mode/PACKER_VERSION
+++ b/nyx_mode/PACKER_VERSION
@@ -1 +1 @@
-bcf3e24
+6067e5c
diff --git a/nyx_mode/libnyx b/nyx_mode/libnyx
-Subproject 6833d236dfe785a8a23d8c8d79e74c99fa63500
+Subproject ea6ceb994ab975b81aea0daaf64b92a3066c1e8
diff --git a/nyx_mode/packer b/nyx_mode/packer
-Subproject bcf3e248b660764f48af54232a3388389a2dfc2
+Subproject 6067e5c0ffb3e9aec35aa3aef29b3e390dd313b
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION
index 9a62db20..ecff1e72 100644
--- a/qemu_mode/QEMUAFL_VERSION
+++ b/qemu_mode/QEMUAFL_VERSION
@@ -1 +1 @@
-847b43acb1
+d40bcd8965
diff --git a/qemu_mode/README.persistent.md b/qemu_mode/README.persistent.md
index ef8fb71b..e89823b5 100644
--- a/qemu_mode/README.persistent.md
+++ b/qemu_mode/README.persistent.md
@@ -99,10 +99,7 @@ be lost at the second execution of the loop.
 
 ### 2.5) Resetting the memory state
 
-This option restores the memory state using the AFL++ Snapshot LKM if loaded.
-Otherwise, all the writeable pages are restored.
-
-To enable this option, set `AFL_QEMU_PERSISTENT_MEM=1`.
+(obsolete chapter)
 
 ### 2.6) Reset on exit()
 
@@ -113,15 +110,7 @@ The environment variable is `AFL_QEMU_PERSISTENT_EXITS`.
 
 ### 2.7) Snapshot
 
-`AFL_QEMU_SNAPSHOT=address` is just a "syntactical sugar" environment variable
-that is equivalent to the following set of variables:
-
-```
-AFL_QEMU_PERSISTENT_ADDR=address
-AFL_QEMU_PERSISTENT_GPR=1
-AFL_QEMU_PERSISTENT_MEM=1
-AFL_QEMU_PERSISTENT_EXITS=1
-```
+obsolete
 
 ## 3) Optional parameters
 
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
-Subproject 847b43acb11530e775013dc24b54c6e27406179
+Subproject d40bcd896521e5a1f0c9939d020fe6291dbdd37
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index c7c493cf..ae3c7ccc 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -136,6 +136,12 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) {
       dlsym(handle, "nyx_config_set_aux_buffer_size");
   if (plugin->nyx_config_set_aux_buffer_size == NULL) { goto fail; }
 
+  plugin->nyx_get_target_hash64 = dlsym(handle, "nyx_get_target_hash64");
+  if (plugin->nyx_get_target_hash64 == NULL) { goto fail; }
+
+  plugin->nyx_config_free = dlsym(handle, "nyx_config_free");
+  if (plugin->nyx_get_target_hash64 == NULL) { goto fail; }
+
   OKF("libnyx plugin is ready!");
   return plugin;
 
@@ -224,6 +230,7 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
   fsrv->nyx_use_tmp_workdir = false;
   fsrv->nyx_tmp_workdir_path = NULL;
   fsrv->nyx_log_fd = -1;
+  fsrv->nyx_target_hash64 = 0;
 #endif
 
   // this structure needs default so we initialize it if this was not done
@@ -527,6 +534,15 @@ static void report_error_and_exit(int error) {
 
 }
 
+#ifdef __linux__
+void nyx_load_target_hash(afl_forkserver_t *fsrv) {
+  void *nyx_config = fsrv->nyx_handlers->nyx_config_load(fsrv->target_path);
+  fsrv->nyx_target_hash64 = fsrv->nyx_handlers->nyx_get_target_hash64(nyx_config);
+  fsrv->nyx_handlers->nyx_config_free(nyx_config);
+}
+#endif
+
+
 /* Spins up fork server. The idea is explained here:
 
    https://lcamtuf.blogspot.com/2014/10/fuzzing-binaries-without-execve.html
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index d3085d42..9eaa661d 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -1231,6 +1231,25 @@ void perform_dry_run(afl_state_t *afl) {
           ck_write(fd, use_mem, read_len, crash_fn);
           close(fd);
 
+#ifdef __linux__
+          if (afl->fsrv.nyx_mode) {
+
+            u8 crash_log_fn[PATH_MAX];
+
+            snprintf(crash_log_fn, PATH_MAX, "%s.log", crash_fn);
+            fd = open(crash_log_fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
+            if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", crash_log_fn); }
+
+            u32 nyx_aux_string_len = afl->fsrv.nyx_handlers->nyx_get_aux_string(
+                afl->fsrv.nyx_runner, afl->fsrv.nyx_aux_string,
+                afl->fsrv.nyx_aux_string_len);
+
+            ck_write(fd, afl->fsrv.nyx_aux_string, nyx_aux_string_len, crash_log_fn);
+            close(fd);
+
+          }
+#endif
+           
           afl->last_crash_time = get_cur_time();
           afl->last_crash_execs = afl->fsrv.total_execs;
 
@@ -2443,21 +2462,20 @@ void check_crash_handling(void) {
 
   if (read(fd, &fchar, 1) == 1 && fchar == '|') {
 
-    SAYF(
-        "\n" cLRD "[-] " cRST
-        "Your system is configured to send core dump notifications to an\n"
-        "    external utility. This will cause issues: there will be an "
-        "extended delay\n"
-        "    between stumbling upon a crash and having this information "
-        "relayed to the\n"
-        "    fuzzer via the standard waitpid() API.\n"
-        "    If you're just experimenting, set "
-        "'AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1'.\n\n"
+    SAYF("\n" cLRD "[-] " cRST
+         "Your system is configured to send core dump notifications to an\n"
+         "    external utility. This will cause issues: there will be an "
+         "extended delay\n"
+         "    between stumbling upon a crash and having this information "
+         "relayed to the\n"
+         "    fuzzer via the standard waitpid() API.\n"
+         "    If you're just experimenting, set "
+         "'AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1'.\n\n"
 
-        "    To avoid having crashes misinterpreted as timeouts, please \n"
-        "    temporarily modify /proc/sys/kernel/core_pattern, like so:\n\n"
+         "    To avoid having crashes misinterpreted as timeouts, please \n"
+         "    temporarily modify /proc/sys/kernel/core_pattern, like so:\n\n"
 
-        "    echo core | sudo tee /proc/sys/kernel/core_pattern\n");
+         "    echo core | sudo tee /proc/sys/kernel/core_pattern\n");
 
     if (!getenv("AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES")) {
 
@@ -2866,6 +2884,7 @@ void check_binary(afl_state_t *afl, u8 *fname) {
   if (strchr(fname, '/') || !(env_path = getenv("PATH"))) {
 
     afl->fsrv.target_path = ck_strdup(fname);
+
 #ifdef __linux__
     if (afl->fsrv.nyx_mode) {
 
@@ -2886,8 +2905,8 @@ void check_binary(afl_state_t *afl, u8 *fname) {
             afl->fsrv.target_path);
 
     }
-
 #endif
+
     if (stat(afl->fsrv.target_path, &st) || !S_ISREG(st.st_mode) ||
         !(st.st_mode & 0111) || (f_len = st.st_size) < 4) {
 
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 9f5f59c0..b1a84cb6 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -80,7 +80,18 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) {
 
   snprintf(fn2, PATH_MAX, "%s/target_hash", afl->out_dir);
   FILE *f2 = create_ffile(fn2);
+
+#ifdef __linux__
+  if (afl->fsrv.nyx_mode) {
+    nyx_load_target_hash(&afl->fsrv);
+    fprintf(f2, "%llx\n", afl->fsrv.nyx_target_hash64);
+  }
+  else {
+    fprintf(f2, "%p\n", (void *)get_binary_hash(afl->fsrv.target_path));
+  }
+#else
   fprintf(f2, "%p\n", (void *)get_binary_hash(afl->fsrv.target_path));
+#endif
   fclose(f2);
 
   snprintf(fn, PATH_MAX, "%s/fuzzer_setup", afl->out_dir);
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 726a2260..a2fd4b76 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1505,7 +1505,7 @@ int main(int argc, char **argv_orig, char **envp) {
   #ifdef __linux__
   if (afl->fsrv.nyx_mode) {
 
-    OKF("AFL++ Nyx mode is enabled (developed and mainted by Sergej Schumilo)");
+    OKF("AFL++ Nyx mode is enabled (developed and maintained by Sergej Schumilo)");
     OKF("Nyx is open source, get it at https://github.com/Nyx-Fuzz");
 
   }
@@ -2225,9 +2225,24 @@ int main(int argc, char **argv_orig, char **envp) {
 
   if (afl->in_place_resume && !afl->afl_env.afl_no_fastresume) {
 
+#ifdef __linux__
+    u64 target_hash = 0;
+    if (afl->fsrv.nyx_mode) {
+      nyx_load_target_hash(&afl->fsrv);
+      target_hash = afl->fsrv.nyx_target_hash64;
+    }
+    else {
+      target_hash = get_binary_hash(afl->fsrv.target_path);
+    }
+#else
     u64 target_hash = get_binary_hash(afl->fsrv.target_path);
+#endif
 
-    if (!target_hash || prev_target_hash != target_hash) {
+    if ((!target_hash || prev_target_hash != target_hash)
+#ifdef __linux__
+      || (afl->fsrv.nyx_mode && target_hash == 0)
+#endif
+    ) {
 
       ACTF("Target binary is different, cannot perform FAST RESUME!");
 
diff --git a/test/test-llvm.sh b/test/test-llvm.sh
index 4dd35e6e..8236d138 100755
--- a/test/test-llvm.sh
+++ b/test/test-llvm.sh
@@ -269,9 +269,9 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
     {
       mkdir -p in
       echo 00000000000000000000000000000000 > in/in
-      AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -Z -l 3 -m none -V30 -i in -o out -c 0 -- ./test-cmplog >>errors 2>&1
+      AFL_BENCH_UNTIL_CRASH=1 AFL_NO_CRASH_README=1 AFL_SHA1_FILENAMES=1 ../afl-fuzz -Z -l 3 -m none -V30 -i in -o out -c 0 -- ./test-cmplog >>errors 2>&1
     } >>errors 2>&1
-    test -n "$( ls out/default/crashes/id:000000* out/default/hangs/id:000000* 2>/dev/null )" && {
+    test -n "$( ls out/default/crashes/* out/default/hangs/* 2>/dev/null )" && {
       $ECHO "$GREEN[+] afl-fuzz is working correctly with llvm_mode cmplog"
     } || {
       echo CUT------------------------------------------------------------------CUT
@@ -280,6 +280,10 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
       $ECHO "$RED[!] afl-fuzz is not working correctly with llvm_mode cmplog"
       CODE=1
     }
+    test -n "$( ls out/default/crashes/id:000000* out/default/hangs/id:000000* 2>/dev/null )" && {
+      $ECHO "$RED[!] filenames are not SHA1"
+      CODE=1
+    } || true
   } || {
     $ECHO "$YELLOW[-] we cannot test llvm_mode cmplog because it is not present"
     INCOMPLETE=1