Backport a malloc fix from Doug Lea's version

Kazu Hirata
Mon May 31 08:36:00 GMT 2010


Attached is a patch to backport a malloc fix from Doug Lea's version

Without this patch, free() could cause a dereference of an invalid
address, resulting in a hard fault under some circumstances.

To avoid confusion, Jeff Johnston committed a patch in this area,

2006-12-18  Jeff Johnston  <>

	* libc/stdlib/mallocr.c (malloc_extend_top): Add patch from
	2.6.5 version of Doug Lea's malloc which is the basis of
	this code.

However, if you look at Jeff's patch closely, it is the opposite of
the change from V2.6.4 to V2.6.5.  Jeff's patch moves set_head_size a
few lines *later*, whereas Doug's change moves set_head_size a few
lines *earlier*.

Here is what I think happened:

  Doug Lea released v2.6.3.

  Doug Lea released v2.6.5, which included the fix mentioned in this

Sometime between 1998-06-17 and 2000-02-17 (the date of newlib CVS
  Somebody either backported the fix mentioned in this patch without
  comments or independently came up with an identical fix.

  Jeff Johnston committed his change above.

FWIW, Doug's versions are available from:

Here is a quick description of the failure mode without this patch.  I
hope you'll excuse me for skipping some details here as it would take
me quite a bit of write up to go through the failure mode in complete

Note that free() attempts to consolidate the newly deallocated chunk
and surrounding areas (both below and above).  Now, suppose:

  malloc_extend_top() calls sbrk() <- Call this Block A
  malloc() is called many times
  malloc() allocates last time from Block A <- Call this pointer P
  somebody else calls sbrk() <- Call this Block B
  malloc_extend_top() calls sbrk() <- Call this Block C

in this chronological order.  Since Block A and Block C are not
contiguous due to Block B, the second call to malloc_extend_top()
installs a couple of dummy used chunks between P and the end of Block
A to prevent free(P) from consolidating P and the area above P.  (The
source code refers to these dummy chunks as "double fencepost".)  Now
without this patch, the dummy used chunks are not set up correctly,
which causes free() to dereference an address stored in an
uninitilized memory location.

In any event, if we backport the fix, I think it's good idea to do so
completely, including comments and version numbers.  Otherwise, we
wouldn't know what version mallocr.c is based on.  You can think of
this patch to rebase mallocr.c to Version 2.6.5.

Tested on a Cortex-M3 chip.  OK to apply?

Kazu Hirata

2010-05-30  Kazu Hirata  <>

	* libc/stdlib/mallocr.c (malloc_extend_top): Backport the
	difference between versions 2.6.4 and 2.6.5.

Index: newlib/libc/stdlib/mallocr.c
RCS file: /cvs/src/src/newlib/libc/stdlib/mallocr.c,v
retrieving revision 1.17
diff -u -r1.17 mallocr.c
--- newlib/libc/stdlib/mallocr.c	28 Sep 2009 16:42:21 -0000	1.17
+++ newlib/libc/stdlib/mallocr.c	31 May 2010 01:02:49 -0000
@@ -8,12 +8,17 @@
   public domain.  Send questions/comments/complaints/performance data
-* VERSION 2.6.4  Thu Nov 28 07:54:55 1996  Doug Lea  (dl at gee)
+* VERSION 2.6.5  Wed Jun 17 15:55:16 1998  Doug Lea  (dl at gee)
    Note: There may be an updated version of this malloc obtainable at
          Check before installing!
+   Note: This version differs from 2.6.4 only by correcting a
+         statement ordering error that could cause failures only
+         when calls to this malloc are interposed with calls to
+         other memory allocators.
 * Why use this malloc?
   This is not the fastest, most space-conserving, most portable, or
@@ -2223,11 +2228,11 @@
       /* Also keep size a multiple of MALLOC_ALIGNMENT */
       old_top_size = (old_top_size - 3*SIZE_SZ) & ~MALLOC_ALIGN_MASK;
+      set_head_size(old_top, old_top_size);
       chunk_at_offset(old_top, old_top_size          )->size =
       chunk_at_offset(old_top, old_top_size + SIZE_SZ)->size =
-      set_head_size(old_top, old_top_size);
       /* If possible, release the rest. */
       if (old_top_size >= MINSIZE) 
         fREe(RCALL chunk2mem(old_top));
@@ -3606,6 +3611,9 @@
+    V2.6.5 Wed Jun 17 15:57:31 1998  Doug Lea  (dl at gee)
+      * Fixed ordering problem with boundary-stamping
     V2.6.3 Sun May 19 08:17:58 1996  Doug Lea  (dl at gee)
       * Added pvalloc, as recommended by H.J. Liu
       * Added 64bit pointer support mainly from Wolfram Gloger

More information about the Newlib mailing list