Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
php7.9549
php-pcre-replace-impl-CWE-680.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File php-pcre-replace-impl-CWE-680.patch of Package php7.9549
Index: php-7.0.7/ext/pcre/php_pcre.c =================================================================== --- php-7.0.7.orig/ext/pcre/php_pcre.c 2016-05-25 15:14:21.000000000 +0200 +++ php-7.0.7/ext/pcre/php_pcre.c 2018-08-29 09:33:16.459141982 +0200 @@ -1108,6 +1108,18 @@ PHPAPI zend_string *php_pcre_replace(zen } /* }}} */ +static size_t zend_safe_address_guarded(size_t nmemb, size_t size, size_t offset) +{ + int overflow; + size_t ret = zend_safe_address(nmemb, size, offset, &overflow); + + if (overflow) { + zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset); + return 0; + } + return ret; +} + /* {{{ php_pcre_replace_impl() */ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *subject_str, char *subject, int subject_len, zval *replace_val, int is_callable_replace, int limit, int *replace_count) { @@ -1119,13 +1131,12 @@ PHPAPI zend_string *php_pcre_replace_imp char **subpat_names; /* Array for named subpatterns */ int num_subpats; /* Number of captured subpatterns */ int size_offsets; /* Size of the offsets array */ - int new_len; /* Length of needed storage */ - int alloc_len; /* Actual allocated length */ + size_t new_len; /* Length of needed storage */ + size_t alloc_len; /* Actual allocated length */ int match_len; /* Length of the current match */ int backref; /* Backreference number */ int start_offset; /* Where the new search starts */ int g_notempty=0; /* If the match should not be empty */ - int replace_len=0; /* Length of replacement string */ char *replace=NULL, /* Replacement string */ *walkbuf, /* Location of current replacement in the result */ *walk, /* Used to walk the replacement string */ @@ -1133,7 +1144,7 @@ PHPAPI zend_string *php_pcre_replace_imp *piece, /* The current piece of subject */ *replace_end=NULL, /* End of replacement string */ walk_last; /* Last walked character */ - int result_len; /* Length of result */ + size_t result_len; /* Length of result */ unsigned char *mark = NULL; /* Target for MARK name */ zend_string *result; /* Result of replacement */ zend_string *eval_result=NULL; /* Result of custom function */ @@ -1155,8 +1166,7 @@ PHPAPI zend_string *php_pcre_replace_imp if (!is_callable_replace) { replace = Z_STRVAL_P(replace_val); - replace_len = (int)Z_STRLEN_P(replace_val); - replace_end = replace + replace_len; + replace_end = replace + Z_STRLEN_P(replace_val); } /* Calculate the size of the offsets array, and allocate memory for it. */ @@ -1176,6 +1186,11 @@ PHPAPI zend_string *php_pcre_replace_imp if (UNEXPECTED(pce->name_count > 0)) { subpat_names = make_subpats_table(num_subpats, pce); if (!subpat_names) { + if (size_offsets <= 32) { + free_alloca(offsets, use_heap); + } else { + efree(offsets); + } return NULL; } } @@ -1219,7 +1234,7 @@ PHPAPI zend_string *php_pcre_replace_imp match = subject + offsets[0]; new_len = result_len + offsets[0] - start_offset; /* part before the match */ - + /* if (!is_callable_replace) */ if (EXPECTED(replace)) { /* do regular substitution */ @@ -1245,7 +1260,7 @@ PHPAPI zend_string *php_pcre_replace_imp } if (new_len >= alloc_len) { - alloc_len = alloc_len + 2 * new_len; + alloc_len = zend_safe_address_guarded(2, new_len, alloc_len); if (result == NULL) { result = zend_string_alloc(alloc_len, 0); } else { @@ -1255,7 +1270,7 @@ PHPAPI zend_string *php_pcre_replace_imp /* copy the part of the string before the match */ memcpy(&ZSTR_VAL(result)[result_len], piece, match-piece); - result_len += (int)(match-piece); + result_len += (match-piece); /* copy replacement and backrefs */ walkbuf = ZSTR_VAL(result) + result_len; @@ -1283,14 +1298,14 @@ PHPAPI zend_string *php_pcre_replace_imp } *walkbuf = '\0'; /* increment the result length by how much we've added to the string */ - result_len += (int)(walkbuf - (ZSTR_VAL(result) + result_len)); + result_len += (walkbuf - (ZSTR_VAL(result) + result_len)); } else { /* Use custom function to get replacement string and its length. */ eval_result = preg_do_repl_func(replace_val, subject, offsets, subpat_names, count, mark); ZEND_ASSERT(eval_result); - new_len += (int)ZSTR_LEN(eval_result); + new_len = zend_safe_address_guarded(1, ZSTR_LEN(eval_result), new_len); if (new_len >= alloc_len) { - alloc_len = alloc_len + 2 * new_len; + alloc_len = zend_safe_address_guarded(2, new_len, alloc_len); if (result == NULL) { result = zend_string_alloc(alloc_len, 0); } else { @@ -1331,7 +1346,7 @@ PHPAPI zend_string *php_pcre_replace_imp break; } new_len = result_len + subject_len - start_offset; - if (new_len > alloc_len) { + if (new_len >= alloc_len) { alloc_len = new_len; /* now we know exactly how long it is */ if (NULL != result) { result = zend_string_realloc(result, alloc_len, 0); @@ -1512,7 +1527,7 @@ static int preg_replace_impl(zval *retur } } } ZEND_HASH_FOREACH_END(); - } else { + } else { /* if subject is not an array */ old_replace_count = replace_count; if ((result = php_replace_in_subject(regex, replace, subject, limit_val, is_callable_replace, &replace_count)) != NULL) { @@ -1520,10 +1535,13 @@ static int preg_replace_impl(zval *retur RETVAL_STR(result); } else { zend_string_release(result); + RETVAL_NULL(); } + } else { + RETVAL_NULL(); } } - + return replace_count; } /* }}} */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor