diff options
author | Stanislav Malyshev <stas@php.net> | 2015-05-10 02:20:08 -0700 |
---|---|---|
committer | Stanislav Malyshev <stas@php.net> | 2015-05-10 02:20:08 -0700 |
commit | c591f022f8abb4c0c2e60a037a0c0c5c5a125957 (patch) | |
tree | 97b2e2fb59833810312ba2efdc4ed2f960c4da05 | |
parent | be9b2a95adb504abd5acdc092d770444ad6f6854 (diff) | |
download | php-git-c591f022f8abb4c0c2e60a037a0c0c5c5a125957.tar.gz |
Fix bug #69403 and other int overflows
-rw-r--r-- | Zend/zend_alloc.c | 22 | ||||
-rw-r--r-- | Zend/zend_operators.c | 11 | ||||
-rw-r--r-- | ext/standard/string.c | 8 |
3 files changed, 25 insertions, 16 deletions
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)) { diff --git a/ext/standard/string.c b/ext/standard/string.c index 7bc2159871..e22207dcb9 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -13,7 +13,7 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf <rasmus@php.net> | - | Stig Sæther Bakken <ssb@php.net> | + | Stig S�ther Bakken <ssb@php.net> | | Zeev Suraski <zeev@zend.com> | +----------------------------------------------------------------------+ */ @@ -1443,7 +1443,7 @@ PHPAPI void php_basename(const char *s, size_t len, char *suffix, size_t sufflen } #if defined(PHP_WIN32) || defined(NETWARE) /* Catch relative paths in c:file.txt style. They're not to confuse - with the NTFS streams. This part ensures also, that no drive + with the NTFS streams. This part ensures also, that no drive letter traversing happens. */ } else if ((*c == ':' && (c - comp == 1))) { if (state == 0) { @@ -4949,6 +4949,10 @@ PHP_FUNCTION(str_repeat) /* Initialize the result string */ result_len = input_len * mult; + if(result_len > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Result is too big, maximum %d allowed", INT_MAX); + RETURN_EMPTY_STRING(); + } result = (char *)safe_emalloc(input_len, mult, 1); /* Heavy optimization for situations where input string is 1 byte long */ |