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); }