about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorDominik Maier <domenukk@gmail.com>2021-04-30 13:35:24 +0200
committerDominik Maier <domenukk@gmail.com>2021-04-30 13:37:59 +0200
commite9d2f72382cab75832721d859c3e731da071435d (patch)
tree98f84e58d0ee55d04a4e6d8c4e2ec6fe90075bd8 /src
parent758bc770a8f2a35e1ec142f9564f2aeac3ce33bc (diff)
downloadafl++-e9d2f72382cab75832721d859c3e731da071435d.tar.gz
fixed potential double free in custom trim (#881)
Diffstat (limited to 'src')
-rw-r--r--src/afl-fuzz-mutators.c23
-rw-r--r--src/afl-fuzz-one.c8
-rw-r--r--src/afl-fuzz-run.c8
3 files changed, 27 insertions, 12 deletions
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index c99d9a4d..d8db8676 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -305,9 +305,13 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
 
 }
 
-u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
+// Custom testcase trimming.
+u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 **in_buf_p,
                     struct custom_mutator *mutator) {
 
+  // We need to pass pointers around, as growing testcases may need to realloc.
+  u8 *in_buf = *in_buf_p;
+
   u8  needs_write = 0, fault = 0;
   u32 trim_exec = 0;
   u32 orig_len = q->len;
@@ -397,14 +401,21 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
 
     if (likely(retlen && cksum == q->exec_cksum)) {
 
-      if (afl_realloc((void **)&in_buf, retlen) == NULL) {
+      // Check if we got a new retbuf and to memcpy our buf.
+      if (in_buf != retbuf) {
 
-        FATAL("can not allocate memory for trim");
+        if (afl_realloc((void **)in_buf_p, retlen) == NULL) {
 
-      }
+          FATAL("can not allocate memory for trim");
+
+        }
 
-      memcpy(in_buf, retbuf, retlen);
-      q->len = retlen;
+        in_buf = *in_buf_p;
+
+        memcpy(in_buf, retbuf, retlen);
+        q->len = retlen;
+
+      }
 
       /* Let's save a clean trace, which will be needed by
          update_bitmap_score once we're done with the trimming stuff. */
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index d72d4145..ed815cb4 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -508,7 +508,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
 
     u32 old_len = afl->queue_cur->len;
 
-    u8 res = trim_case(afl, afl->queue_cur, in_buf);
+    u8 res = trim_case(afl, afl->queue_cur, &in_buf);
     orig_in = in_buf = queue_testcase_get(afl, afl->queue_cur);
 
     if (unlikely(res == FSRV_RUN_ERROR)) {
@@ -3007,16 +3007,16 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
 
     u32 old_len = afl->queue_cur->len;
 
-    u8 res = trim_case(afl, afl->queue_cur, in_buf);
+    u8 res = trim_case(afl, afl->queue_cur, &in_buf);
     orig_in = in_buf = queue_testcase_get(afl, afl->queue_cur);
 
-    if (res == FSRV_RUN_ERROR) {
+    if (unlikely(res == FSRV_RUN_ERROR)) {
 
       FATAL("Unable to execute target application");
 
     }
 
-    if (afl->stop_soon) {
+    if (unlikely(afl->stop_soon)) {
 
       ++afl->cur_skipped_paths;
       goto abandon_entry;
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index 832f17bb..a7b071a5 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -720,7 +720,10 @@ void sync_fuzzers(afl_state_t *afl) {
    trimmer uses power-of-two increments somewhere between 1/16 and 1/1024 of
    file size, to keep the stage short and sweet. */
 
-u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
+u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 **in_buf_p) {
+
+  // We need to pass pointers around, as growing testcases may need to realloc.
+  u8 *in_buf = *in_buf_p;
 
   u32 orig_len = q->len;
 
@@ -734,7 +737,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
 
       if (el->afl_custom_trim) {
 
-        trimmed_case = trim_case_custom(afl, q, in_buf, el);
+        trimmed_case = trim_case_custom(afl, q, in_buf_p, el);
+        in_buf = *in_buf_p;
         custom_trimmed = true;
 
       }