about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2020-02-28 00:35:59 +0100
committervan Hauser <vh@thc.org>2020-02-28 00:35:59 +0100
commitf526bb2ecb6dbbf6b155f12f6e8e12596cd1b84c (patch)
tree49ee1b7b7e2ffa0df10c7ada5687a5cc049f0e03
parent4e37e12c06dda8914dac5175e2f02d3106a3ac9f (diff)
downloadafl++-f526bb2ecb6dbbf6b155f12f6e8e12596cd1b84c.tar.gz
better alloc-inl.h
-rw-r--r--include/alloc-inl.h193
-rw-r--r--include/config.h5
2 files changed, 198 insertions, 0 deletions
diff --git a/include/alloc-inl.h b/include/alloc-inl.h
index a3cc63ca..19ac86e9 100644
--- a/include/alloc-inl.h
+++ b/include/alloc-inl.h
@@ -34,6 +34,197 @@
 #include "types.h"
 #include "debug.h"
 
+#ifndef _WANT_ORIGINAL_AFL_ALLOC
+// afl++ stuff without memory corruption checks - for speed
+
+/* User-facing macro to sprintf() to a dynamically allocated buffer. */
+
+#define alloc_printf(_str...)                        \
+  ({                                                 \
+                                                     \
+    u8* _tmp;                                        \
+    s32 _len = snprintf(NULL, 0, _str);              \
+    if (_len < 0) FATAL("Whoa, snprintf() fails?!"); \
+    _tmp = ck_alloc(_len + 1);                       \
+    snprintf((char*)_tmp, _len + 1, _str);           \
+    _tmp;                                            \
+                                                     \
+  })
+
+/* Macro to enforce allocation limits as a last-resort defense against
+   integer overflows. */
+
+#define ALLOC_CHECK_SIZE(_s)                                          \
+  do {                                                                \
+                                                                      \
+    if ((_s) > MAX_ALLOC) ABORT("Bad alloc request: %u bytes", (_s)); \
+                                                                      \
+  } while (0)
+
+/* Macro to check malloc() failures and the like. */
+
+#define ALLOC_CHECK_RESULT(_r, _s)                                    \
+  do {                                                                \
+                                                                      \
+    if (!(_r)) ABORT("Out of memory: can't allocate %u bytes", (_s)); \
+                                                                      \
+  } while (0)
+
+/* Allocator increments for ck_realloc_block(). */
+
+#define ALLOC_BLK_INC 256
+
+/* Allocate a buffer, explicitly not zeroing it. Returns NULL for zero-sized
+   requests. */
+
+static inline void* DFL_ck_alloc_nozero(u32 size) {
+
+  u8* ret;
+
+  if (!size) return NULL;
+
+  ALLOC_CHECK_SIZE(size);
+  ret = malloc(size);
+  ALLOC_CHECK_RESULT(ret, size);
+
+  return (void*)ret;
+
+}
+
+/* Allocate a buffer, returning zeroed memory. */
+
+static inline void* DFL_ck_alloc(u32 size) {
+
+  void* mem;
+
+  if (!size) return NULL;
+  mem = DFL_ck_alloc_nozero(size);
+
+  return memset(mem, 0, size);
+
+}
+
+/* Free memory, checking for double free and corrupted heap. When DEBUG_BUILD
+   is set, the old memory will be also clobbered with 0xFF. */
+
+static inline void DFL_ck_free(void* mem) {
+
+  if (!mem) return;
+
+  free(mem);
+
+}
+
+/* Re-allocate a buffer, checking for issues and zeroing any newly-added tail.
+   With DEBUG_BUILD, the buffer is always reallocated to a new addresses and the
+   old memory is clobbered with 0xFF. */
+
+static inline void* DFL_ck_realloc(void* orig, u32 size) {
+
+  u8* ret;
+
+  if (!size) {
+
+    DFL_ck_free(orig);
+    return NULL;
+
+  }
+
+  ALLOC_CHECK_SIZE(size);
+
+  /* Catch pointer issues sooner: force relocation and make sure that the
+     original buffer is wiped. */
+
+  ret = realloc(orig, size);
+
+  ALLOC_CHECK_RESULT(ret, size);
+
+  return (void*)ret;
+
+}
+
+/* Re-allocate a buffer with ALLOC_BLK_INC increments (used to speed up
+   repeated small reallocs without complicating the user code). */
+
+static inline void* DFL_ck_realloc_block(void* orig, u32 size) {
+
+  return DFL_ck_realloc(orig, size);
+
+}
+
+/* Create a buffer with a copy of a string. Returns NULL for NULL inputs. */
+
+static inline u8* DFL_ck_strdup(u8* str) {
+
+  u8* ret;
+  u32 size;
+
+  if (!str) return NULL;
+
+  size = strlen((char*)str) + 1;
+
+  ALLOC_CHECK_SIZE(size);
+  ret = malloc(size);
+  ALLOC_CHECK_RESULT(ret, size);
+
+  return memcpy(ret, str, size);
+
+}
+
+/* Create a buffer with a copy of a memory block. Returns NULL for zero-sized
+   or NULL inputs. */
+
+static inline void* DFL_ck_memdup(void* mem, u32 size) {
+
+  u8* ret;
+
+  if (!mem || !size) return NULL;
+
+  ALLOC_CHECK_SIZE(size);
+  ret = malloc(size);
+  ALLOC_CHECK_RESULT(ret, size);
+
+  return memcpy(ret, mem, size);
+
+}
+
+/* Create a buffer with a block of text, appending a NUL terminator at the end.
+   Returns NULL for zero-sized or NULL inputs. */
+
+static inline u8* DFL_ck_memdup_str(u8* mem, u32 size) {
+
+  u8* ret;
+
+  if (!mem || !size) return NULL;
+
+  ALLOC_CHECK_SIZE(size);
+  ret = malloc(size + 1);
+  ALLOC_CHECK_RESULT(ret, size);
+
+  memcpy(ret, mem, size);
+  ret[size] = 0;
+
+  return ret;
+
+}
+
+/* In non-debug mode, we just do straightforward aliasing of the above functions
+   to user-visible names such as ck_alloc(). */
+
+#define ck_alloc DFL_ck_alloc
+#define ck_alloc_nozero DFL_ck_alloc_nozero
+#define ck_realloc DFL_ck_realloc
+#define ck_realloc_block DFL_ck_realloc_block
+#define ck_strdup DFL_ck_strdup
+#define ck_memdup DFL_ck_memdup
+#define ck_memdup_str DFL_ck_memdup_str
+#define ck_free DFL_ck_free
+
+#define alloc_report()
+
+#else
+// This is the original alloc-inl of stock afl
+
 /* User-facing macro to sprintf() to a dynamically allocated buffer. */
 
 #define alloc_printf(_str...)                        \
@@ -568,5 +759,7 @@ static inline void TRK_ck_free(void* ptr, const char* file, const char* func,
 
 #endif                                                     /* ^!DEBUG_BUILD */
 
+#endif                                          /* _WANT_ORIGINAL_AFL_ALLOC */
+
 #endif                                               /* ! _HAVE_ALLOC_INL_H */
 
diff --git a/include/config.h b/include/config.h
index 59a476c9..58562346 100644
--- a/include/config.h
+++ b/include/config.h
@@ -40,6 +40,11 @@
 
 #define USE_COLOR
 
+/* If you want to have the original afl internal memory corruption checks.
+   Disabled by default for speed. it is better to use "make ASAN_BUILD=1". */
+
+//#define _WANT_ORIGINAL_AFL_ALLOC
+
 /* Comment out to disable fancy ANSI boxes and use poor man's 7-bit UI: */
 
 #ifndef ANDROID_DISABLE_FANCY  // Fancy boxes are ugly from adb