SECURITY: CVE-2009-2412 (cve.mitre.org) Fix overflow in pools, where size alignment was taking place. Reported by: Matt Lewis * memory/unix/apr_pools.c (allocator_alloc, apr_palloc): Check for overflow after aligning size. (apr_pcalloc): Drop aligning of size; clearing what the caller asked for should suffice. SEE ALSO: apr-util-1.x-CVE-2009-2412.patch Index: memory/unix/apr_pools.c =================================================================== --- memory/unix/apr_pools.c (revision 798473) +++ memory/unix/apr_pools.c (working copy) @@ -191,16 +191,19 @@ } static APR_INLINE -apr_memnode_t *allocator_alloc(apr_allocator_t *allocator, apr_size_t size) +apr_memnode_t *allocator_alloc(apr_allocator_t *allocator, apr_size_t in_size) { apr_memnode_t *node, **ref; apr_uint32_t max_index; - apr_size_t i, index; + apr_size_t size, i, index; /* Round up the block size to the next boundary, but always * allocate at least a certain size (MIN_ALLOC). */ - size = APR_ALIGN(size + APR_MEMNODE_T_SIZE, BOUNDARY_SIZE); + size = APR_ALIGN(in_size + APR_MEMNODE_T_SIZE, BOUNDARY_SIZE); + if (size < in_size) { + return NULL; + } if (size < MIN_ALLOC) size = MIN_ALLOC; @@ -628,13 +631,19 @@ * Memory allocation */ -APR_DECLARE(void *) apr_palloc(apr_pool_t *pool, apr_size_t size) +APR_DECLARE(void *) apr_palloc(apr_pool_t *pool, apr_size_t in_size) { apr_memnode_t *active, *node; void *mem; - apr_size_t free_index; + apr_size_t size, free_index; - size = APR_ALIGN_DEFAULT(size); + size = APR_ALIGN_DEFAULT(in_size); + if (size < in_size) { + if (pool->abort_fn) + pool->abort_fn(APR_ENOMEM); + + return NULL; + } active = pool->active; /* If the active node has enough bytes left, use it. */ @@ -699,7 +708,6 @@ { void *mem; - size = APR_ALIGN_DEFAULT(size); if ((mem = apr_palloc(pool, size)) != NULL) { memset(mem, 0, size); }