From dba3595c0ae26795a78753ea33ff0c3edf9d6328 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 9 Mar 2020 11:24:10 +0100 Subject: AFL without globals (#220) * moved globals to afl, shm and fsrv * moved argv to afl state, less bugs * fixed unicorn docu * lists everywhere * merged custom mutators * fixed leaks in afl-fuzz --- include/afl-prealloc.h | 101 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 include/afl-prealloc.h (limited to 'include/afl-prealloc.h') diff --git a/include/afl-prealloc.h b/include/afl-prealloc.h new file mode 100644 index 00000000..712cdec6 --- /dev/null +++ b/include/afl-prealloc.h @@ -0,0 +1,101 @@ +/* If we know we'll reuse small elements often, we'll just preallocate a buffer, then fall back to malloc */ +// TODO: Replace free status check with bitmask+CLZ + +#ifndef AFL_PREALLOC_H +#define AFL_PREALLOC_H + +#include +#include +#include + +#include "debug.h" + +typedef enum prealloc_status { + PRE_STATUS_UNUSED = 0,/* free in buf */ + PRE_STATUS_USED, /* used in buf */ + PRE_STATUS_MALLOC /* system malloc */ +} pre_status_t; + + +/* Adds the entry used for prealloc bookkeeping to this struct */ + +#define PREALLOCABLE ;pre_status_t pre_status; /* prealloc status of this instance */ + + +/* allocate an element of type *el_ptr, to this variable. + Uses (and reuses) the given prealloc_buf before hitting libc's malloc. + prealloc_buf must be the pointer to an array with type `type`. + `type` must be a struct with uses PREALLOCABLE (a pre_status_t pre_status member). + prealloc_size must be the array size. + prealloc_counter must be a variable initialized with 0 (of any name). + */ + +#define PRE_ALLOC(el_ptr, prealloc_buf, prealloc_size, prealloc_counter) do { \ + \ + if ((prealloc_counter) >= (prealloc_size)) { \ + \ + el_ptr = malloc(sizeof(*el_ptr)); \ + el_ptr->pre_status = PRE_STATUS_MALLOC; \ + \ + } else { \ + \ + /* Find one of our preallocated elements */ \ + u32 i; \ + for (i = 0; i < (prealloc_size); i++) { \ + \ + el_ptr = &((prealloc_buf)[i]); \ + if (el_ptr->pre_status == PRE_STATUS_UNUSED) { \ + \ + (prealloc_counter)++; \ + el_ptr->pre_status = PRE_STATUS_USED; \ + break; \ + \ + } \ + } \ + } \ + \ + if(!el_ptr) { \ + FATAL("BUG in list.h -> no element found or allocated!"); \ + } \ +} while(0); + + +/* Take a chosen (free) element from the prealloc_buf directly */ + +#define PRE_ALLOC_FORCE(el_ptr, prealloc_counter) do { \ + if ((el_ptr)->pre_status != PRE_STATUS_UNUSED) { \ + FATAL("PRE_ALLOC_FORCE element already allocated"); \ + } \ + (el_ptr)->pre_status = PRE_STATUS_USED; \ + (prealloc_counter)++; \ +} while(0); + + +/* free an preallocated element */ + +#define PRE_FREE(el_ptr, prealloc_counter) do { \ + \ + switch ((el_ptr)->pre_status) { \ + \ + case PRE_STATUS_USED: { \ + (el_ptr)->pre_status = PRE_STATUS_UNUSED; \ + (prealloc_counter)--; \ + if ((prealloc_counter) < 0) { \ + FATAL("Inconsistent data in PRE_FREE"); \ + } \ + break; \ + } \ + case PRE_STATUS_MALLOC: { \ + (el_ptr)->pre_status = PRE_STATUS_UNUSED; \ + free((el_ptr)); \ + break; \ + } \ + default: { \ + FATAL("Double Free Detected"); \ + break; \ + } \ + \ + } \ +} while(0); + +#endif -- cgit 1.4.1