Bug #79188 [NEW]: Memory corruption in preg_replace/preg_replace_callback and unicode
| From: | cschneid@php.net | Date: | Wed, 29 Jan 2020 09:20:46 +0000 |
| Subject: | Bug #79188 [NEW]: Memory corruption in preg_replace/preg_replace_callback and unicode | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-225208@lists.php.net to get a copy of this message | ||
From: cschneid
Operating system:
PHP version: Irrelevant
Package: PCRE related
Bug Type: Bug
Bug description:Memory corruption in preg_replace/preg_replace_callback and unicode
Description:
------------
When using preg_replace with an empty pattern AND replacement string in
a Unicode string there can be a memory corruption happening by
overflowing the result buffer.
The easiest way to reproduce is to compile PHP with --enable-debug and
run it with valgrind, see test script below.
The bug was reproduced with PHP >= 7.0, older versions were not tested.
The patch adds additional tests to increase the result string buffer
size since I wasn't entirely sure how to fix the new_len calculation
above. Maybe someone with a deeper understanding of the code can come up
with a better patch.
Test script:
---------------
USE_ZEND_ALLOC=0 valgrind --undef-value-errors=no sapi/cli/php -r
'preg_replace("//u", "", "a" . str_repeat("\u{1f612}",
10));'
and
USE_ZEND_ALLOC=0 valgrind --undef-value-errors=no sapi/cli/php -r
'preg_replace_callback("//u", function() { return ""; }, "a" .
str_repeat("\u{1f612}", 10));'
Actual result:
--------------
$ USE_ZEND_ALLOC=0 valgrind --undef-value-errors=no sapi/cli/php -r
'preg_replace("//u", "", "a" . str_repeat("\u{1f612}",
10));'==21533==
Memcheck, a memory error detector
==21533== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et
al.
==21533== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright
info
==21533== Command: sapi/cli/php -r preg_replace("//u",\ "",\ "a"\ .\
str_repeat("\\u{1f612}",\ 10));
==21533==
==21533== Invalid write of size 1
==21533== at 0x4C358EB: memmove (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==21533== by 0x504092: php_pcre_replace_impl (php_pcre.c:1737)
==21533== by 0x50391C: php_pcre_replace (php_pcre.c:1544)
==21533== by 0x504EB4: php_replace_in_subject (php_pcre.c:2127)
==21533== by 0x50594B: preg_replace_common (php_pcre.c:2268)
==21533== by 0x505D25: zif_preg_replace (php_pcre.c:2326)
==21533== by 0x83E2B1: ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER
(zend_vm_execute.h:1240)
==21533== by 0x89C658: execute_ex (zend_vm_execute.h:51879)
==21533== by 0x8A06D9: zend_execute (zend_vm_execute.h:55983)
==21533== by 0x7C095E: zend_eval_stringl (zend_execute_API.c:1010)
==21533== by 0x7C0AF7: zend_eval_stringl_ex
(zend_execute_API.c:1051)
==21533== by 0x7C0B6F: zend_eval_string_ex (zend_execute_API.c:1062)
==21533== Address 0x6d56c30 is 0 bytes after a block of size 64
alloc'd
==21533== at 0x4C308BF: realloc (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==21533== by 0x7A2004: __zend_realloc (zend_alloc.c:2994)
==21533== by 0x7A0FF0: _realloc_custom (zend_alloc.c:2434)
==21533== by 0x7A1140: _erealloc (zend_alloc.c:2556)
==21533== by 0x4FF7BD: zend_string_extend (zend_string.h:205)
==21533== by 0x503D4A: php_pcre_replace_impl (php_pcre.c:1668)
==21533== by 0x50391C: php_pcre_replace (php_pcre.c:1544)
==21533== by 0x504EB4: php_replace_in_subject (php_pcre.c:2127)
==21533== by 0x50594B: preg_replace_common (php_pcre.c:2268)
==21533== by 0x505D25: zif_preg_replace (php_pcre.c:2326)
==21533== by 0x83E2B1: ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER
(zend_vm_execute.h:1240)
==21533== by 0x89C658: execute_ex (zend_vm_execute.h:51879)
--
Edit bug report at https://bugs.php.net/bug.php?id=79188&edit=1
--
Fix committed: https://bugs.php.net/fix.php?id=79188&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=79188&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=79188&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=79188&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=79188&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=79188&r=support
Expected behavior: https://bugs.php.net/fix.php?id=79188&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=79188&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=79188&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=79188&r=globals
PHP version support discontinued: https://bugs.php.net/fix.php?id=79188&r=phptooold
Daylight Savings: https://bugs.php.net/fix.php?id=79188&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=79188&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=79188&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=79188&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=79188&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=79188&r=mysqlcfg