about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2022-09-10 18:45:47 +0200
committerGitHub <noreply@github.com>2022-09-10 18:45:47 +0200
commitf12ee5c7d29620561b6b1330a66738e666d48515 (patch)
treeb8ff6ab94fb38353c61c0de5eca30e51d8200648
parentc06c297933f4014b130df5c19a0c10fa5405e120 (diff)
parent258f4ee5291854fd450b2f2600ab9b611c9f4669 (diff)
downloadafl++-f12ee5c7d29620561b6b1330a66738e666d48515.tar.gz
Merge pull request #1512 from devnexen/libdislocator_attrs
libdislocator apply few attributes for few compiler optimisations.
-rw-r--r--utils/libdislocator/libdislocator.so.c110
1 files changed, 20 insertions, 90 deletions
diff --git a/utils/libdislocator/libdislocator.so.c b/utils/libdislocator/libdislocator.so.c
index 149b910e..03eb12a9 100644
--- a/utils/libdislocator/libdislocator.so.c
+++ b/utils/libdislocator/libdislocator.so.c
@@ -47,7 +47,6 @@
   #ifdef __NR_getrandom
     #define arc4random_buf(p, l)                       \
       do {                                             \
-                                                       \
         ssize_t rd = syscall(__NR_getrandom, p, l, 0); \
         if (rd != l) DEBUGF("getrandom failed");       \
                                                        \
@@ -57,7 +56,6 @@
     #include <time.h>
     #define arc4random_buf(p, l)     \
       do {                           \
-                                     \
         srand(time(NULL));           \
         u32 i;                       \
         u8 *ptr = (u8 *)p;           \
@@ -80,7 +78,6 @@
     (defined(__FreeBSD__) && __FreeBSD_version < 1200000)
 // use this hack if not C11
 typedef struct {
-
   long long   __ll;
   long double __ld;
 
@@ -92,11 +89,11 @@ typedef struct {
 
 #ifndef PAGE_SIZE
   #define PAGE_SIZE 4096
-#endif                                                        /* !PAGE_SIZE */
+#endif /* !PAGE_SIZE */
 
 #ifndef MAP_ANONYMOUS
   #define MAP_ANONYMOUS MAP_ANON
-#endif                                                    /* !MAP_ANONYMOUS */
+#endif /* !MAP_ANONYMOUS */
 
 #define SUPER_PAGE_SIZE 1 << 21
 
@@ -104,30 +101,22 @@ typedef struct {
 
 #define DEBUGF(_x...)                 \
   do {                                \
-                                      \
     if (alloc_verbose) {              \
-                                      \
       if (++call_depth == 1) {        \
-                                      \
         fprintf(stderr, "[AFL] " _x); \
         fprintf(stderr, "\n");        \
-                                      \
       }                               \
       call_depth--;                   \
-                                      \
     }                                 \
                                       \
   } while (0)
 
 #define FATAL(_x...)                    \
   do {                                  \
-                                        \
     if (++call_depth == 1) {            \
-                                        \
       fprintf(stderr, "*** [AFL] " _x); \
       fprintf(stderr, " ***\n");        \
       abort();                          \
-                                        \
     }                                   \
     call_depth--;                       \
                                         \
@@ -149,19 +138,19 @@ typedef struct {
 
 /* Configurable stuff (use AFL_LD_* to set): */
 
-static size_t max_mem = MAX_ALLOC;      /* Max heap usage to permit         */
-static u8     alloc_verbose,            /* Additional debug messages        */
-    hard_fail,                          /* abort() when max_mem exceeded?   */
-    no_calloc_over,                     /* abort() on calloc() overflows?   */
-    align_allocations;                  /* Force alignment to sizeof(void*) */
+static size_t max_mem = MAX_ALLOC; /* Max heap usage to permit         */
+static u8     alloc_verbose,       /* Additional debug messages        */
+    hard_fail,                     /* abort() when max_mem exceeded?   */
+    no_calloc_over,                /* abort() on calloc() overflows?   */
+    align_allocations;             /* Force alignment to sizeof(void*) */
 
 #if defined __OpenBSD__ || defined __APPLE__
   #define __thread
   #warning no thread support available
 #endif
-static _Atomic size_t total_mem;        /* Currently allocated mem          */
+static _Atomic size_t total_mem; /* Currently allocated mem          */
 
-static __thread u32 call_depth;         /* To avoid recursion via fprintf() */
+static __thread u32 call_depth; /* To avoid recursion via fprintf() */
 static u32          alloc_canary;
 
 /* This is the main alloc function. It allocates one page more than necessary,
@@ -170,19 +159,16 @@ static u32          alloc_canary;
    the returned memory will be zeroed. */
 
 static void *__dislocator_alloc(size_t len) {
-
   u8    *ret, *base;
   size_t tlen;
   int    flags, protflags, fd, sp;
 
   if (total_mem + len > max_mem || total_mem + len < total_mem) {
-
     if (hard_fail) FATAL("total allocs exceed %zu MB", max_mem / 1024 / 1024);
 
     DEBUGF("total allocs exceed %zu MB, returning NULL", max_mem / 1024 / 1024);
 
     return NULL;
-
   }
 
   size_t rlen;
@@ -215,10 +201,8 @@ static void *__dislocator_alloc(size_t len) {
   if (sp) flags |= MAP_ALIGNED_SUPER;
   #elif defined(__sun)
   if (sp) {
-
     base = (void *)(caddr_t)(1 << 21);
     flags |= MAP_ALIGN;
-
   }
 
   #endif
@@ -230,7 +214,6 @@ static void *__dislocator_alloc(size_t len) {
 #if defined(USEHUGEPAGE)
   /* We try one more time with regular call */
   if (ret == MAP_FAILED) {
-
   #if defined(__APPLE__)
     fd = -1;
   #elif defined(__linux__)
@@ -241,19 +224,16 @@ static void *__dislocator_alloc(size_t len) {
     flags &= -MAP_ALIGN;
   #endif
     ret = (u8 *)mmap(NULL, tlen, protflags, flags, fd, 0);
-
   }
 
 #endif
 
   if (ret == MAP_FAILED) {
-
     if (hard_fail) FATAL("mmap() failed on alloc (OOM?)");
 
     DEBUGF("mmap() failed on alloc (OOM?)");
 
     return NULL;
-
   }
 
 #if defined(USENAMEDPAGE)
@@ -262,9 +242,7 @@ static void *__dislocator_alloc(size_t len) {
   // `<start>-<end> ---p 00000000 00:00 0 [anon:libdislocator]`
   if (prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, (unsigned long)ret, tlen,
             (unsigned long)"libdislocator") < 0) {
-
     DEBUGF("prctl() failed");
-
   }
 
   #endif
@@ -290,22 +268,19 @@ static void *__dislocator_alloc(size_t len) {
   total_mem += len;
 
   if (rlen != len) {
-
     size_t i;
     for (i = len; i < rlen; ++i)
       ret[i] = TAIL_ALLOC_CANARY;
-
   }
 
   return ret;
-
 }
 
 /* The "user-facing" wrapper for calloc(). This just checks for overflows and
    displays debug messages if requested. */
 
-void *calloc(size_t elem_len, size_t elem_cnt) {
-
+__attribute__((malloc)) __attribute__((alloc_size(1, 2))) void *calloc(
+    size_t elem_len, size_t elem_cnt) {
   void *ret;
 
   size_t len = elem_len * elem_cnt;
@@ -313,17 +288,13 @@ void *calloc(size_t elem_len, size_t elem_cnt) {
   /* Perform some sanity checks to detect obvious issues... */
 
   if (elem_cnt && len / elem_cnt != elem_len) {
-
     if (no_calloc_over) {
-
       DEBUGF("calloc(%zu, %zu) would overflow, returning NULL", elem_len,
              elem_cnt);
       return NULL;
-
     }
 
     FATAL("calloc(%zu, %zu) would overflow", elem_len, elem_cnt);
-
   }
 
   ret = __dislocator_alloc(len);
@@ -332,15 +303,14 @@ void *calloc(size_t elem_len, size_t elem_cnt) {
          total_mem);
 
   return ret;
-
 }
 
 /* The wrapper for malloc(). Roughly the same, also clobbers the returned
    memory (unlike calloc(), malloc() is not guaranteed to return zeroed
    memory). */
 
-void *malloc(size_t len) {
-
+__attribute__((malloc)) __attribute__((alloc_size(1))) void *malloc(
+    size_t len) {
   void *ret;
 
   ret = __dislocator_alloc(len);
@@ -350,7 +320,6 @@ void *malloc(size_t len) {
   if (ret && len) memset(ret, ALLOC_CLOBBER, len);
 
   return ret;
-
 }
 
 /* The wrapper for free(). This simply marks the entire region as PROT_NONE.
@@ -358,7 +327,6 @@ void *malloc(size_t len) {
    read the canary. Not very graceful, but works, right? */
 
 void free(void *ptr) {
-
   u32 len;
 
   DEBUGF("free(%p)", ptr);
@@ -373,12 +341,10 @@ void free(void *ptr) {
   u8 *ptr_ = ptr;
 
   if (align_allocations && (len & (ALLOC_ALIGN_SIZE - 1))) {
-
     size_t rlen = (len & ~(ALLOC_ALIGN_SIZE - 1)) + ALLOC_ALIGN_SIZE;
     for (; len < rlen; ++len)
       if (ptr_[len] != TAIL_ALLOC_CANARY)
         FATAL("bad tail allocator canary on free()");
-
   }
 
   /* Protect everything. Note that the extra page at the end is already
@@ -392,32 +358,27 @@ void free(void *ptr) {
   ptr = ptr_;
 
   /* Keep the mapping; this is wasteful, but prevents ptr reuse. */
-
 }
 
 /* Realloc is pretty straightforward, too. We forcibly reallocate the buffer,
    move data, and then free (aka mprotect()) the original one. */
 
-void *realloc(void *ptr, size_t len) {
-
+__attribute__((alloc_size(2))) void *realloc(void *ptr, size_t len) {
   void *ret;
 
   ret = malloc(len);
 
   if (ret && ptr) {
-
     if (PTR_C(ptr) != alloc_canary) FATAL("bad allocator canary on realloc()");
     // Here the tail canary check is delayed to free()
 
     memcpy(ret, ptr, MIN(len, PTR_L(ptr)));
     free(ptr);
-
   }
 
   DEBUGF("realloc(%p, %zu) = %p [%zu total]", ptr, len, ret, total_mem);
 
   return ret;
-
 }
 
 /* posix_memalign we mainly check the proper alignment argument
@@ -425,14 +386,11 @@ void *realloc(void *ptr, size_t len) {
    a normal request */
 
 int posix_memalign(void **ptr, size_t align, size_t len) {
-
   // if (*ptr == NULL) return EINVAL; // (andrea) Why? I comment it out for now
   if ((align % 2) || (align % sizeof(void *))) return EINVAL;
   if (len == 0) {
-
     *ptr = NULL;
     return 0;
-
   }
 
   size_t rem = len % align;
@@ -445,69 +403,57 @@ int posix_memalign(void **ptr, size_t align, size_t len) {
   DEBUGF("posix_memalign(%p %zu, %zu) [*ptr = %p]", ptr, align, len, *ptr);
 
   return 0;
-
 }
 
 /* just the non-posix fashion */
 
-void *memalign(size_t align, size_t len) {
-
+__attribute__((malloc)) __attribute__((alloc_size(2))) void *memalign(
+    size_t align, size_t len) {
   void *ret = NULL;
 
   if (posix_memalign(&ret, align, len)) {
-
     DEBUGF("memalign(%zu, %zu) failed", align, len);
-
   }
 
   return ret;
-
 }
 
 /* sort of C11 alias of memalign only more severe, alignment-wise */
 
-void *aligned_alloc(size_t align, size_t len) {
-
+__attribute__((malloc)) __attribute__((alloc_size(2))) void *aligned_alloc(
+    size_t align, size_t len) {
   void *ret = NULL;
 
   if ((len % align)) return NULL;
 
   if (posix_memalign(&ret, align, len)) {
-
     DEBUGF("aligned_alloc(%zu, %zu) failed", align, len);
-
   }
 
   return ret;
-
 }
 
 /* specific BSD api mainly checking possible overflow for the size */
 
-void *reallocarray(void *ptr, size_t elem_len, size_t elem_cnt) {
-
+__attribute__((alloc_size(2, 3))) void *reallocarray(void *ptr, size_t elem_len,
+                                                     size_t elem_cnt) {
   const size_t elem_lim = 1UL << (sizeof(size_t) * 4);
   const size_t elem_tot = elem_len * elem_cnt;
   void        *ret = NULL;
 
   if ((elem_len >= elem_lim || elem_cnt >= elem_lim) && elem_len > 0 &&
       elem_cnt > (SIZE_MAX / elem_len)) {
-
     DEBUGF("reallocarray size overflow (%zu)", elem_tot);
 
   } else {
-
     ret = realloc(ptr, elem_tot);
-
   }
 
   return ret;
-
 }
 
 #if defined(__APPLE__)
 size_t malloc_size(const void *ptr) {
-
 #elif !defined(__ANDROID__)
 size_t malloc_usable_size(void *ptr) {
 
@@ -517,30 +463,24 @@ size_t malloc_usable_size(const void *ptr) {
 #endif
 
   return ptr ? PTR_L(ptr) : 0;
-
 }
 
 #if defined(__APPLE__)
 size_t malloc_good_size(size_t len) {
-
   return (len & ~(ALLOC_ALIGN_SIZE - 1)) + ALLOC_ALIGN_SIZE;
-
 }
 
 #endif
 
 __attribute__((constructor)) void __dislocator_init(void) {
-
   char *tmp = getenv("AFL_LD_LIMIT_MB");
 
   if (tmp) {
-
     char              *tok;
     unsigned long long mmem = strtoull(tmp, &tok, 10);
     if (*tok != '\0' || errno == ERANGE || mmem > SIZE_MAX / 1024 / 1024)
       FATAL("Bad value for AFL_LD_LIMIT_MB");
     max_mem = mmem * 1024 * 1024;
-
   }
 
   alloc_canary = ALLOC_CANARY;
@@ -552,33 +492,23 @@ __attribute__((constructor)) void __dislocator_init(void) {
   hard_fail = !!getenv("AFL_LD_HARD_FAIL");
   no_calloc_over = !!getenv("AFL_LD_NO_CALLOC_OVER");
   align_allocations = !!getenv("AFL_ALIGNED_ALLOC");
-
 }
 
 /* NetBSD fault handler specific api subset */
 
 void (*esetfunc(void (*fn)(int, const char *, ...)))(int, const char *, ...) {
-
   /* Might not be meaningful to implement; upper calls already report errors */
   return NULL;
-
 }
 
 void *emalloc(size_t len) {
-
   return malloc(len);
-
 }
 
 void *ecalloc(size_t elem_len, size_t elem_cnt) {
-
   return calloc(elem_len, elem_cnt);
-
 }
 
 void *erealloc(void *ptr, size_t len) {
-
   return realloc(ptr, len);
-
 }
-