From: Ulrich Drepper Date: Thu, 8 Aug 2002 08:00:15 +0000 (+0000) Subject: (cALLOc): Check for overflow on multiplication. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=68eebfaf98438d6eb332396f83ea35b159ba794a;p=thirdparty%2Fglibc.git (cALLOc): Check for overflow on multiplication. --- diff --git a/malloc/malloc.c b/malloc/malloc.c index db65535e49a..2837fad462f 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -3795,14 +3795,26 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size; { arena *ar_ptr; mchunkptr p, oldtop; - INTERNAL_SIZE_T sz, csz, oldtopsize; + INTERNAL_SIZE_T bytes, sz, csz, oldtopsize; Void_t* mem; #if defined _LIBC || defined MALLOC_HOOKS __malloc_ptr_t (*hook) __MALLOC_PMT ((size_t, __const __malloc_ptr_t)) = __malloc_hook; + + /* size_t is unsigned so the behavior on overflow is defined. */ + bytes = n * elem_size; +#define HALF_INTERNAL_SIZE_T \ + (((INTERNAL_SIZE_T) 1) << (8 * sizeof (INTERNAL_SIZE_T) / 2)) + if (__builtin_expect ((n | elem_size) >= HALF_INTERNAL_SIZE_T, 0)) { + if (elem_size != 0 && bytes / elem_size != n) { + MALLOC_FAILURE_ACTION; + return 0; + } + } + if (hook != NULL) { - sz = n * elem_size; + sz = bytes; #if defined __GNUC__ && __GNUC__ >= 2 mem = (*hook)(sz, RETURN_ADDRESS (0)); #else @@ -3819,7 +3831,7 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size; } #endif - if(request2size(n * elem_size, sz)) + if(request2size(bytes, sz)) return 0; arena_get(ar_ptr, sz); if(!ar_ptr) @@ -3862,7 +3874,7 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size; } if (p == 0) return 0; } - mem = BOUNDED_N(chunk2mem(p), n * elem_size); + mem = BOUNDED_N(chunk2mem(p), bytes); /* Two optional cases in which clearing not necessary */