Bug in newlib malloc causing libstdc++ test failures
Daniel Jacobowitz
drow@mvista.com
Mon Aug 18 23:22:00 GMT 2003
It looks fine to me - I was just copying the check from glibc's malloc,
but this looks equivalent.
On Mon, Aug 18, 2003 at 03:55:48PM -0400, J. Johnston wrote:
> Sorry about that Daniel. I wanted an alternative patch and forgot about it.
> I prefer the attached patch which is a little cleaner. It successfully rejects
> a request of -4. Please try it out to confirm it works as you expect it to.
>
> -- Jeff J.
>
> Daniel Jacobowitz wrote:
> >
> > Ping?
> >
> > On Thu, Jul 24, 2003 at 07:19:34PM -0400, Daniel Jacobowitz wrote:
> > > 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. */
> > >
> > >
> >
> > --
> > Daniel Jacobowitz
> > MontaVista Software Debian GNU/Linux Developer
> --- /home/jjohnstn/sid/devo/newlib/libc/stdlib/mallocr.c Wed Feb 19 13:57:00 2003
> +++ mallocr.c Mon Aug 18 15:49:38 2003
> @@ -2334,7 +2334,7 @@
> INTERNAL_SIZE_T nb = request2size(bytes); /* padded request size; */
>
> /* Check for overflow and just fail, if so. */
> - if (nb > INT_MAX)
> + if (nb > INT_MAX || nb < bytes)
> return 0;
>
> MALLOC_LOCK;
> @@ -2797,7 +2797,7 @@
> nb = request2size(bytes);
>
> /* Check for overflow and just fail, if so. */
> - if (nb > INT_MAX)
> + if (nb > INT_MAX || nb < bytes)
> return 0;
>
> #if HAVE_MMAP
> @@ -3028,6 +3028,11 @@
> /* Call malloc with worst case padding to hit alignment. */
>
> nb = request2size(bytes);
> +
> + /* Check for overflow. */
> + if (nb > INT_MAX || nb < bytes)
> + return 0;
> +
> m = (char*)(mALLOc(RCALL nb + alignment + MINSIZE));
>
> if (m == 0) return 0; /* propagate failure */
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
More information about the Newlib
mailing list