summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2015-05-10 02:20:08 -0700
committerJulien Pauli <jpauli@php.net>2015-05-13 10:44:11 +0200
commit0a96aa600d1028eda505270366df28e4085a1941 (patch)
treef82ce154f98b9826335509a69f2939376f9dbd48
parentbbe4b87e1d1fa858c208368a28c0fb17c7774fe0 (diff)
downloadphp-git-0a96aa600d1028eda505270366df28e4085a1941.tar.gz
Fix bug #69403 and other int overflows
-rw-r--r--Zend/zend_alloc.c22
-rw-r--r--Zend/zend_operators.c9
-rw-r--r--ext/standard/string.c8
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 */