This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

malloc could leak memory


In the unlikely case of failure of the sbrk() that attempts to align
the sbrk to a page boundary, we'd leak the whole chunk of memory
previously allocated.  This patch corrects this problem, by leaving
the top of the heap misaligned and attempting to correct it next
time.  I'm checking this in, approved by Jeff Johnston.

Index: newlib/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>
	* libc/stdlib/mallocr.c (malloc_extend_top): If correction sbrk
	fails, don't bail out, and try to correct next time.

Index: newlib/libc/stdlib/mallocr.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdlib/mallocr.c,v
retrieving revision 1.5
diff -u -p -r1.5 mallocr.c
--- newlib/libc/stdlib/mallocr.c 3 Feb 2002 09:24:14 -0000 1.5
+++ newlib/libc/stdlib/mallocr.c 13 Apr 2002 10:19:57 -0000
@@ -2128,6 +2128,7 @@ static void malloc_extend_top(RARG nb) R
   char*     brk;                  /* return value from sbrk */
   INTERNAL_SIZE_T front_misalign; /* unusable bytes at front of sbrked space */
   INTERNAL_SIZE_T correction;     /* bytes for 2nd sbrk call */
+  int correction_failed = 0;      /* whether we should relax the assertion */
   char*     new_brk;              /* return of 2nd sbrk call */
   INTERNAL_SIZE_T top_size;       /* new size of top chunk */
 
@@ -2152,11 +2153,13 @@ static void malloc_extend_top(RARG nb) R
   /* Fail if sbrk failed or if a foreign sbrk call killed our space */
   if (brk == (char*)(MORECORE_FAILURE) || 
       (brk < old_end && old_top != initial_top))
-    return;     
+    return;
 
   sbrked_mem += sbrk_size;
 
-  if (brk == old_end) /* can just add bytes to current top */
+  if (brk == old_end /* can just add bytes to current top, unless
+			previous correction failed */
+      && ((POINTER_UINT)old_end & (pagesz - 1)) == 0)
   {
     top_size = sbrk_size + old_top_size;
     set_head(top, top_size | PREV_INUSE);
@@ -2183,7 +2186,12 @@ static void malloc_extend_top(RARG nb) R
 
     /* Allocate correction */
     new_brk = (char*)(MORECORE (correction));
-    if (new_brk == (char*)(MORECORE_FAILURE)) return; 
+    if (new_brk == (char*)(MORECORE_FAILURE))
+      {
+	correction = 0;
+	correction_failed = 1;
+	new_brk = brk;
+      }
 
     sbrked_mem += correction;
 
@@ -2228,7 +2236,8 @@ static void malloc_extend_top(RARG nb) R
 #endif
 
   /* We always land on a page boundary */
-  assert(((unsigned long)((char*)top + top_size) & (pagesz - 1)) == 0);
+  assert(((unsigned long)((char*)top + top_size) & (pagesz - 1)) == 0
+	 || correction_failed);
 }
 
 #endif /* DEFINE_MALLOC */

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist                Professional serial bug killer

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]