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]

Bug in newlib malloc causing libstdc++ test failures


Well, failures might be too weak a word... with arm-elf-run they're more
like disasters.  Later versions of the malloc newlib's implementation is
based on appear to have an overflow check that newlib lacks - either that or
glibc added it separately.  This patch is based on the glibc malloc.

This causes malloc ((unsigned long) -4) to return NULL instead of claiming
to succeed, which happens during the libstdc++-v3 tests for std::bad_alloc.
Is this newlib patch OK?

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

2003-07-24  Daniel Jacobowitz  <drow@mvista.com>

	* mallocr.c (mALLOC, rEALLOc, mEMALIGn): Check for overflow.

Index: mallocr.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/newlib/libc/stdlib/mallocr.c,v
retrieving revision 1.11
diff -u -p -r1.11 mallocr.c
--- mallocr.c	19 Feb 2003 19:00:11 -0000	1.11
+++ mallocr.c	24 Jul 2003 23:09:00 -0000
@@ -2333,6 +2333,10 @@ Void_t* mALLOc(RARG bytes) RDECL size_t 
 
   INTERNAL_SIZE_T nb  = request2size(bytes);  /* padded request size; */
 
+  if ((unsigned long) bytes
+      >= (unsigned long) (INTERNAL_SIZE_T) (-2 * MINSIZE))
+    return 0;
+
   /* Check for overflow and just fail, if so. */
   if (nb > INT_MAX)
     return 0;
@@ -2788,6 +2792,10 @@ Void_t* rEALLOc(RARG oldmem, bytes) RDEC
   /* realloc of null is supposed to be same as malloc */
   if (oldmem == 0) return mALLOc(RCALL bytes);
 
+  if ((unsigned long) bytes
+      >= (unsigned long) (INTERNAL_SIZE_T) (-2 * MINSIZE))
+    return 0;
+
   MALLOC_LOCK;
 
   newp    = oldp    = mem2chunk(oldmem);
@@ -3024,6 +3032,10 @@ Void_t* mEMALIGn(RARG alignment, bytes) 
   /* Otherwise, ensure that it is at least a minimum chunk size */
   
   if (alignment <  MINSIZE) alignment = MINSIZE;
+
+  if ((unsigned long) bytes
+      >= (unsigned long) (INTERNAL_SIZE_T) (-2 * MINSIZE))
+    return 0;
 
   /* Call malloc with worst case padding to hit alignment. */
 


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