Skip Menu |
Report information
Id: 125351
Status: open
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: brian.carpenter [at] gmail.com
sraums2498 [at] gmail.com
Cc:
AdminCc:

Operating System: (no value)
PatchStatus: (no value)
Severity: low
Type: unknown
Perl Version: (no value)
Fixed In: (no value)



Subject: null ptr deref -> Perl_ck_shift (op.c:10857)
Download (untitled) / with headers
text/plain 5.6k
The attached "script" causes a null ptr deref and seg fault in Perl v5.23.0 (v5.22.0-63-g216b41c): Program received signal SIGSEGV, Segmentation fault. 0x000000000049a777 in Perl_ck_shift () at op.c:10857 10857 if (!CvUNIQUE(PL_compcv)) { (gdb) bt #0 0x000000000049a777 in Perl_ck_shift () at op.c:10857 #1 0x000000000065f233 in Perl_yyparse () #2 0x0000000000534d79 in perl_parse () #3 0x000000000042ac38 in main () at perlmain.c:114 (gdb) i r rax 0x0 0 rbx 0x11e1fb0 18751408 rcx 0x0 0 rdx 0x0 0 rsi 0xa5 165 rdi 0x11e1fb0 18751408 rbp 0xa5 0xa5 rsp 0x7fffffffdf20 0x7fffffffdf20 r8 0xac1580 11277696 r9 0x0 0 r10 0x0 0 r11 0x27 39 r12 0xc6 198 r13 0x11f04f0 18810096 r14 0x27 39 r15 0xef5a0f 15686159 rip 0x49a777 0x49a777 <Perl_ck_shift+167> eflags 0x10246 [ PF ZF IF RF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0 ==51781== Invalid read of size 8 ==51781== at 0x49A777: Perl_ck_shift (op.c:10857) ==51781== by 0x65F232: Perl_yyparse (perly.y:996) ==51781== by 0x534D78: perl_parse (perl.c:2296) ==51781== by 0x42AC37: main (perlmain.c:114) ==51781== Address 0x0 is not stack'd, malloc'd or (recently) free'd ==51781== ==51781== ==51781== Process terminating with default action of signal 11 (SIGSEGV) ==51781== Access not within mapped region at address 0x0 ==51781== at 0x49A777: Perl_ck_shift (op.c:10857) ==51781== by 0x65F232: Perl_yyparse (perly.y:996) ==51781== by 0x534D78: perl_parse (perl.c:2296) ==51781== by 0x42AC37: main (perlmain.c:114) ==51781== If you believe this happened as a result of a stack ==51781== overflow in your program's main thread (unlikely but ==51781== possible), you can try to increase the size of the ==51781== main thread stack using the --main-stacksize= flag. ==51781== The main thread stack size used in this run was 8388608. Segmentation fault It also causes a null ptr deref and seg fault in Perl v5.21.7 (v5.21.6-602-ge9d2bd8), albeit in a different location and file: Program received signal SIGSEGV, Segmentation fault. S_pad_findlex (namepv=namepv@entry=0x7fffffffdb30 "&shift", namelen=namelen@entry=6, flags=flags@entry=0, cv=0x0, seq=4, Perl_warn=Perl_warn@entry=1, out_capture=out_capture@entry=0x0, out_name=out_name@entry=0x7fffffffd8f0, out_flags=out_flags@entry=0x7fffffffd8e0) at pad.c:1141 1141 pad.c: No such file or directory. (gdb) bt #0 S_pad_findlex (namepv=namepv@entry=0x7fffffffdb30 "&shift", namelen=namelen@entry=6, flags=flags@entry=0, cv=0x0, seq=4, Perl_warn=Perl_warn@entry=1, out_capture=out_capture@entry=0x0, out_name=out_name@entry=0x7fffffffd8f0, out_flags=out_flags@entry=0x7fffffffd8e0) at pad.c:1141 #1 0x00000000005e217d in Perl_pad_findmy_pvn (namepv=0x7fffffffdb30 "&shift", namelen=6, flags=<optimized out>) at pad.c:962 #2 0x0000000000579950 in Perl_yylex () at toke.c:6430 #3 0x00000000005c60b5 in Perl_yyparse (gramtype=<optimized out>) at perly.c:322 #4 0x00000000004f0875 in S_parse_body (xsinit=0x42ac70 <xs_init>, env=0x0) at perl.c:2271 #5 perl_parse (my_perl=<optimized out>, xsinit=0x42ac70 <xs_init>, argc=<optimized out>, argv=<optimized out>, env=0x0) at perl.c:1605 #6 0x000000000042a87c in main (argc=2, argv=0x7fffffffe3a8, env=0x7fffffffe3c0) at perlmain.c:114 #7 0x00007ffff6f98ead in __libc_start_main (main=<optimized out>, argc=<optimized out>, ubp_av=<optimized out>, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe398) at libc-start.c:244 #8 0x000000000042ab95 in _start () (gdb) i r rax 0x7fffffffd8e0 140737488345312 rbx 0x0 0 rcx 0x0 0 rdx 0x0 0 rsi 0x0 0 rdi 0x7fffffffdb30 140737488345904 rbp 0x6 0x6 rsp 0x7fffffffd7f0 0x7fffffffd7f0 r8 0x4 4 r9 0x1 1 r10 0x5 5 r11 0x7ffff70cf4f0 140737338209520 r12 0x7fffffffdb31 140737488345905 r13 0x0 0 r14 0x6 6 r15 0xe42065 14950501 rip 0x5dea2f 0x5dea2f <S_pad_findlex+55> eflags 0x10246 [ PF ZF IF RF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0 ==12210== Invalid read of size 8 ==12210== at 0x5DEA2F: S_pad_findlex (pad.c:1141) ==12210== by 0x5E217C: Perl_pad_findmy_pvn (pad.c:962) ==12210== by 0x57994F: Perl_yylex (toke.c:6430) ==12210== by 0x5C60B4: Perl_yyparse (perly.c:322) ==12210== by 0x4F0874: perl_parse (perl.c:2271) ==12210== by 0x42A87B: main (perlmain.c:114) ==12210== Address 0x0 is not stack'd, malloc'd or (recently) free'd ==12210== ==12210== ==12210== Process terminating with default action of signal 11 (SIGSEGV) ==12210== Access not within mapped region at address 0x0 ==12210== at 0x5DEA2F: S_pad_findlex (pad.c:1141) ==12210== by 0x5E217C: Perl_pad_findmy_pvn (pad.c:962) ==12210== by 0x57994F: Perl_yylex (toke.c:6430) ==12210== by 0x5C60B4: Perl_yyparse (perly.c:322) ==12210== by 0x4F0874: perl_parse (perl.c:2271) ==12210== by 0x42A87B: main (perlmain.c:114) ==12210== If you believe this happened as a result of a stack ==12210== overflow in your program's main thread (unlikely but ==12210== possible), you can try to increase the size of the ==12210== main thread stack using the --main-stacksize= flag. ==12210== The main thread stack size used in this run was 8388608. Segmentation fault This bug was found with AFL (http://lcamtuf.coredump.cx/afl/).
Subject: test555-min
Download test555-min
application/octet-stream 21b

Message body not shown because it is not plain text.

RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 594b
On Sun Jun 07 12:36:52 2015, brian.carpenter@gmail.com wrote: Show quoted text
> The attached "script" causes a null ptr deref and seg fault in Perl > v5.23.0 (v5.22.0-63-g216b41c): > > Program received signal SIGSEGV, Segmentation fault. > 0x000000000049a777 in Perl_ck_shift () at op.c:10857 > 10857 if (!CvUNIQUE(PL_compcv)) { > (gdb) bt > #0 0x000000000049a777 in Perl_ck_shift () at op.c:10857 > #1 0x000000000065f233 in Perl_yyparse () > #2 0x0000000000534d79 in perl_parse () > #3 0x000000000042ac38 in main () at perlmain.c:114
This looks like it has the same base cause as 124187. Tony
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 170b
FYI, this issue is still present in v5.23.1-213-g4b06b8d. On Tue Jun 09 22:52:01 2015, tonyc wrote: Show quoted text
> > This looks like it has the same base cause as 124187. > > Tony
Subject: 1 script + 2 versions of Perl = 2 different null ptr deref / segfaults
Download (untitled) / with headers
text/plain 3.7k
perl -e 'qq{@{sub{]]}}}}-shift' triggers a null ptr deref and segfault in perl v5.21.7 (v5.21.6-602-ge9d2bd8). S_pad_findlex (namepv=namepv@entry=0x7fffffffdb30 "&shift", namelen=namelen@entry=6, flags=flags@entry=0, cv=0x0, seq=4, Perl_warn=Perl_warn@entry=1, out_capture=out_capture@entry=0x0, out_name=out_name@entry=0x7fffffffd8f0, out_flags=out_flags@entry=0x7fffffffd8e0) at pad.c:1141 1141 pad.c: No such file or directory. (gdb) bt #0 S_pad_findlex (namepv=namepv@entry=0x7fffffffdb30 "&shift", namelen=namelen@entry=6, flags=flags@entry=0, cv=0x0, seq=4, Perl_warn=Perl_warn@entry=1, out_capture=out_capture@entry=0x0, out_name=out_name@entry=0x7fffffffd8f0, out_flags=out_flags@entry=0x7fffffffd8e0) at pad.c:1141 #1 0x00000000005e217d in Perl_pad_findmy_pvn (namepv=0x7fffffffdb30 "&shift", namelen=6, flags=<optimized out>) at pad.c:962 #2 0x0000000000579950 in Perl_yylex () at toke.c:6430 #3 0x00000000005c60b5 in Perl_yyparse (gramtype=<optimized out>) at perly.c:322 #4 0x00000000004f0875 in S_parse_body (xsinit=0x42ac70 <xs_init>, env=0x0) at perl.c:2271 #5 perl_parse (my_perl=<optimized out>, xsinit=0x42ac70 <xs_init>, argc=<optimized out>, argv=<optimized out>, env=0x0) at perl.c:1605 #6 0x000000000042a87c in main (argc=2, argv=0x7fffffffe3a8, env=0x7fffffffe3c0) at perlmain.c:114 #7 0x00007ffff6f98ead in __libc_start_main (main=<optimized out>, argc=<optimized out>, ubp_av=<optimized out>, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe398) at libc-start.c:244 #8 0x000000000042ab95 in _start () ==46065== Invalid read of size 8 ==46065== at 0x5DEA2F: S_pad_findlex (pad.c:1141) ==46065== by 0x5E217C: Perl_pad_findmy_pvn (pad.c:962) ==46065== by 0x57994F: Perl_yylex (toke.c:6430) ==46065== by 0x5C60B4: Perl_yyparse (perly.c:322) ==46065== by 0x4F0874: S_parse_body (perl.c:2271) ==46065== by 0x4F0874: perl_parse (perl.c:1605) ==46065== by 0x42A87B: main (perlmain.c:114) ==46065== Address 0x0 is not stack'd, malloc'd or (recently) free'd ==46065== Process terminating with default action of signal 11 (SIGSEGV) ==46065== Access not within mapped region at address 0x0 ==46065== at 0x5DEA2F: S_pad_findlex (pad.c:1141) ==46065== by 0x5E217C: Perl_pad_findmy_pvn (pad.c:962) ==46065== by 0x57994F: Perl_yylex (toke.c:6430) ==46065== by 0x5C60B4: Perl_yyparse (perly.c:322) ==46065== by 0x4F0874: S_parse_body (perl.c:2271) ==46065== by 0x4F0874: perl_parse (perl.c:1605) ==46065== by 0x42A87B: main (perlmain.c:114) This same script also triggers a completely different null ptr deref and segfault in perl v5.23.4 (v5.23.3-7-ge120c24): 0x00000000004a07c7 in Perl_ck_shift () at op.c:10710 10710 if (!CvUNIQUE(PL_compcv)) { (gdb) bt #0 0x00000000004a07c7 in Perl_ck_shift () at op.c:10710 #1 0x000000000066df23 in Perl_yyparse () #2 0x000000000053c005 in S_parse_body () at perl.c:2304 #3 0x0000000000543d83 in perl_parse () at perl.c:1634 #4 0x000000000042c6f8 in main () at perlmain.c:114 ==24849== Invalid read of size 8 ==24849== at 0x4A07C7: Perl_ck_shift (op.c:10710) ==24849== by 0x66DF22: Perl_yyparse (perly.y:996) ==24849== by 0x53C004: S_parse_body (perl.c:2304) ==24849== by 0x543D82: perl_parse (perl.c:1634) ==24849== by 0x42C6F7: main (perlmain.c:114) ==24849== Address 0x0 is not stack'd, malloc'd or (recently) free'd ==24849== Process terminating with default action of signal 11 (SIGSEGV) ==24849== Access not within mapped region at address 0x0 ==24849== at 0x4A07C7: Perl_ck_shift (op.c:10710) ==24849== by 0x66DF22: Perl_yyparse (perly.y:996) ==24849== by 0x53C004: S_parse_body (perl.c:2304) ==24849== by 0x543D82: perl_parse (perl.c:1634) ==24849== by 0x42C6F7: main (perlmain.c:114)
RT-Send-CC: perl5-porters [...] perl.org
This issue is still present in v5.23.7 (v5.23.6-109-g388b516).
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 853b
From v5.25.4 (v5.25.3-305-g8c6b0c7): ./perl -e 'qq{@{sub{q}}]]}};s0{shift' ASAN:SIGSEGV ================================================================= ==31752==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x00000055ff13 bp 0x7ffda0f99310 sp 0x7ffda0f99110 T0) #0 0x55ff12 in Perl_ck_shift /root/perl/op.c:10881:7 #1 0x6b5f8c in Perl_yyparse /root/perl/perly.y:1166:23 #2 0x59c4a1 in S_parse_body /root/perl/perl.c:2372:9 #3 0x59283c in perl_parse /root/perl/perl.c:1688:2 #4 0x4de835 in main /root/perl/perlmain.c:121:18 #5 0x7f34f1834b44 in __libc_start_main /build/glibc-uPj9cH/glibc-2.19/csu/libc-start.c:287 #6 0x4de4cc in _start (/root/perl/perl+0x4de4cc) AddressSanitizer can not provide additional info. SUMMARY: AddressSanitizer: SEGV /root/perl/op.c:10881 Perl_ck_shift ==31752==ABORTING
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 825b
On Fri Sep 25 19:47:03 2015, brian.carpenter@gmail.com wrote: Show quoted text
> perl -e 'qq{@{sub{]]}}}}-shift'
v5.25.5 (v5.25.4-110-g95c0a76) ==9144==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x00000055fdf3 bp 0x7ffcd79efc10 sp 0x7ffcd79efa30 T0) #0 0x55fdf2 in Perl_ck_shift /root/perl/op.c:10914:7 #1 0x6b6d05 in Perl_yyparse /root/perl/perly.y:1162:23 #2 0x59c451 in S_parse_body /root/perl/perl.c:2373:9 #3 0x5927fc in perl_parse /root/perl/perl.c:1689:2 #4 0x4de5d5 in main /root/perl/perlmain.c:121:18 #5 0x7f43e8cb8b44 in __libc_start_main /build/glibc-uPj9cH/glibc-2.19/csu/libc-start.c:287 #6 0x4de26c in _start (/root/perl/perl+0x4de26c) AddressSanitizer can not provide additional info. SUMMARY: AddressSanitizer: SEGV /root/perl/op.c:10914 Perl_ck_shift ==9144==ABORTING
RT-Send-CC: perl5-porters [...] perl.org
perl -e 'qq{@{sub{]]}}}}*shift' triggers this crash in v5.25.6 (v5.25.5-104-gaff2be5).
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 3.1k
The original case is still crashing as before: % ./miniperl -e 'qq{@{sub{]]}}}};shift' Segmentation fault (core dumped) % .. due to a NULL PL_compcv set by Perl_newATTRSUB_x() (since Father C's 9ffcdca1f5) and hit in Perl_ck_shift(). It seems clear that as mooted this is essentially the same underlying issue as [perl #124187], but that one has been resolved so they should not be merged. I'll copy Dave's commit message from there, since it will be more useful here for the future (particularly the bit about PL_compcv): commit de0885da327045eed274d7f8913a58e6de0e0f30 Author: David Mitchell <davem@iabyn.com> Date: Tue May 5 10:44:16 2015 +0100 null ptr deref in Perl_cv_forget_slab RT #124385 Parsing following a syntax error could result in a null ptr dereference. This commit contains a band-aid that returns from Perl_cv_forget_slab() if the cv arg is null; but the real issue is much deeper and needs a more general fix at some point. Basically, both the lexer and the parser use the save stack, and after an error, they can get out of sync. In particular: 1) when handling a double-quoted string, the lexer does an ENTER, saves most of its current state on the save stack, then uses the literal string as the toke source. When it reaches the end of the string, it LEAVEs, restores the lexer state and continues with the main source. 2) Whenever the parser starts a new block or sub scope, it remembers the current save stack position, and at end of scope, pops the save stack back to that position. In something like "@{ sub {]}} }}}" the lexer sees a double-quoted string, and saves the current lex state. The parser sees the start of a sub, and saves PL_compcv etc. Then a parse error occurs. The parser goes into error recovery, discarding tokens until it can return to a sane state. The lexer runs out of tokens when toking the string, does a LEAVE, and switches back to toking the main source. This LEAVE restores both the lexer's and the parser's state; in particular the parser gets its old PL_compcv restored, even though the parser hasn't finished compiling the current sub. Later, series of '}' tokens coming through allows the parser to finish the sub. Since PL_error_count > 0, it discards the just-compiled sub and sets PL_compcv to null. Normally the LEAVE_SCOPE done just after this would restore PL_compcv to its old value (e.g. PL_main_cv) but the stack has already been popped, so PL_compcv gets left null, and SEGVs occur. The two main ways I can think of fixing this in the long term are 1) avoid the lexer using the save stack for long-term state storage; in particular, make S_sublex_push() malloc a new parser object rather than saving the current lexer state on the save stack. 2) At the end of a sublex, if PL_error_count > 0, don't try to restore state and continue, instead just croak. N.B. the test that this commit adds to lex.t doesn't actually trigger the SEGV, since the bad code is wrapped in an eval which (for reasons I haven't researched) avoids the SEGV.
RT-Send-CC: perl5-porters [...] perl.org
This looks to be the same as [perl #125351], I'll merge them. Hugo
From: Zefram <zefram [...] fysh.org>
Subject: Re: [perl #125351] null ptr deref -> Perl_ck_shift (op.c:10857)
To: perl5-porters [...] perl.org
Date: Fri, 31 Mar 2017 14:15:28 +0100
Looks to be the same mechanism as [perl #126191]. -zefram
To: perl5-security-report [...] perl.org
Date: Thu, 21 Dec 2017 16:38:00 +0530
Subject: PERL-5.26.1 heap_buffer_overflow READ of size 8
From: SRAUMS JN <sraums2498 [...] gmail.com>
Download (untitled) / with headers
text/plain 3.3k
=================================================================
==114384==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000e8e0 at pc 0x000000f14a34 bp 0x7fff4e9807b0 sp 0x7fff4e9807a0
READ of size 8 at 0x60300000e8e0 thread T0
    #0 0xf14a33 in Perl_cv_undef_flags /home/asan_perl/Documents/perl-5.26.1/pad.c:397
    #1 0x1cc91a1 in Perl_sv_clear /home/asan_perl/Documents/perl-5.26.1/sv.c:6623
    #2 0x1ca0107 in Perl_sv_free2 /home/asan_perl/Documents/perl-5.26.1/sv.c:7073
    #3 0x8de987 in S_SvREFCNT_dec /home/asan_perl/Documents/perl-5.26.1/inline.h:189
    #4 0x8de987 in perl_destruct /home/asan_perl/Documents/perl-5.26.1/perl.c:840
    #5 0x46b5fb in main /home/asan_perl/Documents/perl-5.26.1/perlmain.c:134
    #6 0x7fd03655782f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #7 0x46c888 in _start (/home/asan_perl/Documents/perl-5.26.1/perl+0x46c888)

0x60300000e8e0 is located 0 bytes to the right of 32-byte region [0x60300000e8c0,0x60300000e8e0)
allocated by thread T0 here:
    #0 0x7fd0372fb602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602)
    #1 0x167dd81 in Perl_safesysmalloc /home/asan_perl/Documents/perl-5.26.1/util.c:153
    #2 0x1adf2d0 in Perl_av_extend_guts /home/asan_perl/Documents/perl-5.26.1/av.c:186
    #3 0x1aed221 in Perl_av_extend /home/asan_perl/Documents/perl-5.26.1/av.c:80
    #4 0x1aed221 in Perl_av_store /home/asan_perl/Documents/perl-5.26.1/av.c:355
    #5 0xf248f4 in Perl_pad_new /home/asan_perl/Documents/perl-5.26.1/pad.c:231
    #6 0x905842 in S_parse_body /home/asan_perl/Documents/perl-5.26.1/perl.c:2272
    #7 0x905842 in perl_parse /home/asan_perl/Documents/perl-5.26.1/perl.c:1692
    #8 0x46b239 in main /home/asan_perl/Documents/perl-5.26.1/perlmain.c:121
    #9 0x7fd03655782f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/asan_perl/Documents/perl-5.26.1/pad.c:397 Perl_cv_undef_flags
Shadow bytes around the buggy address:
  0x0c067fff9cc0: 02 fa fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa
  0x0c067fff9cd0: 00 00 00 00 fa fa fd fd fd fd fa fa 00 00 00 00
  0x0c067fff9ce0: fa fa fd fd fd fd fa fa 00 00 00 00 fa fa fd fd
  0x0c067fff9cf0: fd fd fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa
  0x0c067fff9d00: fd fd fd fd fa fa fd fd fd fd fa fa 00 00 00 00
=>0x0c067fff9d10: fa fa 00 00 00 00 fa fa 00 00 00 00[fa]fa 00 00
  0x0c067fff9d20: 00 fa fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa
  0x0c067fff9d30: 00 00 00 05 fa fa 00 00 00 00 fa fa fd fd fd fd
  0x0c067fff9d40: fa fa 00 00 07 fa fa fa 00 00 03 fa fa fa 00 00
  0x0c067fff9d50: 00 02 fa fa 00 00 00 07 fa fa 00 00 03 fa fa fa
  0x0c067fff9d60: 00 00 00 00 fa fa 00 00 02 fa fa fa 00 00 00 02
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
==114384==ABORTING


--
Regards,
SRAUMS
Download 89
application/octet-stream 42b

Message body not shown because it is not plain text.

RT-Send-CC: perl5-security-report [...] perl.org
Download (untitled) / with headers
text/plain 366b
This appears similar to rt131836, but is not fixed by its fix. It reduces at least to: ./miniperl -e 's//${sub{b{]]]{}#$/ sub{}' with the same stack trace. I'll come back to this after completing triage on the current batch of new tickets if nobody else gets to it, but I anticipate it'll need more knowledge of the lex/parse phase than I can bring to bear. Hugo
RT-Send-CC: perl5-security-report [...] perl.org
Download (untitled) / with headers
text/plain 511b
On Mon, 08 Jan 2018 16:41:35 -0800, hv wrote: Show quoted text
> This appears similar to rt131836, but is not fixed by its fix. It > reduces at least to: > ./miniperl -e 's//${sub{b{]]]{}#$/ sub{}' > with the same stack trace. > > I'll come back to this after completing triage on the current batch of > new tickets if nobody else gets to it, but I anticipate it'll need > more knowledge of the lex/parse phase than I can bring to bear.
This looks like another case of #125351 and other similar sublex recovery issues. Tony
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 761b
On Wed, 17 Jan 2018 16:24:03 -0800, tonyc wrote: Show quoted text
> On Mon, 08 Jan 2018 16:41:35 -0800, hv wrote:
> > This appears similar to rt131836, but is not fixed by its fix. It > > reduces at least to: > > ./miniperl -e 's//${sub{b{]]]{}#$/ sub{}' > > with the same stack trace. > > > > I'll come back to this after completing triage on the current batch > > of > > new tickets if nobody else gets to it, but I anticipate it'll need > > more knowledge of the lex/parse phase than I can bring to bear.
> > This looks like another case of #125351 and other similar sublex > recovery issues.
And so it is. Since it requires feedng code to the interpreter it isn't a security issue, so it's now public. Since it duplicates #125351 I'm merging it into that ticket. Tony
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 912b
On Mon, 29 Jan 2018 21:29:37 -0800, tonyc wrote: Show quoted text
> On Wed, 17 Jan 2018 16:24:03 -0800, tonyc wrote:
> > On Mon, 08 Jan 2018 16:41:35 -0800, hv wrote:
> > > This appears similar to rt131836, but is not fixed by its fix. It > > > reduces at least to: > > > ./miniperl -e 's//${sub{b{]]]{}#$/ sub{}' > > > with the same stack trace. > > > > > > I'll come back to this after completing triage on the current batch > > > of > > > new tickets if nobody else gets to it, but I anticipate it'll need > > > more knowledge of the lex/parse phase than I can bring to bear.
> > > > This looks like another case of #125351 and other similar sublex > > recovery issues.
> > And so it is. > > Since it requires feedng code to the interpreter it isn't a security > issue, so it's now public. > > Since it duplicates #125351 I'm merging it into that ticket.
And here is hopefully a patch for this long-standing issue. Tony
Subject: 0001-perl-125351-abort-parsing-if-parse-errors-happen-in-.patch
From abf27f937c988e96bf65c6be92ac4edc188e31c3 Mon Sep 17 00:00:00 2001 From: Tony Cook <tony@develop-help.com> Date: Tue, 30 Jan 2018 16:40:53 +1100 Subject: (perl #125351) abort parsing if parse errors happen in a sub lex We've had a few reports of segmentation faults and other misbehaviour when sub-parsing, such as within interpolated expressions, fails. This change aborts compilation if anything complex enough to not be parsed by the lexer is compiled in a sub-parse *and* an error occurs within the sub-parse. An earlier version of this patch failed on simpler expressions, which caused many test failures, which this version doesn't (which may just mean we need more tests...) --- parser.h | 2 ++ t/base/lex.t | 11 ++++++++++- toke.c | 18 ++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/parser.h b/parser.h index 4187e0a93d..216e9deca8 100644 --- a/parser.h +++ b/parser.h @@ -58,6 +58,7 @@ typedef struct yy_parser { 1 = @{...} 2 = ->@ */ U8 expect; /* how to interpret ambiguous tokens */ bool preambled; + bool sub_no_recover; /* can't recover from a sublex error */ I32 lex_formbrack; /* bracket count at outer format level */ OP *lex_inpat; /* in pattern $) and $| are special */ OP *lex_op; /* extra info to pass back on op */ @@ -95,6 +96,7 @@ typedef struct yy_parser { U16 in_my; /* we're compiling a "my"/"our" declaration */ U8 lex_state; /* next token is determined */ U8 error_count; /* how many compile errors so far, max 10 */ + U8 sub_error_count; /* the number of errors before sublexing */ HV *in_my_stash; /* declared class of this "my" declaration */ PerlIO *rsfp; /* current source file pointer */ AV *rsfp_filters; /* holds chain of active source filters */ diff --git a/t/base/lex.t b/t/base/lex.t index de33e7a688..414aa1fceb 100644 --- a/t/base/lex.t +++ b/t/base/lex.t @@ -1,6 +1,6 @@ #!./perl -print "1..117\n"; +print "1..120\n"; $x = 'x'; @@ -557,6 +557,15 @@ eval q|s##[}#e|; eval ('/@0{0*->@*/*]'); print "ok $test - 128171\n"; $test++; } +{ + # various sub-parse recovery issues that crashed perl + eval 's//${sub{b{]]]{}#$/ sub{}'; + print "ok $test - 132640\n"; $test++; + eval 'qq{@{sub{]]}}}};shift'; + print "ok $test - 125351\n"; $test++; + eval 'qq{@{sub{]]}}}}-shift'; + print "ok $test - 126192\n"; $test++; +} $foo = "WRONG"; $foo:: = "bar"; $bar = "baz"; print "not " unless "$foo::$bar" eq "barbaz"; diff --git a/toke.c b/toke.c index 5959bc3e9e..3dcc7e9f86 100644 --- a/toke.c +++ b/toke.c @@ -2390,6 +2390,8 @@ S_sublex_start(pTHX) PL_parser->lex_super_state = PL_lex_state; PL_parser->lex_sub_inwhat = (U16)op_type; PL_parser->lex_sub_op = PL_lex_op; + PL_parser->sub_no_recover = FALSE; + PL_parser->sub_error_count = PL_error_count; PL_lex_state = LEX_INTERPPUSH; PL_expect = XTERM; @@ -2569,6 +2571,20 @@ S_sublex_done(pTHX) else { const line_t l = CopLINE(PL_curcop); LEAVE; + if (PL_parser->sub_error_count != PL_error_count) { + const char * const name = OutCopFILE(PL_curcop); + if (PL_parser->sub_no_recover) { + const char * msg = ""; + if (PL_in_eval) { + SV *errsv = ERRSV; + if (SvCUR(ERRSV)) { + msg = Perl_form(aTHX_ "%" SVf, SVfARG(errsv)); + } + } + abort_execution(msg, name); + NOT_REACHED; + } + } if (PL_multi_close == '<') PL_parser->herelines += l - PL_multi_end; PL_bufend = SvPVX(PL_linestr); @@ -4157,6 +4173,7 @@ S_intuit_more(pTHX_ char *s, char *e) return TRUE; if (*s != '{' && *s != '[') return FALSE; + PL_parser->sub_no_recover = TRUE; if (!PL_lex_inpat) return TRUE; @@ -9580,6 +9597,7 @@ S_scan_ident(pTHX_ char *s, char *dest, STRLEN destlen, I32 ck_uni) CopLINE_set(PL_curcop, orig_copline); PL_parser->herelines = herelines; *dest = '\0'; + PL_parser->sub_no_recover = TRUE; } } else if ( PL_lex_state == LEX_INTERPNORMAL -- 2.11.0


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org