public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Andrew Scull <ascull@google.com>
To: u-boot@lists.denx.de
Cc: sjg@chromium.org, seanga2@gmail.com, Andrew Scull <ascull@google.com>
Subject: [PATCH 11/11] RFC: Hack dlmalloc to poison memory
Date: Thu,  7 Apr 2022 09:41:23 +0000	[thread overview]
Message-ID: <20220407094123.1752236-12-ascull@google.com> (raw)
In-Reply-To: <20220407094123.1752236-1-ascull@google.com>

This is a hugely ugly hack to poison and unpoison memory allocated by
dlmalloc. It wraps every access dlmalloc makes to the metadata breifly
allow it access, taking care not to then poison the parts of the record
which overlap.

The result is very small redzones between the allocations, which has
limted value but has able to spot immediate buffer overruns.

The instrumentation is extremely intrusive and would be benefited by
more intrusions to increase redzone sizes etc.

Signed-off-by: Andrew Scull <ascull@google.com>
---
 common/dlmalloc.c     | 284 ++++++++++++++++++++++++++++++++++++------
 include/compiler.h    |   1 +
 include/linux/types.h |   1 +
 3 files changed, 245 insertions(+), 41 deletions(-)

diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index 11729e8c85..614f004579 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -8,6 +8,8 @@
  * as file malloc-2.6.6.c.
  */
 
+#define DEBUG
+
 #include <common.h>
 #include <log.h>
 #include <asm/global_data.h>
@@ -16,6 +18,8 @@
 #define DEBUG
 #endif
 
+#include <sanitizer/asan_interface.h>
+
 #include <malloc.h>
 #include <asm/io.h>
 
@@ -31,6 +35,17 @@ void malloc_stats();
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/*
+#undef ASAN_POISON_MEMORY_REGION
+#define ASAN_POISON_MEMORY_REGION(p, s) do { \
+    if ((uintptr_t)p == 0x0000150200c0) { \
+        printf("size %lx\n", s); \
+        *(int*)NULL = 9; \
+    } \
+    __asan_poison_memory_region(p, s); \
+} while (0)
+*/
+
 /*
   Emulation of sbrk for WIN32
   All code within the ifdef WIN32 is untested by me.
@@ -409,12 +424,26 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 /* Ptr to next physical malloc_chunk. */
 
-#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~PREV_INUSE) ))
+#define _next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~PREV_INUSE) ))
+#define next_chunk(p) ({ \
+        mchunkptr _ptr = (p); \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        mchunkptr _ret = _next_chunk(_ptr); \
+        ASAN_POISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        _ret; \
+        })
 
 /* Ptr to previous physical malloc_chunk */
 
-#define prev_chunk(p)\
+#define _prev_chunk(p)\
    ((mchunkptr)( ((char*)(p)) - ((p)->prev_size) ))
+#define prev_chunk(p) ({ \
+        mchunkptr _ptr = (p); \
+        ASAN_UNPOISON_MEMORY_REGION(_ptr, SIZE_SZ); \
+        mchunkptr _ret = _prev_chunk(_ptr); \
+        ASAN_POISON_MEMORY_REGION(_ptr, SIZE_SZ); \
+        _ret; \
+        })
 
 
 /* Treat space at ptr + offset as a chunk */
@@ -430,35 +459,102 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 /* extract p's inuse bit */
 
-#define inuse(p)\
+#define _inuse(p)\
 ((((mchunkptr)(((char*)(p))+((p)->size & ~PREV_INUSE)))->size) & PREV_INUSE)
+#define inuse(p) ({ \
+        mchunkptr _p = (p); \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)_p) + SIZE_SZ, SIZE_SZ); \
+        mchunkptr _ptr = ((mchunkptr)(((char*)_p)+(_p->size & ~PREV_INUSE))); \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        INTERNAL_SIZE_T _ret = _inuse(_p); \
+        ASAN_POISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        ASAN_POISON_MEMORY_REGION(((char*)_p) + SIZE_SZ, SIZE_SZ); \
+        _ret; \
+        })
 
 /* extract inuse bit of previous chunk */
 
