This is the mail archive of the
newlib@sources.redhat.com
mailing list for the newlib project.
Bug in newlib malloc causing libstdc++ test failures
- From: Daniel Jacobowitz <drow at mvista dot com>
- To: newlib at sources dot redhat dot com
- Cc: gcc at gcc dot gnu dot org
- Date: Thu, 24 Jul 2003 19:19:34 -0400
- Subject: Bug in newlib malloc causing libstdc++ test failures
- Reply-to: drow at mvista dot com, newlib at sources dot redhat dot com
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. */