[pcre-dev] [Bug 1803] segfault in pcre jit when running twig…

Top Page
Delete this message
Author: admin
Date:  
To: pcre-dev
Subject: [pcre-dev] [Bug 1803] segfault in pcre jit when running twig test suite (PHP7)
https://bugs.exim.org/show_bug.cgi?id=1803

--- Comment #30 from Nish Aravamudan <nish.aravamudan@???> ---
(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.