-#define prev_inuse(p)  ((p)->size & PREV_INUSE)
+#define _prev_inuse(p)  ((p)->size & PREV_INUSE)
+#define prev_inuse(p) ({ \
+        mchunkptr _ptr = (p); \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        INTERNAL_SIZE_T _ret = _prev_inuse(_ptr); \
+        ASAN_POISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        _ret; \
+        })
 
 /* check for mmap()'ed chunk */
 
-#define chunk_is_mmapped(p) ((p)->size & IS_MMAPPED)
+#define _chunk_is_mmapped(p) ((p)->size & IS_MMAPPED)
+#define chunk_is_mmapped(p) ({ \
+        mchunkptr _ptr = (p); \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        INTERNAL_SIZE_T _ret = _chunk_is_mmapped(_ptr); \
+        ASAN_POISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        _ret; \
+        })
 
 /* set/clear chunk as in use without otherwise disturbing */
 
-#define set_inuse(p)\
+#define _set_inuse(p)\
 ((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size |= PREV_INUSE
-
-#define clear_inuse(p)\
+#define set_inuse(p, s) ({ \
+        mchunkptr _p = (p); \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)_p) + SIZE_SZ, SIZE_SZ); \
+        mchunkptr _ptr = ((mchunkptr)(((char*)_p)+(_p->size & ~PREV_INUSE))); \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        _set_inuse(_p, (s)); \
+        ASAN_POISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        ASAN_POISON_MEMORY_REGION(((char*)_p) + SIZE_SZ, SIZE_SZ); \
+        })
+
+#define _clear_inuse(p)\
 ((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size &= ~(PREV_INUSE)
+#define clear_inuse(p, s) ({ \
+        __typeof__(p) _p = (p); \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)_p) + SIZE_SZ, SIZE_SZ); \
+        mchunkptr _ptr = ((mchunkptr)(((char*)_p)+(_p->size & ~PREV_INUSE))); \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        _clear_inuse(_p, (s)); \
+        ASAN_POISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        ASAN_POISON_MEMORY_REGION(((char*)_p) + SIZE_SZ, SIZE_SZ); \
+        })
 
 /* check/set/clear inuse bits in known places */
 
-#define inuse_bit_at_offset(p, s)\
+#define _inuse_bit_at_offset(p, s)\
  (((mchunkptr)(((char*)(p)) + (s)))->size & PREV_INUSE)
-
-#define set_inuse_bit_at_offset(p, s)\
+#define inuse_bit_at_offset(p, s) ({ \
+        __typeof__(p) _p = (p); \
+        __typeof__(s) _s = (s); \
+        __typeof__(p) _ptr = (mchunkptr)(((char*)_p) + _s); \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        INTERNAL_SIZE_T _ret = _inuse_bit_at_offset(_p, _s); \
+        ASAN_POISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        _ret; \
+        })
+
+#define _set_inuse_bit_at_offset(p, s)\
  (((mchunkptr)(((char*)(p)) + (s)))->size |= PREV_INUSE)
-
-#define clear_inuse_bit_at_offset(p, s)\
+#define set_inuse_bit_at_offset(p, s) ({ \
+        __typeof__(p) _p = (p); \
+        __typeof__(s) _s = (s); \
+        __typeof__(p) _ptr = (mchunkptr)(((char*)_p) + _s); \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        _set_inuse_bit_at_offset(_p, _s); \
+        ASAN_POISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        })
+
+#define _clear_inuse_bit_at_offset(p, s)\
  (((mchunkptr)(((char*)(p)) + (s)))->size &= ~(PREV_INUSE))
+#define clear_inuse_bit_at_offset(p, s) ({ \
+        __typeof__(p) _p = (p); \
+        __typeof__(s) _s = (s); \
+        __typeof__(p) _ptr = (mchunkptr)(((char*)_p) + _s); \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        _clear_inuse_bit_at_offset(_p, _s); \
+        ASAN_POISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        })
 
 
 
