Created attachment 627475 [details] This file crashes php Description of problem: php53 crashes on attached file - in preg_replace function Version-Release number of selected component (if applicable): php53-5.3.3-13.el5_8 pcre-6.6-6.el5_6.1 How reproducible: Always Steps to Reproduce: 1. php preg_replace_crash.php Actual results: Segmentation fault Expected results: <span class="search-everything-highlight-color" style="background-color:#FFF984">foobar</span> – a – 00 aaźaaier Additional info: This is really on CentOS, but I think you might be interested, as it can be security related. I stumbled on this bug when Wordpress page was crashing httpd. $ valgrind php preg_replace_crash.php ==26413== Memcheck, a memory error detector ==26413== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. ==26413== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info ==26413== Command: php preg_replace_crash.php ==26413== ==26413== Invalid read of size 1 ==26413== at 0x4A08880: memcpy (mc_replace_strmem.c:587) ==26413== by 0x4612E2: php_pcre_replace_impl (string3.h:51) ==26413== by 0x461F9C: php_replace_in_subject (php_pcre.c:1267) ==26413== by 0x462593: preg_replace_impl (php_pcre.c:1365) ==26413== by 0x462AC2: zif_preg_replace (php_pcre.c:1385) ==26413== by 0x5E78E8: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:316) ==26413== by 0x5BD9AA: execute (zend_vm_execute.h:107) ==26413== by 0x599F44: zend_execute_scripts (zend.c:1194) ==26413== by 0x54AD47: php_execute_script (main.c:2261) ==26413== by 0x622CDD: main (php_cli.c:1192) ==26413== Address 0x4f7e8bf is 1 bytes before a block of size 262,144 alloc'd ==26413== at 0x4A0610C: malloc (vg_replace_malloc.c:195) ==26413== by 0x57CB2D: _zend_mm_alloc_int (zend_alloc.c:1898) ==26413== by 0x57D184: zend_mm_shutdown (zend_alloc.c:1657) ==26413== by 0x5494A6: php_module_startup (main.c:2094) ==26413== by 0x62189C: php_cli_startup (php_cli.c:401) ==26413== by 0x6220E4: main (php_cli.c:775) ==26413== ==26413== Invalid read of size 1 ==26413== at 0x4A08887: memcpy (mc_replace_strmem.c:587) ==26413== by 0x4612E2: php_pcre_replace_impl (string3.h:51) ==26413== by 0x461F9C: php_replace_in_subject (php_pcre.c:1267) ==26413== by 0x462593: preg_replace_impl (php_pcre.c:1365) ==26413== by 0x462AC2: zif_preg_replace (php_pcre.c:1385) ==26413== by 0x5E78E8: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:316) ==26413== by 0x5BD9AA: execute (zend_vm_execute.h:107) ==26413== by 0x599F44: zend_execute_scripts (zend.c:1194) ==26413== by 0x54AD47: php_execute_script (main.c:2261) ==26413== by 0x622CDD: main (php_cli.c:1192) ==26413== Address 0x4f7e8be is 2 bytes before a block of size 262,144 alloc'd ==26413== at 0x4A0610C: malloc (vg_replace_malloc.c:195) ==26413== by 0x57CB2D: _zend_mm_alloc_int (zend_alloc.c:1898) ==26413== by 0x57D184: zend_mm_shutdown (zend_alloc.c:1657) ==26413== by 0x5494A6: php_module_startup (main.c:2094) ==26413== by 0x62189C: php_cli_startup (php_cli.c:401) ==26413== by 0x6220E4: main (php_cli.c:775) ==26413== ==26413== Invalid read of size 1 ==26413== at 0x4A08870: memcpy (mc_replace_strmem.c:587) ==26413== by 0x4612E2: php_pcre_replace_impl (string3.h:51) ==26413== by 0x461F9C: php_replace_in_subject (php_pcre.c:1267) ==26413== by 0x462593: preg_replace_impl (php_pcre.c:1365) ==26413== by 0x462AC2: zif_preg_replace (php_pcre.c:1385) ==26413== by 0x5E78E8: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:316) ==26413== by 0x5BD9AA: execute (zend_vm_execute.h:107) ==26413== by 0x599F44: zend_execute_scripts (zend.c:1194) ==26413== by 0x54AD47: php_execute_script (main.c:2261) ==26413== by 0x622CDD: main (php_cli.c:1192) ==26413== Address 0x4f7e8bd is 3 bytes before a block of size 262,144 alloc'd ==26413== at 0x4A0610C: malloc (vg_replace_malloc.c:195) ==26413== by 0x57CB2D: _zend_mm_alloc_int (zend_alloc.c:1898) ==26413== by 0x57D184: zend_mm_shutdown (zend_alloc.c:1657) ==26413== by 0x5494A6: php_module_startup (main.c:2094) ==26413== by 0x62189C: php_cli_startup (php_cli.c:401) ==26413== by 0x6220E4: main (php_cli.c:775) ==26413== ==26413== Invalid read of size 1 ==26413== at 0x4A08879: memcpy (mc_replace_strmem.c:587) ==26413== by 0x4612E2: php_pcre_replace_impl (string3.h:51) ==26413== by 0x461F9C: php_replace_in_subject (php_pcre.c:1267) ==26413== by 0x462593: preg_replace_impl (php_pcre.c:1365) ==26413== by 0x462AC2: zif_preg_replace (php_pcre.c:1385) ==26413== by 0x5E78E8: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:316) ==26413== by 0x5BD9AA: execute (zend_vm_execute.h:107) ==26413== by 0x599F44: zend_execute_scripts (zend.c:1194) ==26413== by 0x54AD47: php_execute_script (main.c:2261) ==26413== by 0x622CDD: main (php_cli.c:1192) ==26413== Address 0x4f7e8bc is 4 bytes before a block of size 262,144 alloc'd ==26413== at 0x4A0610C: malloc (vg_replace_malloc.c:195) ==26413== by 0x57CB2D: _zend_mm_alloc_int (zend_alloc.c:1898) ==26413== by 0x57D184: zend_mm_shutdown (zend_alloc.c:1657) ==26413== by 0x5494A6: php_module_startup (main.c:2094) ==26413== by 0x62189C: php_cli_startup (php_cli.c:401) ==26413== by 0x6220E4: main (php_cli.c:775) ==26413== ==26413== Invalid write of size 1 ==26413== at 0x4A0888F: memcpy (mc_replace_strmem.c:587) ==26413== by 0x4612E2: php_pcre_replace_impl (string3.h:51) ==26413== by 0x461F9C: php_replace_in_subject (php_pcre.c:1267) ==26413== by 0x462593: preg_replace_impl (php_pcre.c:1365) ==26413== by 0x462AC2: zif_preg_replace (php_pcre.c:1385) ==26413== by 0x5E78E8: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:316) ==26413== by 0x5BD9AA: execute (zend_vm_execute.h:107) ==26413== by 0x599F44: zend_execute_scripts (zend.c:1194) ==26413== by 0x54AD47: php_execute_script (main.c:2261) ==26413== by 0x622CDD: main (php_cli.c:1192) ==26413== Address 0x4f7e8bf is 1 bytes before a block of size 262,144 alloc'd ==26413== at 0x4A0610C: malloc (vg_replace_malloc.c:195) ==26413== by 0x57CB2D: _zend_mm_alloc_int (zend_alloc.c:1898) ==26413== by 0x57D184: zend_mm_shutdown (zend_alloc.c:1657) ==26413== by 0x5494A6: php_module_startup (main.c:2094) ==26413== by 0x62189C: php_cli_startup (php_cli.c:401) ==26413== by 0x6220E4: main (php_cli.c:775) ==26413== ==26413== Invalid write of size 1 ==26413== at 0x4A08877: memcpy (mc_replace_strmem.c:587) ==26413== by 0x4612E2: php_pcre_replace_impl (string3.h:51) ==26413== by 0x461F9C: php_replace_in_subject (php_pcre.c:1267) ==26413== by 0x462593: preg_replace_impl (php_pcre.c:1365) ==26413== by 0x462AC2: zif_preg_replace (php_pcre.c:1385) ==26413== by 0x5E78E8: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:316) ==26413== by 0x5BD9AA: execute (zend_vm_execute.h:107) ==26413== by 0x599F44: zend_execute_scripts (zend.c:1194) ==26413== by 0x54AD47: php_execute_script (main.c:2261) ==26413== by 0x622CDD: main (php_cli.c:1192) ==26413== Address 0x4f7e8be is 2 bytes before a block of size 262,144 alloc'd ==26413== at 0x4A0610C: malloc (vg_replace_malloc.c:195) ==26413== by 0x57CB2D: _zend_mm_alloc_int (zend_alloc.c:1898) ==26413== by 0x57D184: zend_mm_shutdown (zend_alloc.c:1657) ==26413== by 0x5494A6: php_module_startup (main.c:2094) ==26413== by 0x62189C: php_cli_startup (php_cli.c:401) ==26413== by 0x6220E4: main (php_cli.c:775) ==26413== ==26413== Invalid write of size 1 ==26413== at 0x4A0887D: memcpy (mc_replace_strmem.c:587) ==26413== by 0x4612E2: php_pcre_replace_impl (string3.h:51) ==26413== by 0x461F9C: php_replace_in_subject (php_pcre.c:1267) ==26413== by 0x462593: preg_replace_impl (php_pcre.c:1365) ==26413== by 0x462AC2: zif_preg_replace (php_pcre.c:1385) ==26413== by 0x5E78E8: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:316) ==26413== by 0x5BD9AA: execute (zend_vm_execute.h:107) ==26413== by 0x599F44: zend_execute_scripts (zend.c:1194) ==26413== by 0x54AD47: php_execute_script (main.c:2261) ==26413== by 0x622CDD: main (php_cli.c:1192) ==26413== Address 0x4f7e8bd is 3 bytes before a block of size 262,144 alloc'd ==26413== at 0x4A0610C: malloc (vg_replace_malloc.c:195) ==26413== by 0x57CB2D: _zend_mm_alloc_int (zend_alloc.c:1898) ==26413== by 0x57D184: zend_mm_shutdown (zend_alloc.c:1657) ==26413== by 0x5494A6: php_module_startup (main.c:2094) ==26413== by 0x62189C: php_cli_startup (php_cli.c:401) ==26413== by 0x6220E4: main (php_cli.c:775) ==26413== ==26413== Invalid write of size 1 ==26413== at 0x4A08884: memcpy (mc_replace_strmem.c:587) ==26413== by 0x4612E2: php_pcre_replace_impl (string3.h:51) ==26413== by 0x461F9C: php_replace_in_subject (php_pcre.c:1267) ==26413== by 0x462593: preg_replace_impl (php_pcre.c:1365) ==26413== by 0x462AC2: zif_preg_replace (php_pcre.c:1385) ==26413== by 0x5E78E8: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:316) ==26413== by 0x5BD9AA: execute (zend_vm_execute.h:107) ==26413== by 0x599F44: zend_execute_scripts (zend.c:1194) ==26413== by 0x54AD47: php_execute_script (main.c:2261) ==26413== by 0x622CDD: main (php_cli.c:1192) ==26413== Address 0x4f7e8bc is 4 bytes before a block of size 262,144 alloc'd ==26413== at 0x4A0610C: malloc (vg_replace_malloc.c:195) ==26413== by 0x57CB2D: _zend_mm_alloc_int (zend_alloc.c:1898) ==26413== by 0x57D184: zend_mm_shutdown (zend_alloc.c:1657) ==26413== by 0x5494A6: php_module_startup (main.c:2094) ==26413== by 0x62189C: php_cli_startup (php_cli.c:401) ==26413== by 0x6220E4: main (php_cli.c:775) ==26413== ==26413== ==26413== Process terminating with default action of signal 11 (SIGSEGV) ==26413== Access not within mapped region at address 0x4C13FFF ==26413== at 0x4A08880: memcpy (mc_replace_strmem.c:587) ==26413== by 0x4612E2: php_pcre_replace_impl (string3.h:51) ==26413== by 0x461F9C: php_replace_in_subject (php_pcre.c:1267) ==26413== by 0x462593: preg_replace_impl (php_pcre.c:1365) ==26413== by 0x462AC2: zif_preg_replace (php_pcre.c:1385) ==26413== by 0x5E78E8: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:316) ==26413== by 0x5BD9AA: execute (zend_vm_execute.h:107) ==26413== by 0x599F44: zend_execute_scripts (zend.c:1194) ==26413== by 0x54AD47: php_execute_script (main.c:2261) ==26413== by 0x622CDD: main (php_cli.c:1192) ==26413== If you believe this happened as a result of a stack ==26413== overflow in your program's main thread (unlikely but ==26413== possible), you can try to increase the size of the ==26413== main thread stack using the --main-stacksize= flag. ==26413== The main thread stack size used in this run was 10485760. ==26413== Invalid read of size 8 ==26413== at 0x396EA08E15: do_lookup_x (do-lookup.h:47) ==26413== by 0x396EA092B1: _dl_lookup_symbol_x (dl-lookup.c:280) ==26413== by 0x396EA0CF64: _dl_fixup (dl-runtime.c:108) ==26413== by 0x396EA129E1: _dl_runtime_resolve (in /lib64/ld-2.5.so) ==26413== by 0x48024E8: _vgnU_freeres (vg_preloaded.c:62) ==26413== by 0x4F9777E: ??? ==26413== by 0x4612E2: php_pcre_replace_impl (string3.h:51) ==26413== by 0x461F9C: php_replace_in_subject (php_pcre.c:1267) ==26413== by 0x462593: preg_replace_impl (php_pcre.c:1365) ==26413== by 0x462AC2: zif_preg_replace (php_pcre.c:1385) ==26413== by 0x5E78E8: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:316) ==26413== by 0x5BD9AA: execute (zend_vm_execute.h:107) ==26413== Address 0x28 is not stack'd, malloc'd or (recently) free'd ==26413== ==26413== ==26413== Process terminating with default action of signal 11 (SIGSEGV) ==26413== Access not within mapped region at address 0x28 ==26413== at 0x396EA08E15: do_lookup_x (do-lookup.h:47) ==26413== by 0x396EA092B1: _dl_lookup_symbol_x (dl-lookup.c:280) ==26413== by 0x396EA0CF64: _dl_fixup (dl-runtime.c:108) ==26413== by 0x396EA129E1: _dl_runtime_resolve (in /lib64/ld-2.5.so) ==26413== by 0x48024E8: _vgnU_freeres (vg_preloaded.c:62) ==26413== by 0x4F9777E: ??? ==26413== by 0x4612E2: php_pcre_replace_impl (string3.h:51) ==26413== by 0x461F9C: php_replace_in_subject (php_pcre.c:1267) ==26413== by 0x462593: preg_replace_impl (php_pcre.c:1365) ==26413== by 0x462AC2: zif_preg_replace (php_pcre.c:1385) ==26413== by 0x5E78E8: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:316) ==26413== by 0x5BD9AA: execute (zend_vm_execute.h:107) ==26413== If you believe this happened as a result of a stack ==26413== overflow in your program's main thread (unlikely but ==26413== possible), you can try to increase the size of the ==26413== main thread stack using the --main-stacksize= flag. ==26413== The main thread stack size used in this run was 10485760. ==26413== ==26413== HEAP SUMMARY: ==26413== in use at exit: 2,714,420 bytes in 16,247 blocks ==26413== total heap usage: 17,374 allocs, 1,127 frees, 3,110,948 bytes allocated ==26413== ==26413== LEAK SUMMARY: ==26413== definitely lost: 1,497,751 bytes in 15,954 blocks ==26413== indirectly lost: 599 bytes in 11 blocks ==26413== possibly lost: 786,473 bytes in 4 blocks ==26413== still reachable: 429,597 bytes in 278 blocks ==26413== suppressed: 0 bytes in 0 blocks ==26413== Rerun with --leak-check=full to see details of leaked memory ==26413== ==26413== For counts of detected and suppressed errors, rerun with: -v ==26413== ERROR SUMMARY: 3238500 errors from 9 contexts (suppressed: 78 from 7) Segmentation fault
Crash reproduced on rhel5 with php53 5.3.3 and pcre 6.6.6 Not reproduced on rhel6 with php 5.3.3 and pcre 7.8 After investigation on this issue, It seems to be a "pcre" issue. In some case, pcre_exec returns a count value > 0 when it should be -1 (PCRE_ERROR_NOMATCH), and the offset vector contains dummy data.
Created attachment 628829 [details] preg.c Expected output: start:0, count:2 offsets[0]=0 offsets[1]=6 offsets[2]=0 offsets[3]=6 start:6, count:-1 Actual output: start:0, count:2 offsets[0]=0 offsets[1]=6 offsets[2]=0 offsets[3]=6 start:6, count:2 offsets[0]=31 offsets[1]=6 offsets[2]=31 offsets[3]=6 start offset should never be > than end
It's a bug in PCRE. The reproducer can be rewritten for pcretest this way: $ printf '%s\n%s\n' \ '/(?<!\<)(?<!\w)(\pL*foobar\pL*)(?!\w|[^<>]*>)/' \ ' – a – 00 aaźaaier' | pcretest PCRE version 6.6 06-Feb-2006 re> Segmentation fault
Minimal test case: $ printf '%s\n%s\n' '/\pL*a\pL/' 'źa' | pcretest PCRE version 6.6 06-Feb-2006 re> Segmentation fault There seems to be problem when using Unicode properties in ASCII mode on string with some non-ASCII characters.
I've bisected fix for this bug using minimal test case to revision 207 in pcre svn: http://vcs.pcre.org/viewvc?view=revision&revision=207 But a diff for this revision does not apply cleanly to revision 6.6. I tried to port it, but failed - it was still crashing. The fix has to be dependent on earlier code changes.
Created attachment 629315 [details] API/ABI compatibility report Maybe a simplest solution would be to just upgrade pcre to version 7.3 - the same which RHEL6 uses. I've compared this 2 version of library using ABI Compliance Checker 1.98.4 (http://ispras.linuxbase.org/index.php/ABI_compliance_checker) and I'm attaching a compatibility report. It looks like these 2 versions are compatible, so a new version should just work.
(In reply to comment #6) > Maybe a simplest solution would be to just upgrade pcre to version 7.3 - the > same which RHEL6 uses. Correction - RHEL6 uses 7.8, which is binary compatible with 6.6, but isn't source compatible - it lacks a global no_arg variable in namespace pcrecpp. Latest pcre version which is binary and source compatible with 6.6 is 7.5.
Thank you for finding the fix. Actually, it was quite easy to back-port it.
Created attachment 630005 [details] Upstream fix ported to pcre-6.6
This request was evaluated by Red Hat Product Management for inclusion in the current release of Red Hat Enterprise Linux. Because the affected component is not scheduled to be updated in the current release, Red Hat is unable to address this request at this time. Red Hat invites you to ask your support representative to propose this request, if appropriate, in the next release of Red Hat Enterprise Linux.
This request was evaluated by Red Hat Product Management for inclusion in a Red Hat Enterprise Linux release. Product Management has requested further review of this request by Red Hat Engineering, for potential inclusion in a Red Hat Enterprise Linux release for currently deployed products. This request is not yet committed for inclusion in a release.
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. http://rhn.redhat.com/errata/RHBA-2013-1298.html