https://bugs.exim.org/show_bug.cgi?id=1803
--- Comment #30 from Nish Aravamudan <[email protected]> --- (In reply to Zoltan Herczeg from comment #29) > > I don't see any problem. So I'm not 100% sure it's this pattern in this > > execution that is bad, but some state somewhere (could be php, could be > > libpcre) is getting corrupted. > > I agree. This is my opinion as well. > > > I also noticed that for UTF8 specificaly, there is another pcre_exec that > > occurs (l#1853). > > I also mentioned this before. I had the feeling that the 2,4 offset pair is > coming from this pcre_exec (unfortunately both pcre_execs shares the same > ovector). This is confirmed now. And count really is stored in $eax. > > This is the result of the last pcre_exec: > > > (gdb) print offsets[0] > > $130 = 2 > > (gdb) print offsets[1] > > $131 = 4 > > (gdb) printf "0x%x\n", g_notempty > > 0x0 > > (gdb) step > > 1794 if (count == 0) { > > (gdb) print $eax > > $132 = 0 > > (gdb) print offsets[0] > > $133 = 2 > > (gdb) print offsets[1] > > $134 = 4 > > This confirms the "ovector is not changed" theory. The zero return value > means there is not enough space in the ovector, and offsets are not updated. > More precisely it seems as if 0 is passed for the length of offsets vector > (size_offsets is changed to zero somehow?). > > Because count is zero: > > if (count == 0) { > php_error_docref(NULL,E_NOTICE, "Matched, but too many substrings"); > count = size_offsets/3; > } > > count got a new value. However, if size_offsets would be changed to 0, count > would be zero again (0/3=0). > > And the following condition (where the segfault happens) would not be > fulfilled: > > if (count > 0 && (offsets[1] - offsets[0] >= 0)) { > > To make things even more confusing, pcre_exec runs correctly during the > first run: > > > 1794 if (count == 0) { > > (gdb) print $eax > > $122 = 1 > > (gdb) print offsets[0] > > $123 = 2 > > (gdb) print offsets[1] > > $124 = 2 > > Here, there was enough space so the return value was 1, and offsets vector > was updated (2,2 is the correct result for the first run). > > I think we should focus on the size_offsets variable, and what is passed to > pcre_exec. It seems to me that although size_offsets did not change its > value (regardless please print it), somehow 0 is passed to pcre_exec. Or the > passed value is overwritten to zero later (buffer overflow?). Could you > enter to pcre_exec and print the arguments? Especially the size of the > ovector (offsetcount). A watchpoint could help to find where the value is > changed if the argument is correct. I think you're right: Breakpoint 9, php_pcre_split_impl (pce=0x555555d333e0, subject=0x7fffed40b1a8 "\303\251\303\204\303\237\343\201\224a", subject_len=10, return_value=0x7ffff381b240, limit_val=-1, flags=<optimized out>) at /build/php7.0-WHFaJZ/php7.0-7.0.3/ext/pcre/php_pcre.c:1786 1786 count = pcre_exec(pce->re, extra, subject, (gdb) print size_offsets $165 = 3 (gdb) c Continuing. Breakpoint 9, php_pcre_split_impl (pce=0x555555d333e0, subject=0x7fffed40b1a8 "\303\251\303\204\303\237\343\201\224a", subject_len=10, return_value=0x7ffff381b240, limit_val=-1, flags=<optimized out>) at /build/php7.0-WHFaJZ/php7.0-7.0.3/ext/pcre/php_pcre.c:1786 1786 count = pcre_exec(pce->re, extra, subject, (gdb) print size_offsets $166 = 3 (gdb) c Continuing. Breakpoint 10, php_pcre_split_impl (pce=0x555555d333e0, subject=0x7fffed40b1a8 "\303\251\303\204\303\237\343\201\224a", subject_len=10, return_value=0x7ffff381b240, limit_val=-1, flags=<optimized out>) at /build/php7.0-WHFaJZ/php7.0-7.0.3/ext/pcre/php_pcre.c:1851 1851 count = pcre_exec(re_bump, extra_bump, subject, (gdb) print size_offsets $167 = 3 (gdb) c Continuing. Breakpoint 9, php_pcre_split_impl (pce=0x555555d333e0, subject=0x7fffed40b1a8 "\303\251\303\204\303\237\343\201\224a", subject_len=10, return_value=0x7ffff381b240, limit_val=-1, flags=<optimized out>) at /build/php7.0-WHFaJZ/php7.0-7.0.3/ext/pcre/php_pcre.c:1786 1786 count = pcre_exec(pce->re, extra, subject, (gdb) print size_offsets $168 = 0 (gdb) c Continuing. Breakpoint 9, php_pcre_split_impl (pce=0x555555d333e0, subject=0x7fffed40b1a8 "\303\251\303\204\303\237\343\201\224a", subject_len=10, return_value=0x7ffff381b240, limit_val=-1, flags=<optimized out>) at /build/php7.0-WHFaJZ/php7.0-7.0.3/ext/pcre/php_pcre.c:1786 1786 count = pcre_exec(pce->re, extra, subject, (gdb) print size_offsets $169 = 0 (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. __memcpy_avx_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-avx-unaligned.S:271 271 ../sysdeps/x86_64/multiarch/memcpy-avx-unaligned.S: No such file or directory. I will do some more digging into what is changing that value to 0. -- You are receiving this mail because: You are on the CC list for the bug. -- ## List details at https://lists.exim.org/mailman/listinfo/pcre-dev