@@ -469,19 +565,46 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 /* Get size, ignoring use bits */
 
-#define chunksize(p)          ((p)->size & ~(SIZE_BITS))
+#define _chunksize(p)          ((p)->size & ~(SIZE_BITS))
+#define chunksize(p) ({ \
+        mchunkptr _ptr = (p); \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        INTERNAL_SIZE_T _ret = _chunksize(_ptr); \
+        ASAN_POISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        _ret; \
+        })
 
 /* Set size at head, without disturbing its use bit */
 
-#define set_head_size(p, s)   ((p)->size = (((p)->size & PREV_INUSE) | (s)))
+#define _set_head_size(p, s)   ((p)->size = (((p)->size & PREV_INUSE) | (s)))
+#define set_head_size(p, s) ({ \
+        __typeof__(p) _ptr = (p); \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        _set_head_size(_ptr, (s)); \
+        ASAN_POISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        })
 
 /* Set size/use ignoring previous bits in header */
 
-#define set_head(p, s)        ((p)->size = (s))
+#define _set_head(p, s)        ((p)->size = (s))
+#define set_head(p, s) ({ \
+        __typeof__(p) _ptr = (p); \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        _set_head(_ptr, (s)); \
+        ASAN_POISON_MEMORY_REGION(((char*)_ptr) + SIZE_SZ, SIZE_SZ); \
+        })
 
 /* Set size at footer (only when chunk is not in use) */
 
-#define set_foot(p, s)   (((mchunkptr)((char*)(p) + (s)))->prev_size = (s))
+#define _set_foot(p, s)   (((mchunkptr)((char*)(p) + (s)))->prev_size = (s))
+#define set_foot(p, s) ({ \
+        __typeof__(p) _p = (p); \
+        __typeof__(s) _s = (s); \
+        __typeof__(p) _ptr = (mchunkptr)(((char*)_p) + _s); \
+        ASAN_UNPOISON_MEMORY_REGION(_ptr, SIZE_SZ); \
+        _set_foot(_p, (s)); \
+        ASAN_POISON_MEMORY_REGION(_ptr, SIZE_SZ); \
+        })
 
 
 
@@ -604,8 +727,11 @@ void *sbrk(ptrdiff_t increment)
 	 * if we are giving memory back make sure we clear it out since
 	 * we set MORECORE_CLEARS to 1
 	 */
-	if (increment < 0)
+	if (increment < 0) {
+                ASAN_UNPOISON_MEMORY_REGION((void *)new, -increment);
 		memset((void *)new, 0, -increment);
+                ASAN_POISON_MEMORY_REGION((void *)new, -increment);
+        }
 
 	if ((new < mem_malloc_start) || (new > mem_malloc_end))
 		return (void *)MORECORE_FAILURE;
@@ -630,13 +756,24 @@ void mem_malloc_init(ulong start, ulong size)
 #ifdef CONFIG_SYS_MALLOC_CLEAR_ON_INIT
 	memset((void *)mem_malloc_start, 0x0, size);
 #endif
+        ASAN_POISON_MEMORY_REGION((void *)start, size);
 	malloc_bin_reloc();
 }
 
 /* field-extraction macros */
 
-#define first(b) ((b)->fd)
-#define last(b)  ((b)->bk)
+#define first(b) ({ \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)b) + 2*SIZE_SZ, 2*sizeof(uintptr_t)); \
+        void *_ret = (b)->fd; \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)b) + 2*SIZE_SZ, 2*sizeof(uintptr_t)); \
+        _ret; \
+        })
+#define last(b)  ({ \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)b) + 2*SIZE_SZ, 2*sizeof(uintptr_t)); \
+        void *_ret = (b)->bk; \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)b) + 2*SIZE_SZ, 2*sizeof(uintptr_t)); \
+        _ret; \
+        })
 
 /*
   Indexing into bins
@@ -781,7 +918,7 @@ static void do_check_chunk(mchunkptr p)
 static void do_check_chunk(p) mchunkptr p;
 #endif
 {
-  INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
+  INTERNAL_SIZE_T sz = chunksize(p);
 
   /* No checkable chunk is mmapped */
   assert(!chunk_is_mmapped(p));
