about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvanhauser-thc <vh@thc.org>2024-02-04 16:03:12 +0100
committervanhauser-thc <vh@thc.org>2024-02-04 16:03:12 +0100
commitc77709cdd9b50832ed537dfd65d30bc7ffa79e7b (patch)
tree9b1cf5379c7c8080787a3b6bd10c46f3e4909d05
parent27338fcef121c7700a1e2e99cb31cb7106159293 (diff)
downloadafl++-c77709cdd9b50832ed537dfd65d30bc7ffa79e7b.tar.gz
add U256/32byte support
-rw-r--r--include/cmplog.h19
-rw-r--r--instrumentation/afl-compiler-rt.o.c78
-rw-r--r--src/afl-forkserver.c10
-rw-r--r--src/afl-fuzz-redqueen.c10
-rw-r--r--src/afl-fuzz.c6
-rwxr-xr-xtest/test-llvm.sh2
6 files changed, 87 insertions, 38 deletions
diff --git a/include/cmplog.h b/include/cmplog.h
index 6bfc146b..91c2a665 100644
--- a/include/cmplog.h
+++ b/include/cmplog.h
@@ -43,13 +43,11 @@
 
 struct cmp_header {
 
-  unsigned hits : 24;
-  unsigned id : 24;
-  unsigned shape : 5;
-  unsigned type : 2;
-  unsigned attribute : 4;
-  unsigned overflow : 1;
-  unsigned reserved : 4;
+  unsigned hits : 6;       // up to 63 entries, we have CMP_MAP_H = 32
+  unsigned shape : 6;      // 63 bytes, we support 32 max
+  unsigned type : 2;       // 4, we use 3: none, rtn, cmp
+  unsigned attribute : 4;  // 16 for arithmetic comparison types
+  unsigned reserved : 6;
 
 } __attribute__((packed));
 
@@ -59,14 +57,17 @@ struct cmp_operands {
   u64 v1;
   u64 v0_128;
   u64 v1_128;
+  u64 unused;
+  u8  unused1;
+  u8  unused2;
 
 } __attribute__((packed));
 
 struct cmpfn_operands {
 
-  u8 v0[31];
+  u8 v0[32];
   u8 v0_len;
-  u8 v1[31];
+  u8 v1[32];
   u8 v1_len;
 
 } __attribute__((packed));
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index c342334c..a154bcf7 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -186,6 +186,8 @@ __thread u32        __afl_prev_ctx;
 struct cmp_map *__afl_cmp_map;
 struct cmp_map *__afl_cmp_map_backup;
 
+static u8 __afl_cmplog_max_len = 16;
+
 /* Child pid? */
 
 static s32 child_pid;
@@ -730,6 +732,12 @@ static void __afl_map_shm(void) {
 
 #endif  // __AFL_CODE_COVERAGE
 
+  if (!__afl_cmp_map && getenv("AFL_CMPLOG_DEBUG")) {
+
+    __afl_cmp_map_backup = __afl_cmp_map = malloc(sizeof(struct cmp_map));
+
+  }
+
 }
 
 /* unmap SHM. */
