Make free chunk size a multiple of MALLOC_ALIGNMENT
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 25 May 2012 00:50:28 +0000 (17:50 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 25 May 2012 00:50:28 +0000 (17:50 -0700)
ChangeLog
malloc/malloc.c

index dbf24e2..ac5a898 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2012-05-24  H.J. Lu  <hongjiu.lu@intel.com>
+
+       [BZ #13576]
+       * malloc/malloc.c (sYSMALLOc): Free the old top chunk with a
+       multiple of MALLOC_ALIGNMENT in size.
+       (_int_free): Check chunk size is a multiple of MALLOC_ALIGNMENT.
+
 2012-05-24  Joseph Myers  <joseph@codesourcery.com>
 
        * conform/data/stdio.h-data (BUFSIZ): Use macro-int-constant.
index 447b622..28039b4 100644 (file)
@@ -2396,11 +2396,12 @@ static void* sysmalloc(INTERNAL_SIZE_T nb, mstate av)
       top(av) = chunk_at_offset(heap, sizeof(*heap));
       set_head(top(av), (heap->size - sizeof(*heap)) | PREV_INUSE);
 
-      /* Setup fencepost and free the old top chunk. */
+      /* Setup fencepost and free the old top chunk with a multiple of
+        MALLOC_ALIGNMENT in size. */
       /* The fencepost takes at least MINSIZE bytes, because it might
         become the top chunk again later.  Note that a footer is set
         up, too, although the chunk is marked in use. */
-      old_size -= MINSIZE;
+      old_size = (old_size - MINSIZE) & ~MALLOC_ALIGN_MASK;
       set_head(chunk_at_offset(old_top, old_size + 2*SIZE_SZ), 0|PREV_INUSE);
       if (old_size >= MINSIZE) {
        set_head(chunk_at_offset(old_top, old_size), (2*SIZE_SZ)|PREV_INUSE);
@@ -3809,8 +3810,9 @@ _int_free(mstate av, mchunkptr p, int have_lock)
       malloc_printerr (check_action, errstr, chunk2mem(p));
       return;
     }
-  /* We know that each chunk is at least MINSIZE bytes in size.  */
-  if (__builtin_expect (size < MINSIZE, 0))
+  /* We know that each chunk is at least MINSIZE bytes in size or a
+     multiple of MALLOC_ALIGNMENT.  */
+  if (__builtin_expect (size < MINSIZE || !aligned_OK (size), 0))
     {
       errstr = "free(): invalid size";
       goto errout;