@@ -802,7 +939,7 @@ static void do_check_free_chunk(mchunkptr p)
 static void do_check_free_chunk(p) mchunkptr p;
 #endif
 {
-  INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
+  INTERNAL_SIZE_T sz = chunksize(p);
   mchunkptr next = chunk_at_offset(p, sz);
 
   do_check_chunk(p);
@@ -816,14 +953,22 @@ static void do_check_free_chunk(p) mchunkptr p;
     assert((sz & MALLOC_ALIGN_MASK) == 0);
     assert(aligned_OK(chunk2mem(p)));
     /* ... matching footer field */
+    ASAN_UNPOISON_MEMORY_REGION(next, SIZE_SZ);
     assert(next->prev_size == sz);
+    ASAN_POISON_MEMORY_REGION(next, SIZE_SZ);
     /* ... and is fully consolidated */
     assert(prev_inuse(p));
     assert (next == top || inuse(next));
 
     /* ... and has minimally sane links */
+    ASAN_UNPOISON_MEMORY_REGION(((char*)p) + 2*SIZE_SZ, 2*sizeof(uintptr_t));
+    ASAN_UNPOISON_MEMORY_REGION(((char*)p->fd) + 2*SIZE_SZ, 2*sizeof(uintptr_t));
+    ASAN_UNPOISON_MEMORY_REGION(((char*)p->bk) + 2*SIZE_SZ, 2*sizeof(uintptr_t));
     assert(p->fd->bk == p);
     assert(p->bk->fd == p);
+    ASAN_POISON_MEMORY_REGION(((char*)p->fd) + 2*SIZE_SZ, 2*sizeof(uintptr_t));
+    ASAN_POISON_MEMORY_REGION(((char*)p->bk) + 2*SIZE_SZ, 2*sizeof(uintptr_t));
+    ASAN_POISON_MEMORY_REGION(((char*)p) + 2*SIZE_SZ, 2*sizeof(uintptr_t));
   }
   else /* markers are always of size SIZE_SZ */
     assert(sz == SIZE_SZ);
