Skip Menu |
Report information
Id: 124099
Status: resolved
Priority: 0/
Queue: perl5

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

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



Subject: null ptr deref -> Perl_find_lexical_cv () at op.c:11235
Download (untitled) / with headers
text/plain 6.6k
Built v5.21.10 (v5.21.9-259-g88d9f32) with the following command line: ./Configure -des -Dusedevel -DDEBUGGING -Dcc=afl-gcc -Doptimize=-O2\ -g && AFL_HARDEN=1 make -j12 test-prep Bug found with AFL (http://lcamtuf.coredump.cx/afl) Valgrind: Array found where operator expected at test271-min line 1, at end of line (Missing operator before ?) ==3428== Invalid read of size 8 ==3428== at 0x455678: Perl_find_lexical_cv (op.c:11238) ==3428== by 0x64B706: Perl_yylex (toke.c:6503) ==3428== by 0x65ACF4: Perl_yyparse (perly.c:322) ==3428== by 0x534490: perl_parse (perl.c:2289) ==3428== by 0x42AED7: main (perlmain.c:114) ==3428== Address 0x5edfea0 is 0 bytes after a block of size 16 alloc'd ==3428== at 0x4C28CCE: realloc (vg_replace_malloc.c:632) ==3428== by 0x7E0A18: Perl_safesysrealloc (util.c:270) ==3428== by 0x8A500E: Perl_av_extend_guts (av.c:159) ==3428== by 0x67EEC4: S_pad_alloc_name (pad.c:2684) ==3428== by 0x684644: S_pad_findlex (pad.c:1331) ==3428== by 0x684499: S_pad_findlex (pad.c:1308) ==3428== by 0x68696A: Perl_pad_findmy_pvn (pad.c:962) ==3428== by 0x5F7A3C: Perl_yylex (toke.c:6481) ==3428== by 0x65ACF4: Perl_yyparse (perly.c:322) ==3428== by 0x534490: perl_parse (perl.c:2289) ==3428== by 0x42AED7: main (perlmain.c:114) ==3428== ==3428== Invalid read of size 1 ==3428== at 0x455684: Perl_find_lexical_cv (op.c:11235) ==3428== by 0x64B706: Perl_yylex (toke.c:6503) ==3428== by 0x65ACF4: Perl_yyparse (perly.c:322) ==3428== by 0x534490: perl_parse (perl.c:2289) ==3428== by 0x42AED7: main (perlmain.c:114) ==3428== Address 0x29 is not stack'd, malloc'd or (recently) free'd ==3428== ==3428== ==3428== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==3428== Access not within mapped region at address 0x29 ==3428== at 0x455684: Perl_find_lexical_cv (op.c:11235) ==3428== by 0x64B706: Perl_yylex (toke.c:6503) ==3428== by 0x65ACF4: Perl_yyparse (perly.c:322) ==3428== by 0x534490: perl_parse (perl.c:2289) ==3428== by 0x42AED7: main (perlmain.c:114) ==3428== If you believe this happened as a result of a stack ==3428== overflow in your program's main thread (unlikely but ==3428== possible), you can try to increase the size of the ==3428== main thread stack using the --main-stacksize= flag. ==3428== The main thread stack size used in this run was 8388608. Segmentation fault GDB: gdb-peda$ file ~/perl/perl gdb-peda$ set args test271-min gdb-peda$ r [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Array found where operator expected at test271-min line 1, at end of line (Missing operator before ?) Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] RAX: 0x0 RBX: 0x11edc49 --> 0x0 RCX: 0x10 RDX: 0x1 RSI: 0x11f0160 --> 0x11c9f60 --> 0x0 RDI: 0x11e20b8 --> 0x11e0660 --> 0x0 RBP: 0x11d2590 --> 0x11edf5a --> 0x6826 ('&h') RSP: 0x7fffffffd960 --> 0x0 RIP: 0x455684 (<Perl_find_lexical_cv+484>: movzx edx,BYTE PTR [rax+0x29]) R8 : 0x2 R9 : 0x11f00e0 --> 0x1 R10: 0x11f0180 --> 0x11f0130 --> 0x1 R11: 0x11f0130 --> 0x1 R12: 0x0 R13: 0x0 R14: 0x11d27a0 (0x00000000011d27a0) R15: 0x1 EFLAGS: 0x10202 (carry parity adjust zero sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x455670 <Perl_find_lexical_cv+464>: lea rsp,[rsp+0x98] 0x455678 <Perl_find_lexical_cv+472>: mov rax,QWORD PTR [rsi+r8*8] 0x45567c <Perl_find_lexical_cv+476>: lea rcx,[r8*8+0x0] => 0x455684 <Perl_find_lexical_cv+484>: movzx edx,BYTE PTR [rax+0x29] 0x455688 <Perl_find_lexical_cv+488>: test dl,0x1 0x45568b <Perl_find_lexical_cv+491>: jne 0x4555f8 <Perl_find_lexical_cv+344> 0x455691 <Perl_find_lexical_cv+497>: nop DWORD PTR [rax] 0x455694 <Perl_find_lexical_cv+500>: lea rsp,[rsp-0x98] [------------------------------------stack-------------------------------------] 0000| 0x7fffffffd960 --> 0x0 0008| 0x7fffffffd968 --> 0xe1075289aa3ceb00 0016| 0x7fffffffd970 --> 0x0 0024| 0x7fffffffd978 --> 0x64b707 (<Perl_yylex+487543>: mov BYTE PTR [rsp+0x40],0x1) 0032| 0x7fffffffd980 --> 0x7ffff7dea1e0 (push rbx) 0040| 0x7fffffffd988 --> 0x11ea1f8 --> 0x620068 (<Perl_yylex+309720>: and al,0x10) 0048| 0x7fffffffd990 --> 0x7fffffffe100 --> 0x3877552a ('*Uw8') 0056| 0x7fffffffd998 --> 0x1 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV Perl_find_lexical_cv () at op.c:11235 11235 while (PadnameOUTER(name)) { gdb-peda$ bt #0 Perl_find_lexical_cv () at op.c:11235 #1 0x000000000064b707 in Perl_yylex () at toke.c:6503 #2 0x000000000065acf5 in Perl_yyparse () #3 0x0000000000534491 in perl_parse () #4 0x000000000042aed8 in main () at perlmain.c:114 #5 0x00007ffff6d7cead 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=0x7fffffffe388) at libc-start.c:244 #6 0x000000000042b1dd in _start () gdb-peda$ i r rax 0x0 0x0 rbx 0x11edc49 0x11edc49 rcx 0x10 0x10 rdx 0x1 0x1 rsi 0x11f0160 0x11f0160 rdi 0x11e20b8 0x11e20b8 rbp 0x11d2590 0x11d2590 rsp 0x7fffffffd960 0x7fffffffd960 r8 0x2 0x2 r9 0x11f00e0 0x11f00e0 r10 0x11f0180 0x11f0180 r11 0x11f0130 0x11f0130 r12 0x0 0x0 r13 0x0 0x0 r14 0x11d27a0 0x11d27a0 r15 0x1 0x1 rip 0x455684 0x455684 <Perl_find_lexical_cv+484> eflags 0x10202 [ IF RF ] cs 0x33 0x33 ss 0x2b 0x2b ds 0x0 0x0 es 0x0 0x0 fs 0x0 0x0 gs 0x0 0x0 gdb-peda$ exploitable Description: Access violation near NULL on source operand Short description: SourceAvNearNull (16/22) Hash: 2cd9775ce7faae9f56a2d26643b1d670.2cd9775ce7faae9f56a2d26643b1d670 Exploitability Classification: PROBABLY_NOT_EXPLOITABLE Explanation: The target crashed on an access violation at an address matching the source operand of the current instruction. This likely indicates a read access violation, which may mean the application crashed on a simple NULL dereference to data structure that has no immediate effect on control of the processor. Other tags: AccessViolation (21/22) Hexdump of the 25-byte test case: 0000000 7b30 796d 6d40 757b 2663 4068 3b30 3b30 0000010 7573 7b62 7573 7b62 0068 0000019 System Info: Debian 7, Kernel 3.2.65-1+deb7u1 x86_64, GCC 4.9.2, libc 2.13-38+deb7u8
Subject: test271-min
Download test271-min
application/octet-stream 25b

Message body not shown because it is not plain text.

RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 2.2k
I think the pad-related debug may be significant: % ./miniperl -DXv -ce '0{my@m{uc&h@0;0;sub{sub{h' Pad 0x1c762f8[0x1c84d40] new: compcv=0x1c762e0 name=0x1c84d70 flags=0x0 Pad findlex cv=0x1c762e0 searching "&my" seq=-50 Pad 0x1c762f8[0x1c84d40] alloc: 1 for padsv Pad addname: 1 "%m" new lex=0x1c97288 Pad findlex cv=0x1c762e0 searching "&uc" seq=-50 Pad 0x1c762f8[0x1c84d40] alloc: 2 for padsv Pad addname: 2 "&h" new lex=0x1c972d0 Array found where operator expected at -e line 1, at end of line (Missing operator before ?) Pad findlex cv=0x1c762e0 searching "@0" seq=-50 Pad intromy: 1 "%m", (4294967246,4294967295) Pad intromy: 2 "&h", (4294967246,4294967295) Pad intromy: seq -> 4294967247 Pad findlex cv=0x1c762e0 searching "&sub" seq=-49 Pad 0x1c973d8[0x1c98860] new: compcv=0x1c973c0 name=0x1c98910 flags=0x6 Pad findlex cv=0x1c973c0 searching "&sub" seq=-48 Pad findlex cv=0x1c762e0 searching "&sub" seq=-49 Pad 0x1c97420[0x1c98ab0] new: compcv=0x1c97408 name=0x1c98ae0 flags=0x6 Pad findlex cv=0x1c97408 searching "&h" seq=-47 Pad findlex cv=0x1c973c0 searching "&h" seq=-48 Pad findlex cv=0x1c762e0 searching "&h" seq=-49 Pad findlex cv=0x1c762e0 matched: offset=2 (4294967246,4294967295) Pad 0x1c973d8[0x1c98860] alloc: 1 for padsv Pad addname: 1 "&h" FAKE Pad 0x1c97420[0x1c98ab0] alloc: 1 for padsv Pad addname: 1 "&h" FAKE Segmentation fault (core dumped) % I'm not sure what any of that means, but it seems odd that we addname "&h" at line 7 of the output, and odder that we haven't attempted a findlex first; this appears to be because PL_in_my remains true when we reach S_pending_ident(PL_tokenbuf="&h") inside the braces of '0{my@m{&h' whereas it is false at the same point without the leading '0'. (We also seem rather inconsistent about size and sign of seq in the debug output, not sure if there's any good reason for that.) Bisect points to: commit f815dc14d7c5540dfb5d02d001e0101c6266f281 Author: Father Chrysostomos <sprout@cpan.org> Date: Sun Jun 30 00:20:33 2013 -0700 Inline list constants These are inlined the same way as 1..5. We have two ops: rv2av | `-- const The const op returns an AV, which is stored in the op tree, and then rv2av flattens it. .. which is maybe somehow interacting with the lexical sub support. Hugo
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 1.4k
On Sat Mar 21 04:35:54 2015, hv wrote: Show quoted text
> I'm not sure what any of that means, but it seems odd that we addname > "&h" at line 7 of the output,
my &h will cause &h to be added to the pad, but it also generates a syntax error. When there are syntax errors, the lexer sometimes gets confused as to what a ‘my’ is meant to apply to. Extra pad entries like an empty &h shouldn’t cause any problems, but it seems the pads are getting corrupted somehow. Show quoted text
> and odder that we haven't attempted a > findlex first; this appears to be because PL_in_my remains true when > we reach S_pending_ident(PL_tokenbuf="&h") inside the braces of > '0{my@m{&h' whereas it is false at the same point without the leading > '0'.
That’s what I was referring to about lexer confusion above. As long as it works correctly in the absence of syntax errors, that should suffice. Show quoted text
> > (We also seem rather inconsistent about size and sign of seq in the > debug output, not sure if there's any good reason for that.) > > Bisect points to: > > commit f815dc14d7c5540dfb5d02d001e0101c6266f281 > Author: Father Chrysostomos <sprout@cpan.org> > Date: Sun Jun 30 00:20:33 2013 -0700 > > Inline list constants > > These are inlined the same way as 1..5. We have two ops: > > rv2av > | > `-- const > > The const op returns an AV, which is stored in the op tree, and then > rv2av flattens it. > > .. which is maybe somehow interacting with the lexical sub support.
I think that’s a red herring. -- Father Chrysostomos
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 492b
perl -e 'm0{0\my}sub H;0;sub{sub{H' points to a slightly different line in op.c: Perl_find_lexical_cv () at op.c:11239 11239 while (PadnameOUTER(name)) { gdb-peda$ list 11234 CV * 11235 Perl_find_lexical_cv(pTHX_ PADOFFSET off) 11236 { 11237 PADNAME *name = PAD_COMPNAME(off); 11238 CV *compcv = PL_compcv; 11239 while (PadnameOUTER(name)) { 11240 assert(PARENT_PAD_INDEX(name)); 11241 compcv = CvOUTSIDE(PL_compcv); 11242 name = PadlistNAMESARRAY(CvPADLIST(compcv)) 11243
Download (untitled) / with headers
text/plain 1.3k
~/perl/miniperl -DXv -ce 'm0{0\my}sub H;0;sub{sub{H' Pad 0x1a162f8[0x1a25f10] new: compcv=0x1a162e0 name=0x1a25f40 flags=0x0 Pad findlex cv=0x1a162e0 searching "&m0" seq=-50 Backslash found where operator expected at -e line 1, near "0\" (Missing operator before \?) Pad findlex cv=0x1a162e0 searching "&my" seq=-49 Pad leavemy: seq = 4294967248 Pad findlex cv=0x1a162e0 searching "&sub" seq=-48 Pad findlex cv=0x1a162e0 searching "&H" seq=-48 Pad 0x1a162f8[0x1a25f10] alloc: 1 for entersub Pad 0x1a162f8[0x1a25f10] free: 1 Pad 0x1a162f8[0x1a25f10] alloc: 2 for padsv Pad addname: 2 "&H" new lex=0x1a2d020 Pad intromy: 2 "&H", (4294967248,4294967295) Pad intromy: seq -> 4294967249 Pad findlex cv=0x1a162e0 searching "&sub" seq=-47 Pad 0x1a2d128[0x1a36ef0] new: compcv=0x1a2d110 name=0x1a36f20 flags=0x6 Pad findlex cv=0x1a2d110 searching "&sub" seq=-46 Pad findlex cv=0x1a162e0 searching "&sub" seq=-47 Pad 0x1a2d170[0x1a370c0] new: compcv=0x1a2d158 name=0x1a370f0 flags=0x6 Pad findlex cv=0x1a2d158 searching "&H" seq=-45 Pad findlex cv=0x1a2d110 searching "&H" seq=-46 Pad findlex cv=0x1a162e0 searching "&H" seq=-47 Pad findlex cv=0x1a162e0 matched: offset=2 (4294967248,4294967295) Pad 0x1a2d128[0x1a36ef0] alloc: 1 for padsv Pad addname: 1 "&H" FAKE Pad 0x1a2d170[0x1a370c0] alloc: 1 for padsv Pad addname: 1 "&H" FAKE Segmentation fault
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 200b
This variation loops: ./miniperl -e '0{my&h@0;0;sub{sub{h' I think this line in find_lexical_cv is wrong: compcv = CvOUTSIDE(PL_compcv); It should be CvOUTSIDE(compcv). -- Father Chrysostomos
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 669b
On Fri Mar 27 09:35:52 2015, sprout wrote: Show quoted text
> This variation loops: > > ./miniperl -e '0{my&h@0;0;sub{sub{h' > > I think this line in find_lexical_cv is wrong: > > compcv = CvOUTSIDE(PL_compcv); > > It should be CvOUTSIDE(compcv).
It has nothing to do with syntax errors. This example demonstrates the problem more clearly (to me, at least): $ ./perl -Ilib -Mfeature=:all -e 'my sub h; sub{my $x; sub{h}}' The lexical_subs feature is experimental at -e line 1. Assertion failed: (SvTYPE(cv) == SVt_PVCV || SvTYPE(cv) == SVt_PVFM), function Perl_cv_const_sv_or_av, file op.c, line 7933. Abort trap: 6 I have now fixed it in d655d9a2c4. -- Father Chrysostomos
Download (untitled) / with headers
text/plain 200b
Thank you for submitting this ticket. The issue should now be resolved with the release today of Perl v5.22, which is available at http://www.perl.org/get.html -- Karl Williamson for the Perl 5 team


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