This is the mail archive of the cygwin-developers@cygwin.com mailing list for the Cygwin 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]

Re: realloc overflow problem


On Fri, Jul 19, 2002 at 01:32:04PM -0400, Jason Tishler wrote:
>[This may be more appropriate for the newlib list, but I will start
>here.  Please feel free to redirect this post...]

I actually mentioned it in the newlib mailing list some time ago.

http://sources.redhat.com/ml/newlib/2002/msg00101.html

It is more appropriate to mention it there.  FWIW, I came up with a
similar fix.

cgf

>While tracking down a Cygwin Python problem, I believe that I have
>uncovered an overflow problem in realloc() (and possibly other malloc
>routines).  The attached test program, realloc.cc, demonstrates the
>problem:
>
>    $ realloc 536870911  # realloc((maximum int value) / 4) fails
>    realloc(536870911) failed
>    $ realloc 2147483647 # realloc(maximum int value) "succeeds"
>    $
>
>The attached patch "fixes" the overflow problem by changing many (long)
>casts into (unsigned long) ones:
>
>    $ realloc 2147483647
>    realloc(2147483647) failed
>
>Is this the right approach?  Or, is there a better way?
>
>Thanks,
>Jason

>#include <stdio.h>
>#include <stdlib.h>
>
>int
>main(int argc, char* argv[])
>{
>	size_t size = atol(argv[1]);
>
>	char* p = (char*) malloc(1);
>	if (!p)
>	{
>		printf("malloc(1) failed\n");
>		exit(1);
>	}
>
>	p = (char*) realloc(p, size);
>	if (!p)
>	{
>		printf("realloc(%lu) failed\n", size);
>		exit(2);
>	}
>
>	return 0;
>}

>Index: mallocr.c
>===================================================================
>RCS file: /cvs/src/src/newlib/libc/stdlib/mallocr.c,v
>retrieving revision 1.6
>diff -u -p -r1.6 mallocr.c
>--- mallocr.c	13 Apr 2002 10:27:02 -0000	1.6
>+++ mallocr.c	19 Jul 2002 17:16:00 -0000
>@@ -1399,8 +1399,8 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-
> /* pad request bytes into a usable size */
> 
> #define request2size(req) \
>- (((long)((req) + (SIZE_SZ + MALLOC_ALIGN_MASK)) < \
>-  (long)(MINSIZE + MALLOC_ALIGN_MASK)) ? ((MINSIZE + MALLOC_ALIGN_MASK) & ~(MALLOC_ALIGN_MASK)) : \
>+ (((unsigned long)((req) + (SIZE_SZ + MALLOC_ALIGN_MASK)) < \
>+  (unsigned long)(MINSIZE + MALLOC_ALIGN_MASK)) ? ((MINSIZE + MALLOC_ALIGN_MASK) & ~(MALLOC_ALIGN_MASK)) : \
>    (((req) + (SIZE_SZ + MALLOC_ALIGN_MASK)) & ~(MALLOC_ALIGN_MASK)))
> 
> /* Check if m has acceptable alignment */
>@@ -2825,7 +2825,7 @@ Void_t* rEALLOc(RARG oldmem, bytes) RDEC
> 
>   check_inuse_chunk(oldp);
> 
>-  if ((long)(oldsize) < (long)(nb))  
>+  if ((unsigned long)(oldsize) < (unsigned long)(nb))  
>   {
> 
>     /* Try expanding forward */
>@@ -2838,7 +2838,7 @@ Void_t* rEALLOc(RARG oldmem, bytes) RDEC
>       /* Forward into top only if a remainder */
>       if (next == top)
>       {
>-        if ((long)(nextsize + newsize) >= (long)(nb + MINSIZE))
>+        if ((unsigned long)(nextsize + newsize) >= (unsigned long)(nb + MINSIZE))
>         {
>           newsize += nextsize;
>           top = chunk_at_offset(oldp, nb);
>@@ -2850,7 +2850,7 @@ Void_t* rEALLOc(RARG oldmem, bytes) RDEC
>       }
> 
>       /* Forward into next chunk */
>-      else if (((long)(nextsize + newsize) >= (long)(nb)))
>+      else if (((unsigned long)(nextsize + newsize) >= (unsigned long)(nb)))
>       { 
>         unlink(next, bck, fwd);
>         newsize  += nextsize;
>@@ -2877,7 +2877,7 @@ Void_t* rEALLOc(RARG oldmem, bytes) RDEC
>         /* into top */
>         if (next == top)
>         {
>-          if ((long)(nextsize + prevsize + newsize) >= (long)(nb + MINSIZE))
>+          if ((unsigned long)(nextsize + prevsize + newsize) >= (unsigned long)(nb + MINSIZE))
>           {
>             unlink(prev, bck, fwd);
>             newp = prev;
>@@ -2893,7 +2893,7 @@ Void_t* rEALLOc(RARG oldmem, bytes) RDEC
>         }
> 
>         /* into next chunk */
>-        else if (((long)(nextsize + prevsize + newsize) >= (long)(nb)))
>+        else if (((unsigned long)(nextsize + prevsize + newsize) >= (unsigned long)(nb)))
>         {
>           unlink(next, bck, fwd);
>           unlink(prev, bck, fwd);
>@@ -2906,7 +2906,7 @@ Void_t* rEALLOc(RARG oldmem, bytes) RDEC
>       }
>       
>       /* backward only */
>-      if (prev != 0 && (long)(prevsize + newsize) >= (long)nb)  
>+      if (prev != 0 && (unsigned long)(prevsize + newsize) >= (unsigned long)nb)  
>       {
>         unlink(prev, bck, fwd);
>         newp = prev;
>@@ -2949,7 +2949,7 @@ Void_t* rEALLOc(RARG oldmem, bytes) RDEC
> 
>   remainder_size = long_sub_size_t(newsize, nb);
> 
>-  if (remainder_size >= (long)MINSIZE) /* split off remainder */
>+  if (remainder_size >= (unsigned long)MINSIZE) /* split off remainder */
>   {
>     remainder = chunk_at_offset(newp, nb);
>     set_head_size(newp, nb);


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