@@ -867,7 +1012,7 @@ static void do_check_malloced_chunk(mchunkptr p, INTERNAL_SIZE_T s)
 static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s;
 #endif
 {
-  INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
+  INTERNAL_SIZE_T sz = chunksize(p);
   long room = sz - s;
 
   do_check_inuse_chunk(p);
@@ -919,31 +1064,48 @@ static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s;
 
 #define frontlink(P, S, IDX, BK, FD)                                          \
 {                                                                             \
+  ASAN_UNPOISON_MEMORY_REGION(((char*)P) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
   if (S < MAX_SMALLBIN_SIZE)                                                  \
   {                                                                           \
     IDX = smallbin_index(S);                                                  \
     mark_binblock(IDX);                                                       \
     BK = bin_at(IDX);                                                         \
+  ASAN_UNPOISON_MEMORY_REGION(((char*)BK) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
     FD = BK->fd;                                                              \
     P->bk = BK;                                                               \
     P->fd = FD;                                                               \
+  ASAN_UNPOISON_MEMORY_REGION(((char*)FD) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
     FD->bk = BK->fd = P;                                                      \
   }                                                                           \
   else                                                                        \
   {                                                                           \
     IDX = bin_index(S);                                                       \
     BK = bin_at(IDX);                                                         \
+  ASAN_UNPOISON_MEMORY_REGION(((char*)BK) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
     FD = BK->fd;                                                              \
+  ASAN_UNPOISON_MEMORY_REGION(((char*)FD) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
     if (FD == BK) mark_binblock(IDX);                                         \
     else                                                                      \
     {                                                                         \
-      while (FD != BK && S < chunksize(FD)) FD = FD->fd;                      \
+      while (FD != BK && S < chunksize(FD)) { \
+          mchunkptr old = FD; \
+          FD = FD->fd;                      \
+        ASAN_POISON_MEMORY_REGION(((char*)old) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)FD) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
+      } \
+      mchunkptr oldbk = BK; \
       BK = FD->bk;                                                            \
+  ASAN_POISON_MEMORY_REGION(((char*)oldbk) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
+  ASAN_UNPOISON_MEMORY_REGION(((char*)BK) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
+        ASAN_UNPOISON_MEMORY_REGION(((char*)FD) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
     }                                                                         \
     P->bk = BK;                                                               \
     P->fd = FD;                                                               \
     FD->bk = BK->fd = P;                                                      \
   }                                                                           \
+  ASAN_POISON_MEMORY_REGION(((char*)P) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
+  ASAN_POISON_MEMORY_REGION(((char*)BK) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
+  ASAN_POISON_MEMORY_REGION(((char*)FD) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
 }
 
 
@@ -951,18 +1113,26 @@ static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s;
 
 #define unlink(P, BK, FD)                                                     \
 {                                                                             \
+  ASAN_UNPOISON_MEMORY_REGION(((char*)P) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
   BK = P->bk;                                                                 \
   FD = P->fd;                                                                 \
+  ASAN_POISON_MEMORY_REGION(((char*)P) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
+  ASAN_UNPOISON_MEMORY_REGION(((char*)BK) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
+  ASAN_UNPOISON_MEMORY_REGION(((char*)FD) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
   FD->bk = BK;                                                                \
   BK->fd = FD;                                                                \
+  ASAN_POISON_MEMORY_REGION(((char*)BK) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
+  ASAN_POISON_MEMORY_REGION(((char*)FD) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
 }                                                                             \
 
 /* Place p as the last remainder */
 
 #define link_last_remainder(P)                                                \
 {                                                                             \
+  ASAN_UNPOISON_MEMORY_REGION(((char*)P) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
   last_remainder->fd = last_remainder->bk =  P;                               \
   P->fd = P->bk = last_remainder;                                             \
+  ASAN_POISON_MEMORY_REGION(((char*)P) + 2*SIZE_SZ, 2*sizeof(uintptr_t));                                 \
 }
 
 /* Clear the last_remainder bin */
@@ -1280,6 +1450,14 @@ static void malloc_extend_top(nb) INTERNAL_SIZE_T nb;
 
 */
 
+#define publish_mem(p) ({ \
+        __typeof__(p) _chunk = (p); \
+        Void_t *_ret = chunk2mem(_chunk); \
+        INTERNAL_SIZE_T _size = malloc_usable_size(_ret); \
+        ASAN_UNPOISON_MEMORY_REGION(_ret, _size); \
+        _ret; \
+        })
+
 #if __STD_C
 Void_t* mALLOc(size_t bytes)
 #else
@@ -1339,7 +1517,7 @@ Void_t* mALLOc(bytes) size_t bytes;
       unlink(victim, bck, fwd);
       set_inuse_bit_at_offset(victim, victim_size);
       check_malloced_chunk(victim, nb);
-      return chunk2mem(victim);
+      return publish_mem(victim);
     }
 
     idx += 2; /* Set for bin scan below. We've already scanned 2 bins. */
@@ -1350,7 +1528,11 @@ Void_t* mALLOc(bytes) size_t bytes;
     idx = bin_index(nb);
     bin = bin_at(idx);
 
-    for (victim = last(bin); victim != bin; victim = victim->bk)
+    for (victim = last(bin); victim != bin;
+            ASAN_UNPOISON_MEMORY_REGION((char*)victim + 2*SIZE_SZ, 2*sizeof(uintptr_t)),
+            victim = victim->bk,
+            ASAN_POISON_MEMORY_REGION((char*)victim + 2*SIZE_SZ, 2*sizeof(uintptr_t))
+            )
     {
       victim_size = chunksize(victim);
       remainder_size = victim_size - nb;
@@ -1366,7 +1548,7 @@ Void_t* mALLOc(bytes) size_t bytes;
 	unlink(victim, bck, fwd);
 	set_inuse_bit_at_offset(victim, victim_size);
 	check_malloced_chunk(victim, nb);
-	return chunk2mem(victim);
+	return publish_mem(victim);
       }
     }
 
@@ -1389,7 +1571,7 @@ Void_t* mALLOc(bytes) size_t bytes;
       set_head(remainder, remainder_size | PREV_INUSE);
       set_foot(remainder, remainder_size);
       check_malloced_chunk(victim, nb);
-      return chunk2mem(victim);
+      return publish_mem(victim);
     }
 
     clear_last_remainder;
@@ -1398,7 +1580,7 @@ Void_t* mALLOc(bytes) size_t bytes;
     {
       set_inuse_bit_at_offset(victim, victim_size);
       check_malloced_chunk(victim, nb);
-      return chunk2mem(victim);
+      return publish_mem(victim);
     }
 
     /* Else place in bin */
@@ -1439,7 +1621,11 @@ Void_t* mALLOc(bytes) size_t bytes;
       {
 	/* Find and use first big enough chunk ... */
 
-	for (victim = last(bin); victim != bin; victim = victim->bk)
+	for (victim = last(bin); victim != bin; 
+                ASAN_UNPOISON_MEMORY_REGION((char*)victim + 2*SIZE_SZ, 2*sizeof(uintptr_t)),
+                victim = victim->bk,
+                ASAN_POISON_MEMORY_REGION((char*)victim + 2*SIZE_SZ, 2*sizeof(uintptr_t))
+                )
 	{
 	  victim_size = chunksize(victim);
 	  remainder_size = victim_size - nb;
@@ -1453,7 +1639,7 @@ Void_t* mALLOc(bytes) size_t bytes;
 	    set_head(remainder, remainder_size | PREV_INUSE);
 	    set_foot(remainder, remainder_size);
 	    check_malloced_chunk(victim, nb);
-	    return chunk2mem(victim);
+	    return publish_mem(victim);
 	  }
 
 	  else if (remainder_size >= 0)  /* take */
@@ -1461,7 +1647,7 @@ Void_t* mALLOc(bytes) size_t bytes;
 	    set_inuse_bit_at_offset(victim, victim_size);
 	    unlink(victim, bck, fwd);
 	    check_malloced_chunk(victim, nb);
-	    return chunk2mem(victim);
+	    return publish_mem(victim);
 	  }
 
 	}
@@ -1509,7 +1695,7 @@ Void_t* mALLOc(bytes) size_t bytes;
     /* If big and would otherwise need to extend, try to use mmap instead */
     if ((unsigned long)nb >= (unsigned long)mmap_threshold &&
 	(victim = mmap_chunk(nb)))
-      return chunk2mem(victim);
+      return publish_mem(victim);
 #endif
 
     /* Try to extend */
@@ -1523,7 +1709,8 @@ Void_t* mALLOc(bytes) size_t bytes;
   top = chunk_at_offset(victim, nb);
   set_head(top, remainder_size | PREV_INUSE);
   check_malloced_chunk(victim, nb);
-  return chunk2mem(victim);
+
+  return publish_mem(victim);
 
 }
 
@@ -1578,8 +1765,12 @@ void fREe(mem) Void_t* mem;
   if (mem == NULL)                              /* free(0) has no effect */
     return;
 
+  ASAN_POISON_MEMORY_REGION(mem, malloc_usable_size(mem));
+
   p = mem2chunk(mem);
+  ASAN_UNPOISON_MEMORY_REGION(((char*)p) + SIZE_SZ, SIZE_SZ);
   hd = p->size;
+  ASAN_POISON_MEMORY_REGION(((char*)p) + SIZE_SZ, SIZE_SZ);
 
 #if HAVE_MMAP
   if (hd & IS_MMAPPED)                       /* release mmapped memory. */
@@ -1601,7 +1792,9 @@ void fREe(mem) Void_t* mem;
 
     if (!(hd & PREV_INUSE))                    /* consolidate backward */
     {
+      ASAN_UNPOISON_MEMORY_REGION(((char*)p), SIZE_SZ);
       prevsz = p->prev_size;
+      ASAN_POISON_MEMORY_REGION(((char*)p), SIZE_SZ);
       p = chunk_at_offset(p, -((long) prevsz));
       sz += prevsz;
       unlink(p, bck, fwd);
@@ -1620,20 +1813,25 @@ void fREe(mem) Void_t* mem;
 
   if (!(hd & PREV_INUSE))                    /* consolidate backward */
   {
+    ASAN_UNPOISON_MEMORY_REGION(p, SIZE_SZ);
     prevsz = p->prev_size;
+    ASAN_POISON_MEMORY_REGION(p, SIZE_SZ);
     p = chunk_at_offset(p, -((long) prevsz));
     sz += prevsz;
 
+    ASAN_UNPOISON_MEMORY_REGION((char*)p + 2*SIZE_SZ, 2*sizeof(uintptr_t));
     if (p->fd == last_remainder)             /* keep as last_remainder */
       islr = 1;
     else
       unlink(p, bck, fwd);
+    ASAN_POISON_MEMORY_REGION((char*)p + 2*SIZE_SZ, 2*sizeof(uintptr_t));
   }
 
   if (!(inuse_bit_at_offset(next, nextsz)))   /* consolidate forward */
   {
     sz += nextsz;
 
+    ASAN_UNPOISON_MEMORY_REGION((char*)next + 2*SIZE_SZ, 2*sizeof(uintptr_t));
     if (!islr && next->fd == last_remainder)  /* re-insert last_remainder */
     {
       islr = 1;
@@ -1641,6 +1839,7 @@ void fREe(mem) Void_t* mem;
     }
     else
       unlink(next, bck, fwd);
+    ASAN_POISON_MEMORY_REGION((char*)next + 2*SIZE_SZ, 2*sizeof(uintptr_t));
   }
 
 
@@ -1747,7 +1946,7 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
   {
 #if HAVE_MREMAP
     newp = mremap_chunk(oldp, nb);
-    if(newp) return chunk2mem(newp);
+    if(newp) return publish_mem(newp);
 #endif
     /* Note the extra SIZE_SZ overhead. */
     if(oldsize - SIZE_SZ >= nb) return oldmem; /* do nothing */
@@ -1782,7 +1981,7 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
 	  top = chunk_at_offset(oldp, nb);
 	  set_head(top, (newsize - nb) | PREV_INUSE);
 	  set_head_size(oldp, nb);
-	  return chunk2mem(oldp);
+	  return publish_mem(oldp);
 	}
       }
 
@@ -1895,7 +2094,7 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
   }
 
   check_inuse_chunk(newp);
-  return chunk2mem(newp);
+  return publish_mem(newp);
 }
 
 
@@ -2006,7 +2205,7 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
   {
 #if HAVE_MMAP
     if(chunk_is_mmapped(p))
-      return chunk2mem(p); /* nothing more to do */
+      return publish_mem(p); /* nothing more to do */
 #endif
   }
   else /* misaligned */
@@ -2032,7 +2231,7 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
     {
       newp->prev_size = p->prev_size + leadsize;
       set_head(newp, newsize|IS_MMAPPED);
-      return chunk2mem(newp);
+      return publish_mem(newp);
     }
 #endif
 
@@ -2060,7 +2259,7 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
   }
 
   check_inuse_chunk(p);
-  return chunk2mem(p);
+  return publish_mem(p);
 
 }
 
@@ -2318,7 +2517,10 @@ static void malloc_update_mallinfo()
   for (i = 1; i < NAV; ++i)
   {
     b = bin_at(i);
-    for (p = last(b); p != b; p = p->bk)
+    for (p = last(b); p != b;
+            ASAN_UNPOISON_MEMORY_REGION((char*)p + 2*SIZE_SZ, 2*sizeof(uintptr_t)),
+            p = p->bk,
+            ASAN_POISON_MEMORY_REGION((char*)p + 2*SIZE_SZ, 2*sizeof(uintptr_t)))
     {
 #ifdef DEBUG
       check_free_chunk(p);
diff --git a/include/compiler.h b/include/compiler.h
index ef7b2cb1f7..7f7e82daf7 100644
--- a/include/compiler.h
+++ b/include/compiler.h
@@ -126,6 +126,7 @@ typedef __u32 u32;
 
 /* Type for `void *' pointers. */
 typedef unsigned long int uintptr_t;
+typedef long int intptr_t;
 
 #include <linux/string.h>
 #include <linux/types.h>
diff --git a/include/linux/types.h b/include/linux/types.h
index baa2c491ea..d86d2611c0 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -25,6 +25,7 @@ typedef __kernel_uid16_t        uid16_t;
 typedef __kernel_gid16_t        gid16_t;
 
 typedef unsigned long		uintptr_t;
+typedef long		        intptr_t;
 
 #ifdef CONFIG_UID16
 /* This is defined by include/asm-{arch}/posix_types.h */
-- 
2.35.1.1094.g7c7d902a7c-goog


  parent reply	other threads:[~2022-04-07  9:44 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-07  9:41 [PATCH 00/11] Fuzzing and ASAN for sandbox Andrew Scull
2022-04-07  9:41 ` [PATCH 01/11] sandbox: Set the EFI symbols in linker script Andrew Scull
2022-04-11 18:35   ` Simon Glass
2022-04-11 22:15   ` Heinrich Schuchardt
2022-04-11 22:37     ` Andrew Scull
2022-04-07  9:41 ` [PATCH 02/11] sandbox: Migrate getopt section to linker list Andrew Scull
2022-04-11 18:35   ` Simon Glass
2022-04-07  9:41 ` [PATCH 03/11] linker_lists: Rename sections to remove . prefix Andrew Scull
2022-04-11 18:35   ` Simon Glass
2022-04-07  9:41 ` [PATCH 04/11] sandbox: Add support for Address Sanitizer Andrew Scull
2022-04-11 18:35   ` Simon Glass
2022-04-12  9:26     ` Andrew Scull
2022-04-07  9:41 ` [PATCH 05/11] fuzzing_engine: Add fuzzing engine uclass Andrew Scull
2022-04-11 18:35   ` Simon Glass
2022-04-07  9:41 ` [PATCH 06/11] test: fuzz: Add framework for fuzzing Andrew Scull
2022-04-11 18:35   ` Simon Glass
2022-04-07  9:41 ` [PATCH 07/11] sandbox: Decouple program entry from sandbox init Andrew Scull
2022-04-11 18:35   ` Simon Glass
2022-04-07  9:41 ` [PATCH 08/11] sandbox: Add libfuzzer integration Andrew Scull
2022-04-11 18:35   ` Simon Glass
2022-04-07  9:41 ` [PATCH 09/11] sandbox: Implement fuzzing engine driver Andrew Scull
2022-04-11 18:35   ` Simon Glass
2022-04-14 13:44     ` Andrew Scull
2022-04-07  9:41 ` [PATCH 10/11] fuzz: virtio: Add fuzzer for vring Andrew Scull
2022-04-11 18:35   ` Simon Glass
2022-04-12 14:04     ` Andrew Scull
2022-04-07  9:41 ` Andrew Scull [this message]
2022-04-11 18:35   ` [PATCH 11/11] RFC: Hack dlmalloc to poison memory Simon Glass
2022-04-12 10:19     ` Andrew Scull

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220407094123.1752236-12-ascull@google.com \
    --to=ascull@google.com \
    --cc=seanga2@gmail.com \
    --cc=sjg@chromium.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox