Mail Archives: cygwin-developers/2002/07/19/13:30:51
--Boundary_(ID_QPSO584em1rJoEN7fzqpCQ)
Content-type: text/plain; charset=us-ascii
Content-transfer-encoding: 7BIT
Content-disposition: inline
[This may be more appropriate for the newlib list, but I will start
here. Please feel free to redirect this post...]
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
--Boundary_(ID_QPSO584em1rJoEN7fzqpCQ)
Content-type: text/plain; charset=us-ascii; NAME=realloc.cc
Content-transfer-encoding: 7BIT
Content-disposition: attachment; filename=realloc.cc
#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;
}
--Boundary_(ID_QPSO584em1rJoEN7fzqpCQ)
Content-type: text/plain; charset=us-ascii; NAME=mallocr.c.diff
Content-transfer-encoding: 7BIT
Content-disposition: attachment; filename=mallocr.c.diff
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);
--Boundary_(ID_QPSO584em1rJoEN7fzqpCQ)--
- Raw text -