Front page | perl.perl5.porters |
Postings from October 2016
Re: [perl #129903] regexec.c stack overflow
Thread Previous
|
Thread Next
From:
demerphq
Date:
October 18, 2016 08:17
Subject:
Re: [perl #129903] regexec.c stack overflow
Message ID:
CANgJU+WDXp_wf_U7w6weFA9=kg---F_Zog1-vEKUk4-+D2Wb3Q@mail.gmail.com
On 18 October 2016 at 10:00, demerphq <demerphq@gmail.com> wrote:
> On 18 October 2016 at 03:17, Father Chrysostomos via RT
> <perlbug-followup@perl.org> wrote:
>> On Mon Oct 17 10:26:19 2016, brian.carpenter@gmail.com wrote:
>>> I'm not convinced that this is an actual bug,
>>
>> I think it is.
>>
>>> but #p5p was silent when I
>>> asked about it. Affects Perl back to 5.20.2 including v5.25.6
>>> (v5.25.5-114-g87af8d5). Valgrind fails pretty quickly but gdb just goes on
>>> forever.
>>>
>>> perl -e '/0'
>>
>> That is nonsensical code.
>
> Do you mean just the '/0' or the full pattern?
>
> With some editing I read the original code as being the same as
>
>
> (m/(?{
> m!(0)!,
> s!!!
> })/) / 0
>
> Which is strange but IMO valid code.
>
>> $ perl5.18.3 -e '/(?{m}(0)},s\/\/\/})//0'
>> Segmentation fault: 11
>> $ perl5.14.4 -e '/(?{m}(0)},s\/\/\/})//0'
>> Sequence (?{...}) not terminated or not {}-balanced in regex; marked by <-- HERE in m/(?{ <-- HERE m}(0)},s///})/ at -e line 1.
>>
>> I do not have 5.16 handy. The output from 5.14 is what I would expect.
>
> I am not sure why. Is it because you expect the first } to close the
> (?{ , while I dont? The inside of the (?{ ... }) is code, and should
> follow nesting rules, so m}(0)} should be parsed and extracted as a
> balanced construct, just as it would if it were q}foo}, and then the
> s/// gets parsed out, to find the trailing }) which finish the (?{})
> construct.
>
> I would say the 5.14.4 behavior is a misparse.
>
> If this is legal:
>
> perl -le'print q}foo}'
> foo
>
> then I would expect this:
>
> m}(0)}
>
> to be legal too, and i would expect it to be legal inside of a (?{ ...
> }) construct in a pattern.
>
>>> ==6615==ERROR: AddressSanitizer: stack-overflow on address 0x7ffc78f88ca8
>>> (pc 0x0000004c0d4c bp 0x7ffc78f89500 sp 0x7ffc78f88cb0 T0)
>>> #0 0x4c0d4b in calloc (/root/perl/perl+0x4c0d4b)
>>> #1 0x7f9301 in Perl_safesyscalloc /root/perl/util.c:442:18
>>> #2 0xb45aed in Perl_regexec_flags /root/perl/regexec.c:3128:9
>>> #3 0x8cf9c5 in Perl_pp_subst /root/perl/pp_hot.c:2981:10
>>> #4 0x7f4483 in Perl_runops_debug /root/perl/dump.c:2246:23
>>> #5 0xb984b6 in S_regmatch /root/perl/regexec.c:6888:3
>>> #6 0xb7337c in S_regtry /root/perl/regexec.c:3622:14
>>
>> It should not even be getting that far. It should fail at compile time.
>
> Looking forward to hearing more on why.
I dont think the simplified version of the code should infinite loop
on the stack.
For this code (because $_ is the empty string) we should perform an
outer match once, then a match using qr/(0)/ twice, once via the
"empty pattern special case" in the s///, both of which should fail,
and then the outer match should stop. We should not loop. Apparently
the problem is related to the empty-pattern special case behavior. If
I change the pattern from
m/(?{ m!(0)!, s!!! })/
to
m/(?{ m!(0)!, s!(0)!! })/
which should be equivalent valgrind is happy and we get what I expect,
a division by zero error:
$ ./perl -le'(m/(?{ m!(0)!, s!(0)!! })/) / 0'
Illegal division by zero at -e line 1.
$ ./perl -le'(m/(?{ m!(0)!, s!!! })/) / 0'
Segmentation fault
And here is the valgrind output:
$ valgrind ./perl -le'(m/(?{ m!(0)!, s!!! })/) / 0'
==25240== Memcheck, a memory error detector
==25240== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==25240== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==25240== Command: ./perl -le(m/(?{\ m!(0)!,\ s!!!\ })/)\ /\ 0
==25240==
==25240== Stack overflow in thread 1: can't grow stack to 0xffe801f88
==25240==
==25240== Process terminating with default action of signal 11 (SIGSEGV)
==25240== Access not within mapped region at address 0xFFE801F88
==25240== at 0x5D01B0: Perl_sv_2pv_flags (sv.c:2939)
==25240== If you believe this happened as a result of a stack
==25240== overflow in your program's main thread (unlikely but
==25240== possible), you can try to increase the size of the
==25240== main thread stack using the --main-stacksize= flag.
==25240== The main thread stack size used in this run was 8388608.
==25240== Stack overflow in thread 1: can't grow stack to 0xffe801f68
==25240==
==25240== Process terminating with default action of signal 11 (SIGSEGV)
==25240== Access not within mapped region at address 0xFFE801F68
==25240== at 0x4A256B0: _vgnU_freeres (in
/usr/lib/valgrind/vgpreload_core-amd64-linux.so)
==25240== If you believe this happened as a result of a stack
==25240== overflow in your program's main thread (unlikely but
==25240== possible), you can try to increase the size of the
==25240== main thread stack using the --main-stacksize= flag.
==25240== The main thread stack size used in this run was 8388608.
==25240==
==25240== HEAP SUMMARY:
==25240== in use at exit: 7,449,285 bytes in 11,675 blocks
==25240== total heap usage: 11,825 allocs, 150 frees, 8,150,685
bytes allocated
==25240==
==25240== LEAK SUMMARY:
==25240== definitely lost: 0 bytes in 0 blocks
==25240== indirectly lost: 0 bytes in 0 blocks
==25240== possibly lost: 0 bytes in 0 blocks
==25240== still reachable: 7,449,285 bytes in 11,675 blocks
==25240== suppressed: 0 bytes in 0 blocks
==25240== Rerun with --leak-check=full to see details of leaked memory
==25240==
==25240== For counts of detected and suppressed errors, rerun with: -v
==25240== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Segmentation fault
This is definitely a bug.
Yves
--
perl -Mre=debug -e "/just|another|perl|hacker/"
Thread Previous
|
Thread Next