From c591f022f8abb4c0c2e60a037a0c0c5c5a125957 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sun, 10 May 2015 02:20:08 -0700 Subject: Fix bug #69403 and other int overflows --- Zend/zend_alloc.c | 22 +++++++++++----------- Zend/zend_operators.c | 11 ++++++++--- 2 files changed, 19 insertions(+), 14 deletions(-) (limited to 'Zend') diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index ae88b5dae9..d23118bf91 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -980,7 +980,7 @@ static void zend_mm_random(unsigned char *buf, size_t size) /* {{{ */ int has_context = 0; if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)) { - /* Could mean that the key container does not exist, let try + /* Could mean that the key container does not exist, let try again by asking for a new one */ if (GetLastError() == NTE_BAD_KEYSET) { if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) { @@ -1344,7 +1344,7 @@ static int zend_mm_check_ptr(zend_mm_heap *heap, void *ptr, int silent ZEND_FILE } if (!silent) { TSRMLS_FETCH(); - + zend_message_dispatcher(ZMSG_LOG_SCRIPT_NAME, NULL TSRMLS_CC); zend_debug_alloc_output("---------------------------------------\n"); zend_debug_alloc_output("%s(%d) : Block "PTR_FMT" status:\n" ZEND_FILE_LINE_RELAY_CC, ptr); @@ -2171,7 +2171,7 @@ static void *_zend_mm_realloc_int(zend_mm_heap *heap, void *p, size_t size ZEND_ #if ZEND_MM_CACHE if (ZEND_MM_SMALL_SIZE(true_size)) { size_t index = ZEND_MM_BUCKET_INDEX(true_size); - + if (heap->cache[index] != NULL) { zend_mm_free_block *best_fit; zend_mm_free_block **cache; @@ -2184,7 +2184,7 @@ static void *_zend_mm_realloc_int(zend_mm_heap *heap, void *p, size_t size ZEND_ heap->cache[index] = best_fit->prev_free_block; ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED); ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0); - + ptr = ZEND_MM_DATA_OF(best_fit); #if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION @@ -2466,7 +2466,7 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset) : "%0"(res), "rm"(size), "rm"(offset)); - + if (UNEXPECTED(overflow)) { zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset); return 0; @@ -2575,7 +2575,7 @@ ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LI ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { - int length; + size_t length; char *p; #ifdef ZEND_SIGNALS TSRMLS_FETCH(); @@ -2583,13 +2583,13 @@ ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) HANDLE_BLOCK_INTERRUPTIONS(); - length = strlen(s)+1; - p = (char *) _emalloc(length ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + length = strlen(s); + p = (char *) _emalloc(safe_address(length, 1, 1) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); if (UNEXPECTED(p == NULL)) { HANDLE_UNBLOCK_INTERRUPTIONS(); return p; } - memcpy(p, s, length); + memcpy(p, s, length+1); HANDLE_UNBLOCK_INTERRUPTIONS(); return p; } @@ -2603,7 +2603,7 @@ ZEND_API char *_estrndup(const char *s, uint length ZEND_FILE_LINE_DC ZEND_FILE_ HANDLE_BLOCK_INTERRUPTIONS(); - p = (char *) _emalloc(length+1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + p = (char *) _emalloc(safe_address(length, 1, 1) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); if (UNEXPECTED(p == NULL)) { HANDLE_UNBLOCK_INTERRUPTIONS(); return p; @@ -2624,7 +2624,7 @@ ZEND_API char *zend_strndup(const char *s, uint length) HANDLE_BLOCK_INTERRUPTIONS(); - p = (char *) malloc(length+1); + p = (char *) malloc(safe_address(length, 1, 1)); if (UNEXPECTED(p == NULL)) { HANDLE_UNBLOCK_INTERRUPTIONS(); return p; diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index a791a36d78..75c456cfb0 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -1264,14 +1264,19 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{ zend_error(E_ERROR, "String size overflow"); } - Z_STRVAL_P(result) = erealloc(Z_STRVAL_P(result), res_len+1); + Z_STRVAL_P(result) = safe_erealloc(Z_STRVAL_P(result), res_len, 1, 1); memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(result), Z_STRVAL_P(op2), Z_STRLEN_P(op2)); Z_STRVAL_P(result)[res_len]=0; Z_STRLEN_P(result) = res_len; } else { int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2); - char *buf = (char *) emalloc(length + 1); + char *buf; + + if (Z_STRLEN_P(op1) < 0 || Z_STRLEN_P(op2) < 0 || (int) (Z_STRLEN_P(op1) + Z_STRLEN_P(op2)) < 0) { + zend_error(E_ERROR, "String size overflow"); + } + buf = (char *) safe_emalloc(length, 1, 1); memcpy(buf, Z_STRVAL_P(op1), Z_STRLEN_P(op1)); memcpy(buf + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2)); @@ -2067,7 +2072,7 @@ ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2) /* {{{ */ } else if (ret2!=IS_DOUBLE) { if (oflow1) { ZVAL_LONG(result, oflow1); - return; + return; } dval2 = (double) lval2; } else if (dval1 == dval2 && !zend_finite(dval1)) { -- cgit v1.2.1