Mailing-List: contact cygwin-developers-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-developers-owner AT cygwin DOT com Delivered-To: mailing list cygwin-developers AT cygwin DOT com Date: Fri, 19 Jul 2002 14:00:18 -0400 From: Christopher Faylor To: cygwin-developers AT cygwin DOT com Subject: Re: realloc overflow problem Message-ID: <20020719180018.GB30860@redhat.com> Reply-To: cygwin-developers AT cygwin DOT com Mail-Followup-To: cygwin-developers AT cygwin DOT com References: <20020719173204 DOT GD376 AT tishler DOT net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20020719173204.GD376@tishler.net> User-Agent: Mutt/1.3.23.1i 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 >#include > >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);