about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvanhauser-thc <vh@thc.org>2022-07-19 12:24:03 +0200
committervanhauser-thc <vh@thc.org>2022-07-19 12:24:03 +0200
commitca4a8c0f920f83c86aeb599b94b50fce2af68389 (patch)
tree0c59bc591d0c8991775c0db8655e4b9c5321b666
parentb847e0f414e7b310e1a68bc501d4e2453bfce70e (diff)
downloadafl++-ca4a8c0f920f83c86aeb599b94b50fce2af68389.tar.gz
post_process 0/NULL return support
-rw-r--r--docs/Changelog.md3
-rw-r--r--docs/custom_mutators.md4
-rw-r--r--src/afl-fuzz-bitmap.c15
-rw-r--r--src/afl-fuzz-cmplog.c13
-rw-r--r--src/afl-fuzz-mutators.c18
-rw-r--r--src/afl-fuzz-python.c11
-rw-r--r--src/afl-fuzz-run.c33
7 files changed, 82 insertions, 15 deletions
diff --git a/docs/Changelog.md b/docs/Changelog.md
index ff3907f0..c7414ff2 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -9,6 +9,9 @@ Want to stay in the loop on major new features? Join our mailing list by
 sending a mail to <afl-users+subscribe@googlegroups.com>.
 
 ### Version ++4.02a (dev)
+  - afl-fuzz:
+    - change post_process hook to allow returning NULL and 0 length to
+      tell afl-fuzz to skip this mutated input
   - gcc_plugin:
     - Adacore submitted CMPLOG support to the gcc_plugin! :-)
   - llvm_mode:
diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md
index 7b4e0516..d84e4e02 100644
--- a/docs/custom_mutators.md
+++ b/docs/custom_mutators.md
@@ -159,6 +159,10 @@ def deinit():  # optional for Python
     This can return any python object that implements the buffer protocol and
     supports PyBUF_SIMPLE. These include bytes, bytearray, etc.
 
+    You can decide in the post_process mutator to not send the mutated data
+    to the target, e.g. if it is too short, too corrupted, etc. If so,
+    return a NULL buffer and zero length (or a 0 length string in Python).
+
 - `queue_new_entry` (optional):
 
     This methods is called after adding a new test case to the queue. If the
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 089f7bb5..b3a10bb7 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -647,8 +647,19 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
 
       if (afl->fsrv.exec_tmout < afl->hang_tmout) {
 
-        u8 new_fault;
-        len = write_to_testcase(afl, &mem, len, 0);
+        u8  new_fault;
+        u32 tmp_len = write_to_testcase(afl, &mem, len, 0);
+
+        if (likely(tmp_len)) {
+
+          len = tmp_len;
+
+        } else {
+
+          len = write_to_testcase(afl, &mem, len, 1);
+
+        }
+
         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 258d9ea7..d0c829e2 100644
--- a/src/afl-fuzz-cmplog.c
+++ b/src/afl-fuzz-cmplog.c
@@ -47,9 +47,18 @@ void cmplog_exec_child(afl_forkserver_t *fsrv, char **argv) {
 
 u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
 
-  u8 fault;
+  u8  fault;
+  u32 tmp_len = write_to_testcase(afl, (void **)&out_buf, len, 0);
 
-  write_to_testcase(afl, (void **)&out_buf, len, 0);
+  if (likely(tmp_len)) {
+
+    len = tmp_len;
+
+  } else {
+
+    len = write_to_testcase(afl, (void **)&out_buf, len, 1);
+
+  }
 
   fault = fuzz_run_target(afl, &afl->cmplog_fsrv, afl->fsrv.exec_tmout);
 
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index dd97a7d3..b9daebfa 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -430,13 +430,21 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
 
       retlen = write_to_testcase(afl, (void **)&retbuf, retlen, 0);
 
-      fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
-      ++afl->trim_execs;
+      if (unlikely(!retlen)) {
+
+        ++afl->trim_execs;
+
+      } else {
 
-      if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; }
+        fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
+        ++afl->trim_execs;
 
-      classify_counts(&afl->fsrv);
-      cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
+        if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; }
+
+        classify_counts(&afl->fsrv);
+        cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
+
+      }
 
     }
 
diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c
index a3d864c3..a43d80bb 100644
--- a/src/afl-fuzz-python.c
+++ b/src/afl-fuzz-python.c
@@ -535,7 +535,16 @@ size_t post_process_py(void *py_mutator, u8 *buf, size_t buf_size,
 
     Py_DECREF(py_value);
 
-    *out_buf = (u8 *)py->post_process_buf.buf;
+    if (unlikely(py->post_process_buf.len == 0)) {
+
+      *out_buf = NULL;
+
+    } else {
+
+      *out_buf = (u8 *)py->post_process_buf.buf;
+
+    }
+
     return py->post_process_buf.len;
 
   } else {
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index 0f3be1a7..b97a8e6a 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -109,17 +109,36 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) {
 
         if (unlikely(!new_buf && new_size <= 0)) {
 
-          FATAL("Custom_post_process failed (ret: %lu)",
-                (long unsigned)new_size);
+          new_size = 0;
+          new_buf = new_mem;
+          // FATAL("Custom_post_process failed (ret: %lu)", (long
+          // unsigned)new_size);
 
-        }
+        } else {
 
-        new_mem = new_buf;
+          new_mem = new_buf;
+
+        }
 
       }
 
     });
 
+    if (unlikely(!new_size)) {
+
+      // perform dummy runs (fix = 1), but skip all others
+      if (fix) {
+
+        new_size = len;
+
+      } else {
+
+        return 0;
+
+      }
+
+    }
+
     if (unlikely(new_size < afl->min_length && !fix)) {
 
       new_size = afl->min_length;
@@ -969,7 +988,11 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
 
   u8 fault;
 
-  len = write_to_testcase(afl, (void **)&out_buf, len, 0);
+  if (unlikely(len = write_to_testcase(afl, (void **)&out_buf, len, 0) == 0)) {
+
+    return 0;
+
+  }
 
   fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);