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 

Reply via email to