]> granicus.if.org Git - php/commitdiff
Fix bug #69403 and other int overflows
authorStanislav Malyshev <stas@php.net>
Sun, 10 May 2015 09:20:08 +0000 (02:20 -0700)
committerStanislav Malyshev <stas@php.net>
Sun, 10 May 2015 09:20:08 +0000 (02:20 -0700)
Zend/zend_alloc.c
Zend/zend_operators.c
ext/standard/string.c

index ae88b5dae9e176d1d52463cb309169d5be241bab..d23118bf91d93c800ff2dedc7eedc98cd947b9f0 100644 (file)
@@ -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;
index a791a36d78848b717b7c720bb9167145079b09b7..75c456cfb085e4c0c831b0e313cae9395d56fa3b 100644 (file)
@@ -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)) {
index 7bc21598712267d90c4feaf5bba1ed012cb6237f..e22207dcb9f9129f4449b80137f1094264716ff1 100644 (file)
@@ -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 Sther 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 */