about summary refs log tree commit diff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2012-05-24 17:50:28 -0700
committerH.J. Lu <hjl.tools@gmail.com>2012-05-24 17:50:28 -0700
commit347c92e9e78c39d8494c8497f420a7fa30c89565 (patch)
tree0ad300e1813fa710fe4ad214596916be349a30ba
parent6bcc8b3ff98f227022f35f003505c06a916d8436 (diff)
downloadglibc-347c92e9e78c39d8494c8497f420a7fa30c89565.tar.gz
glibc-347c92e9e78c39d8494c8497f420a7fa30c89565.tar.xz
glibc-347c92e9e78c39d8494c8497f420a7fa30c89565.zip
Make free chunk size a multiple of MALLOC_ALIGNMENT
-rw-r--r--ChangeLog7
-rw-r--r--malloc/malloc.c10
2 files changed, 13 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index dbf24e22a6..ac5a8984d6 100644
--- 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.
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 447b622342..28039b4720 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -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;