about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2016-06-08 20:50:21 +0200
committerFlorian Weimer <fweimer@redhat.com>2016-06-08 20:50:21 +0200
commit1e8a8875d69e36d2890b223ffe8853a8ff0c9512 (patch)
treeeb133b0a58fc24fda5b7093ddd5f259013333256
parent8fa8a330f95c2f39eae7960ccf2825e693789202 (diff)
downloadglibc-1e8a8875d69e36d2890b223ffe8853a8ff0c9512.tar.gz
glibc-1e8a8875d69e36d2890b223ffe8853a8ff0c9512.tar.xz
glibc-1e8a8875d69e36d2890b223ffe8853a8ff0c9512.zip
malloc: Correct size computation in realloc for dumped fake mmapped chunks
For regular mmapped chunks there are two size fields (hence a reduction
by 2 * SIZE_SZ bytes), but for fake chunks, we only have one size field,
so we need to subtract SIZE_SZ bytes.

This was initially reported as Emacs bug 23726.
-rw-r--r--ChangeLog7
-rw-r--r--malloc/malloc.c12
2 files changed, 15 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 20b3dc0194..6ceb2dfeec 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2016-06-08  Florian Weimer  <fweimer@redhat.com>
+
+	Emacs bug 23726.
+	* malloc/malloc.c (dumped_main_arena_start): Update comment.
+	(__libc_realloc): Correct size computation for dumped fake mmapped
+	chunks.
+
 2016-06-07  Joseph Myers  <joseph@codesourcery.com>
 
 	[BZ #20219]
diff --git a/malloc/malloc.c b/malloc/malloc.c
index ead9a21d81..6f77d372a8 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1748,7 +1748,9 @@ static struct malloc_state main_arena =
 
 /* These variables are used for undumping support.  Chunked are marked
    as using mmap, but we leave them alone if they fall into this
-   range.  */
+   range.  NB: The chunk size for these chunks only includes the
+   initial size field (of SIZE_SZ bytes), there is no trailing size
+   field (unlike with regular mmapped chunks).  */
 static mchunkptr dumped_main_arena_start; /* Inclusive.  */
 static mchunkptr dumped_main_arena_end;   /* Exclusive.  */
 
@@ -3029,9 +3031,11 @@ __libc_realloc (void *oldmem, size_t bytes)
 	  if (newmem == 0)
 	    return NULL;
 	  /* Copy as many bytes as are available from the old chunk
-	     and fit into the new size.  */
-	  if (bytes > oldsize - 2 * SIZE_SZ)
-	    bytes = oldsize - 2 * SIZE_SZ;
+	     and fit into the new size.  NB: The overhead for faked
+	     mmapped chunks is only SIZE_SZ, not 2 * SIZE_SZ as for
+	     regular mmapped chunks.  */
+	  if (bytes > oldsize - SIZE_SZ)
+	    bytes = oldsize - SIZE_SZ;
 	  memcpy (newmem, oldmem, bytes);
 	  return newmem;
 	}