Skip to content

Commit

Permalink
Fix #74604: Out of bounds in php_pcre_replace_impl
Browse files Browse the repository at this point in the history
Trying to allocate a `zend_string` with a length only slighty smaller
than `SIZE_MAX` causes an integer overflow; we make sure that this
doesn't happen by catering to the maximal overhead of a `zend_string`.

Closes GH-7597.
  • Loading branch information
cmb69 committed Nov 29, 2021
1 parent 31749aa commit 712fc54
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 4 deletions.
3 changes: 3 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ PHP NEWS
- OpenSSL:
. Fixed bug #75725 (./configure: detecting RAND_egd). (Dilyan Palauzov)

- PCRE:
. Fixed bug #74604 (Out of bounds in php_pcre_replace_impl). (cmb, Dmitry)

- Standard:
. Fixed bug #81618 (dns_get_record fails on FreeBSD for missing type).
(fsbruva)
Expand Down
3 changes: 2 additions & 1 deletion Zend/zend_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ END_EXTERN_C()

#define _ZSTR_STRUCT_SIZE(len) (_ZSTR_HEADER_SIZE + len + 1)

#define ZSTR_MAX_LEN (SIZE_MAX - ZEND_MM_ALIGNED_SIZE(_ZSTR_HEADER_SIZE + 1))
#define ZSTR_MAX_OVERHEAD (ZEND_MM_ALIGNED_SIZE(_ZSTR_HEADER_SIZE + 1))
#define ZSTR_MAX_LEN (SIZE_MAX - ZSTR_MAX_OVERHEAD)

#define ZSTR_ALLOCA_ALLOC(str, _len, use_heap) do { \
(str) = (zend_string *)do_alloca(ZEND_MM_ALIGNED_SIZE_EX(_ZSTR_STRUCT_SIZE(_len), 8), (use_heap)); \
Expand Down
6 changes: 3 additions & 3 deletions ext/pcre/php_pcre.c
Original file line number Diff line number Diff line change
Expand Up @@ -1725,7 +1725,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su
}

if (new_len >= alloc_len) {
alloc_len = zend_safe_address_guarded(2, new_len, 0);
alloc_len = zend_safe_address_guarded(2, new_len, ZSTR_MAX_OVERHEAD) - ZSTR_MAX_OVERHEAD;
if (result == NULL) {
result = zend_string_alloc(alloc_len, 0);
} else {
Expand Down Expand Up @@ -1961,9 +1961,9 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
pcre2_get_mark(match_data), flags);

ZEND_ASSERT(eval_result);
new_len = zend_safe_address_guarded(1, ZSTR_LEN(eval_result), new_len);
new_len = zend_safe_address_guarded(1, ZSTR_LEN(eval_result) + ZSTR_MAX_OVERHEAD, new_len) -ZSTR_MAX_OVERHEAD;
if (new_len >= alloc_len) {
alloc_len = zend_safe_address_guarded(2, new_len, 0);
alloc_len = zend_safe_address_guarded(2, new_len, ZSTR_MAX_OVERHEAD) - ZSTR_MAX_OVERHEAD;
if (result == NULL) {
result = zend_string_alloc(alloc_len, 0);
} else {
Expand Down

0 comments on commit 712fc54

Please sign in to comment.