Open p5pRT opened 5 years ago
./perl -e 'for$0(qw(0 0)){push@r\,qr/@r(?{})/}' triggers a null pointer dereference and segfault in v5.29.0-87-ga13f1de.
==10676==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x0000007060c8 bp 0x7fffb4efe100 sp 0x7fffb4efe0e0 T0) ==10676==The signal is caused by a READ memory access. ==10676==Hint: address points to the zero page. #0 0x7060c7 in S_SvREFCNT_dec /root/perl/./inline.h:212:11 #1 0x7305f0 in S_free_codeblocks /root/perl/regcomp.c:6268:9 #2 0x9b59ca in Perl_leave_scope /root/perl/scope.c #3 0x9df198 in Perl_dounwind /root/perl/pp_ctl.c:1549:9 #4 0x5b5846 in S_my_exit_jump /root/perl/perl.c:5240:9 #5 0x5c092e in Perl_my_failure_exit /root/perl/perl.c:5227:5 #6 0x9e1d2f in Perl_die_unwind /root/perl/pp_ctl.c:1796:5 #7 0x7ce081 in Perl_vcroak /root/perl/util.c:1715:5 #8 0x7c6b5b in Perl_croak /root/perl/util.c:1760:5 #9 0x70362b in S_reg /root/perl/regcomp.c #10 0x77618a in S_regatom /root/perl/regcomp.c:12960:15 #11 0x77232c in S_regpiece /root/perl/regcomp.c:12004:11 #12 0x762ea2 in S_regbranch /root/perl/regcomp.c:11932:18 #13 0x6f451c in S_reg /root/perl/regcomp.c:11663:10 #14 0x77618a in S_regatom /root/perl/regcomp.c:12960:15 #15 0x77232c in S_regpiece /root/perl/regcomp.c:12004:11 #16 0x762ea2 in S_regbranch /root/perl/regcomp.c:11932:18 #17 0x6f451c in S_reg /root/perl/regcomp.c:11663:10 #18 0x6dc4ba in Perl_re_op_compile /root/perl/regcomp.c:7224:9 #19 0x9c4274 in Perl_pp_regcomp /root/perl/pp_ctl.c:108:14 #20 0x7c17d8 in Perl_runops_debug /root/perl/dump.c:2536:23 #21 0x5b0831 in S_run_body /root/perl/perl.c #22 0x5afe7b in perl_run /root/perl/perl.c:2617:2 #23 0x50da47 in main /root/perl/perlmain.c:122:9 #24 0x7f39127c182f in __libc_start_main /build/glibc-Cl5G7W/glibc-2.23/csu/../csu/libc-start.c:291 #25 0x436d28 in _start (/root/perl/perl+0x436d28)
AddressSanitizer can not provide additional info. SUMMARY: AddressSanitizer: SEGV /root/perl/./inline.h:212:11 in S_SvREFCNT_dec ==10676==ABORTING
This is still present in v39.10
==62279==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x55e6f775dee0 bp 0x7fffab24da10 sp 0x7fffab24d9d0 T0) ==62279==The signal is caused by a READ memory access. ==62279==Hint: this fault was caused by a dereference of a high value address (see register values below). Disassemble the provided pc to learn which register was used.
0 0x55e6f775dee0 in Perl_SvREFCNT_dec_NN /home/khw/perl/locales/straight/./sv_inline.h:710:14
1 0x55e6f7777ae2 in S_free_codeblocks /home/khw/perl/locales/straight/regcomp.c:498:13
2 0x55e6f7a3c0cc in Perl_leave_scope /home/khw/perl/locales/straight/scope.c:1537:13
3 0x55e6f74bcbb5 in Perl_dounwind /home/khw/perl/locales/straight/pp_ctl.c:1775:9
4 0x55e6f707e980 in S_my_exit_jump /home/khw/perl/locales/straight/perl.c:5519:9
5 0x55e6f7093ca7 in Perl_my_failure_exit /home/khw/perl/locales/straight/perl.c:5506:5
6 0x55e6f74c3996 in Perl_die_unwind /home/khw/perl/locales/straight/pp_ctl.c:2092:5
7 0x55e6f7d7f9e6 in Perl_vcroak /home/khw/perl/locales/straight/util.c:1897:5
8 0x55e6f7d8077d in Perl_croak /home/khw/perl/locales/straight/util.c:1948:5
9 0x55e6f77446a4 in S_reg /home/khw/perl/locales/straight/regcomp.c:3797:21
10 0x55e6f77c2880 in S_regatom /home/khw/perl/locales/straight/regcomp.c:5609:15
11 0x55e6f77b55ae in S_regpiece /home/khw/perl/locales/straight/regcomp.c:4745:11
12 0x55e6f778d187 in S_regbranch /home/khw/perl/locales/straight/regcomp.c:4510:18
13 0x55e6f7755896 in S_reg /home/khw/perl/locales/straight/regcomp.c:4182:10
14 0x55e6f77c2880 in S_regatom /home/khw/perl/locales/straight/regcomp.c:5609:15
15 0x55e6f77b55ae in S_regpiece /home/khw/perl/locales/straight/regcomp.c:4745:11
16 0x55e6f778d187 in S_regbranch /home/khw/perl/locales/straight/regcomp.c:4510:18
17 0x55e6f7755896 in S_reg /home/khw/perl/locales/straight/regcomp.c:4182:10
18 0x55e6f76fb3be in Perl_re_op_compile /home/khw/perl/locales/straight/regcomp.c:1714:9
19 0x55e6f7494e3f in Perl_pp_regcomp /home/khw/perl/locales/straight/pp_ctl.c:119:14
20 0x55e6f7155438 in Perl_runops_debug /home/khw/perl/locales/straight/dump.c:2866:23
21 0x55e6f7074fa2 in S_run_body /home/khw/perl/locales/straight/perl.c:2889:9
22 0x55e6f707219d in perl_run /home/khw/perl/locales/straight/perl.c:2804:9
23 0x55e6f6f58cf4 in main /home/khw/perl/locales/straight/perlmain.c:127:9
24 0x7fad5cf0dd8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
25 0x7fad5cf0de3f in __libc_start_main csu/../csu/libc-start.c:392:3
26 0x55e6f6e9ad24 in _start (/home/khw/perl/locales/straight/perl+0x28fd24) (BuildId: 0cb917dd7204b49daa8373c79aba4404dbac8aea)
I don't get a null pointer dereference, but I'm not using ASan either.
$ ./perl -Ilib -Mre=eval -e 'for$0(qw(0 0)){push@r,qr/@r(?{})/}'
Segmentation fault
$ gdb --args ./perl -Ilib -Mre=eval -e 'for$0(qw(0 0)){push@r,qr/@r(?{})/}'
...
(gdb) r
Starting program: /home/mauke/Projects/perl5/perl -Ilib -Mre=eval -e for\$0\(qw\(0\ 0\)\)\{push@r,qr/@r\(\?\{\}\)/\}
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
S_compile_runtime_code (plen=<optimized out>, pat=0x555555a520f0 "(?^:(?{}))(?{})", pRExC_state=0x7fffffffd280) at regcomp.c:1053
1053 assert(pat[src->start] == '(');
(gdb) bt
#0 S_compile_runtime_code (plen=<optimized out>, pat=0x555555a520f0 "(?^:(?{}))(?{})", pRExC_state=0x7fffffffd280) at regcomp.c:1053
#1 Perl_re_op_compile (patternp=<optimized out>, pat_count=<optimized out>, expr=<optimized out>, eng=0x555555a235c0 <PL_core_reg_engine>, old_re=0x555555a2f678, is_bare_re=<optimized out>, orig_rx_flags=0, pm_flags=2013265920)
at regcomp.c:1602
#2 0x000055555568c1e0 in Perl_pp_regcomp () at pp_ctl.c:121
#3 0x00005555555f0252 in Perl_runops_debug () at dump.c:2866
#4 0x00005555555d5ed0 in S_run_body (oldscope=1) at perl.c:2865
#5 perl_run (my_perl=<optimized out>) at perl.c:2780
#6 0x000055555559e19c in main (argc=<optimized out>, argv=<optimized out>, env=<optimized out>) at perlmain.c:127
(gdb) p src
$1 = (struct reg_code_block *) 0x555555a63350
(gdb) p src->start
$2 = 2314885530818453536
(gdb)
Slightly reduced:
perl -e 'use re "eval"; my @x = qr/(?{})/; push @x, qr/(?{})@x/'
This segfaults about 50% of the time for me.
Slightly reduced:
perl -e 'use re "eval"; my @x = qr/(?{})/; push @x, qr/(?{})@x/'
This segfaults about 50% of the time for me.
... which is what I also get on Ubuntu Linux 22.04 LTS. But on FreeBSD-13, I don't get any message or segfault.
$ perl -e 'use re "eval"; my @x = qr/(?{})/; push @x, qr/(?{})@x/'
$ perl -e 'use re "eval"; my @x = qr/(?{})/; push @x, qr/(?{})@x/'
$ perl -e 'use re "eval"; my @x = qr/(?{})/; push @x, qr/(?{})@x/'
$ perl -e 'use re "eval"; my @x = qr/(?{})/; push @x, qr/(?{})@x/'
$ perl -e 'use re "eval"; my @x = qr/(?{})/; push @x, qr/(?{})@x/'
$ perl -e 'use re "eval"; my @x = qr/(?{})/; push @x, qr/(?{})@x/'
$ perl -e 'use re "eval"; my @x = qr/(?{})/; push @x, qr/(?{})@x/'
$ perl -e 'use re "eval"; my @x = qr/(?{})/; push @x, qr/(?{})@x/'
$ perl -e 'use re "eval"; my @x = qr/(?{})/; push @x, qr/(?{})@x/'
$ perl -e 'use re "eval"; my @x = qr/(?{})/; push @x, qr/(?{})@x/'
I have a patch that seems to fix this issue: https://github.com/mauke/perl5/commit/039cadf286fae4962564c355239af1f20fc4d8a3
However, this patch was written based on vibes, not any deep understanding of the code. I'd appreciate any review of what's going on here. @iabyn ?
I have a very similar patch in development (passing address of n as a pointer), but there are some subtleties you've missed (notably at line 734, *pn shouldn't be reset to zero). I wasn't entirely happy with my branch, so I was going to leave it until tomorrow to see if there was a more elegant fix. Probably best to leave this one to me - it was my mistake in the first place.
I've now created PR #22201, which has a more general fix to this issue.
Migrated from rt.perl.org#133369 (status was 'new')
Searchable as RT133369$