diff options
author | Ilia Alshanetsky <iliaa@php.net> | 2006-08-10 17:16:24 +0000 |
---|---|---|
committer | Ilia Alshanetsky <iliaa@php.net> | 2006-08-10 17:16:24 +0000 |
commit | 1016df1c1a766c6b55d400f8789cda221b40d5fc (patch) | |
tree | c9dca58122e03ee54e61037dd97567dbed41131d | |
parent | fc45bcc239c528e7009cf2d0a3973dd21f3a0d81 (diff) | |
download | php-git-1016df1c1a766c6b55d400f8789cda221b40d5fc.tar.gz |
Various security fixes backported from 5.2
# part 1
-rw-r--r-- | Zend/zend_alloc.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 086a3785c8..3de98292f0 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -72,7 +72,15 @@ static long mem_block_end_magic = MEM_BLOCK_END_MAGIC; #define CHECK_MEMORY_LIMIT(s, rs) _CHECK_MEMORY_LIMIT(s, rs, NULL, 0) # endif -#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { AG(allocated_memory) += rs;\ +#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { if ((ssize_t)(rs) > (ssize_t)(INT_MAX - AG(allocated_memory))) { \ + if (file) { \ + fprintf(stderr, "Integer overflow in memory_limit check detected at %s:%d\n", file, lineno); \ + } else { \ + fprintf(stderr, "Integer overflow in memory_limit check detected\n"); \ + } \ + exit(1); \ + } \ + AG(allocated_memory) += rs;\ if (AG(memory_limit)<AG(allocated_memory)) {\ int php_mem_limit = AG(memory_limit); \ AG(allocated_memory) -= rs; \ @@ -127,7 +135,7 @@ static long mem_block_end_magic = MEM_BLOCK_END_MAGIC; #endif #define DECLARE_CACHE_VARS() \ - unsigned int real_size; \ + size_t real_size; \ unsigned int cache_index #define REAL_SIZE(size) ((size+7) & ~0x7) @@ -142,12 +150,16 @@ static long mem_block_end_magic = MEM_BLOCK_END_MAGIC; ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { - zend_mem_header *p; + zend_mem_header *p = NULL; DECLARE_CACHE_VARS(); TSRMLS_FETCH(); CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); + if (size > INT_MAX || SIZE < size) { + goto emalloc_error; + } + #if !ZEND_DISABLE_MEMORY_CACHE if ((CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) { p = AG(cache)[CACHE_INDEX][--AG(cache_count)[CACHE_INDEX]]; @@ -184,6 +196,8 @@ ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) } #endif +emalloc_error: + HANDLE_BLOCK_INTERRUPTIONS(); if (!p) { @@ -357,6 +371,13 @@ ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LIN CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); HANDLE_BLOCK_INTERRUPTIONS(); + + if (size > INT_MAX || SIZE < size) { + REMOVE_POINTER_FROM_LIST(p); + p = NULL; + goto erealloc_error; + } + #if MEMORY_LIMIT CHECK_MEMORY_LIMIT(size - p->size, SIZE - REAL_SIZE(p->size)); if (AG(allocated_memory) > AG(allocated_memory_peak)) { @@ -365,6 +386,7 @@ ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LIN #endif REMOVE_POINTER_FROM_LIST(p); p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE); +erealloc_error: if (!p) { if (!allow_failure) { fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size); |