2007/4/6, Karl Chen <[EMAIL PROTECTED]>:
Hi all, apologies if this has been discussed before, but I
couldn't find anything about this issue in gcc mailing list
archives.
Use of operator new (et al) appears to have an integer overflow;
this function:
int * allocate_int(size_t n)
{
return new int[n];
}
with gcc-4.1 on IA-32 compiles to:
_Z12allocate_intj:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl 8(%ebp), %eax
sall $2, %eax ####
movl %eax, (%esp)
call _Znaj
leave
ret
which is equivalent to the compilation of:
int * allocate_int(size_t n)
{
return (int*) operator new[](4 * n);
}
"4 * n", unchecked, is vulnerable to integer overflow. On IA-32,
"new int[0x40000001]" becomes equivalent to "new int[1]". I've
verified this on gcc-2.95 through 4.1. For larger objects the
effects are exaggerated; smaller counts are needed to overflow.
This is similar to the calloc integer overflow vulnerability in
glibc, which was fixed back in 2002. Interestingly, RUS-CERT
2002-08:02 did mention 'operator new', and so did Bugtraq 5398.
http://cert.uni-stuttgart.de/advisories/calloc.php
http://www.securityfocus.com/bid/5398/discuss
See also this 2004 article by Raymond Chen:
http://blogs.msdn.com/oldnewthing/archive/2004/01/29/64389.aspx
Possible fixes might be to abort or to pass ULONG_MAX (0xFFFFFFFF)
to 'operator new' and let it return NULL or throw bad_alloc.
At least one other compiler already specifically guards against
integer overflow in 'operator new'.
--
Karl 2007-04-06 07:30
You've reason! There was not anything about this issue in gcc mailing
list archives.
But, i've more discussion about it!.
A possible workaround could be it but it's vulnerable if it's defined
with -DNDEBUG :
int * allocate_int(size_t n)
{
// it's another integer overflow, a positive can become to a negative.
// n=1073741823 (0x3FFFFFFF) => n*4=-4 (0xFFFFFFFC)
// return (int*) operator new[](-4); !!! it's easy for
buffer overflow.
assert(0 <= (4 * n));
// it's an assert against your integer overflow.
assert((4ULL * n) <= ULONG_MAX);
return (int*) operator new[](4 * n);
}