diff options
author | Stanislav Malyshev <stas@php.net> | 2015-05-10 02:20:08 -0700 |
---|---|---|
committer | Julien Pauli <jpauli@php.net> | 2015-05-13 10:44:11 +0200 |
commit | 0a96aa600d1028eda505270366df28e4085a1941 (patch) | |
tree | f82ce154f98b9826335509a69f2939376f9dbd48 | |
parent | bbe4b87e1d1fa858c208368a28c0fb17c7774fe0 (diff) | |
download | php-git-0a96aa600d1028eda505270366df28e4085a1941.tar.gz |
Fix bug #69403 and other int overflows
-rw-r--r-- | Zend/zend_alloc.c | 22 | ||||
-rw-r--r-- | Zend/zend_operators.c | 9 | ||||
-rw-r--r-- | ext/standard/string.c | 8 |
3 files changed, 24 insertions, 15 deletions
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index db71d52b69..cd422e2d3e 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -984,7 +984,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)) { @@ -1348,7 +1348,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); @@ -2175,7 +2175,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; @@ -2188,7 +2188,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 @@ -2470,7 +2470,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; @@ -2619,7 +2619,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(); @@ -2627,13 +2627,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; } @@ -2647,7 +2647,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; @@ -2668,7 +2668,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 c87591513a..e0812fccc4 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -1319,14 +1319,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)); diff --git a/ext/standard/string.c b/ext/standard/string.c index 410535b41c..8c850512c7 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> | +----------------------------------------------------------------------+ */ @@ -1454,7 +1454,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) { @@ -4910,6 +4910,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 */ |