about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorvanhauser-thc <vh@thc.org>2021-02-17 19:10:05 +0100
committervanhauser-thc <vh@thc.org>2021-02-17 19:10:05 +0100
commit5dd35f5281afec0955c08fe9f99e3c83222b7764 (patch)
tree15ef219387edd067d9619dc903fcb0de6faac52d /src
parent4c47b242eb976b8518ab8884733d02465f02d90a (diff)
downloadafl++-5dd35f5281afec0955c08fe9f99e3c83222b7764.tar.gz
fix a rare i2s illegal memory access
Diffstat (limited to 'src')
-rw-r--r--src/afl-fuzz-redqueen.c71
1 files changed, 58 insertions, 13 deletions
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index bbe35fe5..3ac7ba11 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -808,37 +808,82 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
     // Try to identify transform magic
     if (pattern != o_pattern && repl == changed_val && attr <= IS_EQUAL) {
 
-      u64 *ptr = (u64 *)&buf[idx];
-      u64 *o_ptr = (u64 *)&orig_buf[idx];
-      u64  b_val, o_b_val, mask;
+      u64 b_val, o_b_val, mask;
+      u8  bytes;
 
       switch (SHAPE_BYTES(h->shape)) {
 
         case 0:
         case 1:
-          b_val = (u64)(*ptr % 0x100);
+          bytes = 1;
+          break;
+        case 2:
+          bytes = 2;
+          break;
+        case 3:
+        case 4:
+          bytes = 4;
+          break;
+        default:
+          bytes = 8;
+
+      }
+
+      // necessary for preventing heap access overflow
+      bytes = MIN(bytes, len - idx);
+
+      switch (bytes) {
+
+        case 0:                        // cannot happen
+          b_val = o_b_val = mask = 0;  // keep the linters happy
+          break;
+        case 1: {
+
+          u8 *ptr = (u8 *)&buf[idx];
+          u8 *o_ptr = (u8 *)&orig_buf[idx];
+          b_val = (u64)(*ptr);
           o_b_val = (u64)(*o_ptr % 0x100);
           mask = 0xff;
           break;
+
+        }
+
         case 2:
-        case 3:
-          b_val = (u64)(*ptr % 0x10000);
-          o_b_val = (u64)(*o_ptr % 0x10000);
+        case 3: {
+
+          u16 *ptr = (u16 *)&buf[idx];
+          u16 *o_ptr = (u16 *)&orig_buf[idx];
+          b_val = (u64)(*ptr);
+          o_b_val = (u64)(*o_ptr);
           mask = 0xffff;
           break;
+
+        }
+
         case 4:
         case 5:
         case 6:
-        case 7:
-          b_val = (u64)(*ptr % 0x100000000);
-          o_b_val = (u64)(*o_ptr % 0x100000000);
+        case 7: {
+
+          u32 *ptr = (u32 *)&buf[idx];
+          u32 *o_ptr = (u32 *)&orig_buf[idx];
+          b_val = (u64)(*ptr);
+          o_b_val = (u64)(*o_ptr);
           mask = 0xffffffff;
           break;
-        default:
-          b_val = *ptr;
-          o_b_val = *o_ptr;
+
+        }
+
+        default: {
+
+          u64 *ptr = (u64 *)&buf[idx];
+          u64 *o_ptr = (u64 *)&orig_buf[idx];
+          b_val = (u64)(*ptr);
+          o_b_val = (u64)(*o_ptr);
           mask = 0xffffffffffffffff;
 
+        }
+
       }
 
       // test for arithmetic, eg. "if ((user_val - 0x1111) == 0x1234) ..."