@@ -1893,7 +1901,8 @@ void __cmplog_ins_hook1(uint8_t arg1, uint8_t arg2, uint8_t attr) {
 
 void __cmplog_ins_hook2(uint16_t arg1, uint16_t arg2, uint8_t attr) {
 
-  if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
+  if (likely(!__afl_cmp_map)) return;
+  if (unlikely(arg1 == arg2)) return;
 
   uintptr_t k = (uintptr_t)__builtin_return_address(0);
   k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
@@ -1931,7 +1940,8 @@ void __cmplog_ins_hook4(uint32_t arg1, uint32_t arg2, uint8_t attr) {
 
   // fprintf(stderr, "hook4 arg0=%x arg1=%x attr=%u\n", arg1, arg2, attr);
 
-  if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
+  if (likely(!__afl_cmp_map)) return;
+  if (unlikely(arg1 == arg2)) return;
 
   uintptr_t k = (uintptr_t)__builtin_return_address(0);
   k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
@@ -1969,7 +1979,8 @@ void __cmplog_ins_hook8(uint64_t arg1, uint64_t arg2, uint8_t attr) {
 
   // fprintf(stderr, "hook8 arg0=%lx arg1=%lx attr=%u\n", arg1, arg2, attr);
 
-  if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
+  if (likely(!__afl_cmp_map)) return;
+  if (unlikely(arg1 == arg2)) return;
 
   uintptr_t k = (uintptr_t)__builtin_return_address(0);
   k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
@@ -2012,7 +2023,8 @@ void __cmplog_ins_hookN(uint128_t arg1, uint128_t arg2, uint8_t attr,
   // (u64)(arg1 >> 64), (u64)arg1, (u64)(arg2 >> 64), (u64)arg2, size + 1,
   // attr);
 
-  if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
+  if (likely(!__afl_cmp_map)) return;
+  if (unlikely(arg1 == arg2 || size > __afl_cmplog_max_len)) return;
 
   uintptr_t k = (uintptr_t)__builtin_return_address(0);
   k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
@@ -2056,6 +2068,7 @@ void __cmplog_ins_hookN(uint128_t arg1, uint128_t arg2, uint8_t attr,
 void __cmplog_ins_hook16(uint128_t arg1, uint128_t arg2, uint8_t attr) {
 
   if (likely(!__afl_cmp_map)) return;
+  if (16 > __afl_cmplog_max_len) return;
 
   uintptr_t k = (uintptr_t)__builtin_return_address(0);
   k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
@@ -2249,13 +2262,25 @@ void __cmplog_rtn_hook_strn(u8 *ptr1, u8 *ptr2, u64 len) {
 
   // fprintf(stderr, "RTN1 %p %p %u\n", ptr1, ptr2, len);
   if (likely(!__afl_cmp_map)) return;
-  if (unlikely(!len)) return;
-  int len0 = MIN(len, 31);
+  if (unlikely(!len || len > __afl_cmplog_max_len)) return;
+
+  int len0 = MIN(len, 32);
+
   int len1 = strnlen(ptr1, len0);
-  if (len1 < 31) len1 = area_is_valid(ptr1, len1 + 1);
+  if (len1 <= 32) len1 = area_is_valid(ptr1, len1 + 1);
+  if (len1 > __afl_cmplog_max_len) len1 = 0;
+
   int len2 = strnlen(ptr2, len0);
-  if (len2 < 31) len2 = area_is_valid(ptr2, len2 + 1);
-  int l = MAX(len1, len2);
+  if (len2 <= 32) len2 = area_is_valid(ptr2, len2 + 1);
+  if (len2 > __afl_cmplog_max_len) len2 = 0;
+
+  int l;
+  if (!len1)
+    l = len2;
+  else if (!len2)
+    l = len1;
+  else
+    l = MAX(len1, len2);
   if (l < 2) return;
 
   uintptr_t k = (uintptr_t)__builtin_return_address(0);
@@ -2299,10 +2324,18 @@ void __cmplog_rtn_hook_str(u8 *ptr1, u8 *ptr2) {
   // fprintf(stderr, "RTN1 %p %p\n", ptr1, ptr2);
   if (likely(!__afl_cmp_map)) return;
   if (unlikely(!ptr1 || !ptr2)) return;
-  int len1 = strnlen(ptr1, 30) + 1;
-  int len2 = strnlen(ptr2, 30) + 1;
-  int l = MAX(len1, len2);
-  if (l < 3) return;
+  int len1 = strnlen(ptr1, 31) + 1;
+  int len2 = strnlen(ptr2, 31) + 1;
+  if (len1 > __afl_cmplog_max_len) len1 = 0;
+  if (len2 > __afl_cmplog_max_len) len2 = 0;
+  int l;
+  if (!len1)
+    l = len2;
+  else if (!len2)
+    l = len1;
+  else
+    l = MAX(len1, len2);
+  if (l < 2) return;
 
   uintptr_t k = (uintptr_t)__builtin_return_address(0);
   k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
@@ -2344,7 +2377,7 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
 
   /*
     u32 i;
-    if (area_is_valid(ptr1, 31) <= 0 || area_is_valid(ptr2, 31) <= 0) return;
+    if (area_is_valid(ptr1, 32) <= 0 || area_is_valid(ptr2, 32) <= 0) return;
     fprintf(stderr, "rtn arg0=");
     for (i = 0; i < 32; i++)
       fprintf(stderr, "%02x", ptr1[i]);
@@ -2357,10 +2390,10 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
   // fprintf(stderr, "RTN1 %p %p\n", ptr1, ptr2);
   if (likely(!__afl_cmp_map)) return;
   int l1, l2;
-  if ((l1 = area_is_valid(ptr1, 31)) <= 0 ||
-      (l2 = area_is_valid(ptr2, 31)) <= 0)
+  if ((l1 = area_is_valid(ptr1, 32)) <= 0 ||
+      (l2 = area_is_valid(ptr2, 32)) <= 0)
     return;
-  int len = MIN(31, MIN(l1, l2));
+  int len = MIN(__afl_cmplog_max_len, MIN(l1, l2));
 
   // fprintf(stderr, "RTN2 %u\n", len);
   uintptr_t k = (uintptr_t)__builtin_return_address(0);
@@ -2409,7 +2442,7 @@ void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u64 len) {
 #if 0
   /*
     u32 i;
-    if (area_is_valid(ptr1, 31) <= 0 || area_is_valid(ptr2, 31) <= 0) return;
+    if (area_is_valid(ptr1, 32) <= 0 || area_is_valid(ptr2, 32) <= 0) return;
     fprintf(stderr, "rtn_n len=%u arg0=", len);
     for (i = 0; i < len; i++)
       fprintf(stderr, "%02x", ptr1[i]);
@@ -2421,12 +2454,15 @@ void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u64 len) {
 
   // fprintf(stderr, "RTN1 %p %p %u\n", ptr1, ptr2, len);
   if (likely(!__afl_cmp_map)) return;
-  if (unlikely(!len)) return;
-  int l = MIN(31, len);
+  if (!len) return;
+  int l = MIN(32, len), l1, l2;
 
-  if ((l = area_is_valid(ptr1, l)) <= 0 || (l = area_is_valid(ptr2, l)) <= 0)
+  if ((l1 = area_is_valid(ptr1, l)) <= 0 || (l2 = area_is_valid(ptr2, l)) <= 0)
     return;
 
+  len = MIN(l1, l2);
+  if (len > __afl_cmplog_max_len) return;
+
   // fprintf(stderr, "RTN2 %u\n", l);
   uintptr_t k = (uintptr_t)__builtin_return_address(0);
   k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index a3a869d7..c5184639 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -1105,6 +1105,10 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
         fsrv->map_size = tmp_map_size;
 
+      } else {
+
+        fsrv->real_map_size = fsrv->map_size = MAP_SIZE;
+
       }
 
       if ((status & FS_NEW_OPT_SHDMEM_FUZZ)) {
@@ -1208,6 +1212,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
       if ((status & FS_OPT_ERROR) == FS_OPT_ERROR)
         report_error_and_exit(FS_OPT_GET_ERROR(status));
 
+      if (fsrv->cmplog_binary) {
+
+        FATAL("Target was recompiled with outdated CMPLOG, recompile it!\n");
+
+      }
+
       if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) {
 
         // workaround for recent AFL++ versions
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index eead7a8b..eb96de68 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -11,7 +11,7 @@
                         Andrea Fioraldi <andreafioraldi@gmail.com>
 
    Copyright 2016, 2017 Google Inc. All rights reserved.
-   Copyright 2019-2024 AFLplusplus Project. All rights reserved.
+   Copyright 2019-2023 AFLplusplus Project. All rights reserved.
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -2219,15 +2219,15 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
 
   }
 
-  if (l0 == 0 || l1 == 0 || ol0 == 0 || ol1 == 0 || l0 > 31 || l1 > 31 ||
-      ol0 > 31 || ol1 > 31) {
+  if (l0 == 0 || l1 == 0 || ol0 == 0 || ol1 == 0 || l0 > 32 || l1 > 32 ||
+      ol0 > 32 || ol1 > 32) {
 
     l0 = ol0 = hshape;
 
   }
 
   u8  lmax = MAX(l0, ol0);
-  u8  save[40];
+  u8  save[80];
   u32 saved_idx = idx, pre, from = 0, to = 0, i, j;
   u32 its_len = MIN(MIN(lmax, hshape), len - idx);
   its_len = MIN(its_len, taint_len);
@@ -2330,7 +2330,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
     u32 tob64 = 0, fromb64 = 0;
     u32 from_0 = 0, from_x = 0, from_X = 0, from_slash = 0, from_up = 0;
     u32 to_0 = 0, to_x = 0, to_slash = 0, to_up = 0;
-    u8  xor_val[32], arith_val[32], tmp[48];
+    u8  xor_val[64], arith_val[64], tmp[64];
 
     idx = saved_idx;
     its_len = saved_its_len;
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index b556b4b6..34268113 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -956,9 +956,11 @@ int main(int argc, char **argv_orig, char **envp) {
       break;
 
       case 'd':
-      case 'D':                                    /* old deterministic */
+      case 'D':                                        /* old deterministic */
 
-        WARNF("Parameters -d and -D are deprecated, a new enhanced deterministic fuzzing is active by default, to disable it use -z");
+        WARNF(
+            "Parameters -d and -D are deprecated, a new enhanced deterministic "
+            "fuzzing is active by default, to disable it use -z");
         break;
 
       case 'z':                                         /* no deterministic */
diff --git a/test/test-llvm.sh b/test/test-llvm.sh
index 53bbd7b4..aef7a5e2 100755
--- a/test/test-llvm.sh
+++ b/test/test-llvm.sh
@@ -62,7 +62,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
       $ECHO "$RED[!] llvm_mode threadsafe instrumentation failed"
       CODE=1
     }
-    rm -f test-instr.ts.0 test-instr.ts.1
+    rm -f test-instr.ts.0 test-instr.ts.1 test-instr.ts
   } || {
     $ECHO "$RED[!] llvm_mode (threadsafe) failed"
     CODE=1