Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

31 byte one liner crashes Perl5.21.9 #14447

Closed
p5pRT opened this issue Jan 26, 2015 · 18 comments
Closed

31 byte one liner crashes Perl5.21.9 #14447

p5pRT opened this issue Jan 26, 2015 · 18 comments

Comments

@p5pRT
Copy link

p5pRT commented Jan 26, 2015

Migrated from rt.perl.org#123677 (status was 'resolved')

Searchable as RT123677$

@p5pRT
Copy link
Author

p5pRT commented Jan 26, 2015

From @geeknik

Good morning. The fuzzing attack against Perl continues with an interesting
(at least to me) test case. I built Perl 5.21.9 from Git source this
morning.

/home/geeknik/perl5/perl -v
This is perl 5, version 21, subversion 9 (v5.21.9 (v5.21.8-57-gd28cce6))
built for x86_64-linux

Using the american fuzzy lop (http​://http​://lcamtuf.coredump.cx/afl/)
compiler in this fashion, I built the executable​:

CC=/path/to/afl-gcc ./Configure (defaulted through all of the options)
ran make without using AFL_HARDEN=1

Test case and core dump are attached.

valgrind -q /home/geeknik/perl5/perl final-crasher4
Bareword found where operator expected at final-crasher4 line 1, near "0h"
(Missing operator before h?)
==37418== Invalid read of size 2
==37418== at 0x464C79​: Perl_newSVREF (op.c​:9387)
==37418== by 0x5BA3F7​: Perl_yyparse (perly.y​:1109)
==37418== by 0x4E6494​: perl_parse (perl.c​:2273)
==37418== by 0x429BBB​: main (perlmain.c​:114)
==37418== Address 0x10805edc128 is not stack'd, malloc'd or (recently)
free'd
==37418==
==37418==
==37418== Process terminating with default action of signal 11 (SIGSEGV)​:
dumping core
==37418== Access not within mapped region at address 0x10805EDC128
==37418== at 0x464C79​: Perl_newSVREF (op.c​:9387)
==37418== by 0x5BA3F7​: Perl_yyparse (perly.y​:1109)
==37418== by 0x4E6494​: perl_parse (perl.c​:2273)
==37418== by 0x429BBB​: main (perlmain.c​:114)
==37418== If you believe this happened as a result of a stack
==37418== overflow in your program's main thread (unlikely but
==37418== possible), you can try to increase the size of the
==37418== main thread stack using the --main-stacksize= flag.
==37418== The main thread stack size used in this run was 8388608.
Segmentation fault

gdb /home/geeknik/perl5/perl core
Reading symbols from /home/geeknik/perl5/perl...done.
[New LWP 45131]

warning​: Can't read pathname for load map​: Input/output error.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `/home/geeknik/perl5/perl final-crasher4'.
Program terminated with signal 11, Segmentation fault.
#0 Perl_newSVREF (o=0x10800e043b8) at op.c​:9387
9387 if (o->op_type == OP_PADANY) {
(gdb) bt
#0 Perl_newSVREF (o=0x10800e043b8) at op.c​:9387
#1 0x00000000005ba3f8 in Perl_yyparse (gramtype=<optimized out>) at
perly.y​:1109
#2 0x00000000004e6495 in S_parse_body (xsinit=0x429fb0 <xs_init>, env=0x0)
at perl.c​:2273
#3 perl_parse (my_perl=<optimized out>, xsinit=0x429fb0 <xs_init>,
argc=<optimized out>, argv=<optimized out>, env=0x0) at perl.c​:1607
#4 0x0000000000429bbc in main (argc=2, argv=0x7fffffffe3c8,
env=0x7fffffffe3e0) at perlmain.c​:114
#5 0x00007ffff6f97ead 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=0x7fffffffe3b8) at libc-start.c​:244
#6 0x0000000000429ed5 in _start ()
(gdb) i r
rax 0xc8 200
rbx 0xe00f80 14684032
rcx 0x2 2
rdx 0xc7 199
rsi 0xffffffffffffffff -1
rdi 0x10800e043b8 1133886063544
rbp 0xaaaaaaaaaaaaaaab 0xaaaaaaaaaaaaaaab
rsp 0x7fffffffdfb0 0x7fffffffdfb0
r8 0x200002800000024 144115359874547748
r9 0xffffffffffffffff -1
r10 0xfffffffffffffffd -3
r11 0xee 238
r12 0xee 238
r13 0x1 1
r14 0xe00b10 14682896
r15 0x70 112
rip 0x464c79 0x464c79 <Perl_newSVREF+1>
eflags 0x10283 [ CF SF IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb)

Test case​:
s)$0{0h());qx(@​0);qx(@​0);qx(@​0)

hexdump​:
0000000 2973 3024 307b 2868 2929 713b 2878 3040
0000010 3b29 7871 4028 2930 713b 2878 3040 0029
000001f

@p5pRT
Copy link
Author

p5pRT commented Jan 26, 2015

From @geeknik

onelinecrash.tar.gz

@p5pRT
Copy link
Author

p5pRT commented Jan 26, 2015

From @geeknik

A slightly different test case (30 bytes) provides a vastly different gdb
and valgrind output. Not sure if related or needs a new bug​:

perl -e 's)$0{0h());qx(@​0);qx(@​0);qx[-]'
Bareword found where operator expected at -e line 1, near "0h"
(Missing operator before h?)
syntax error at -e line 1, near "0h"
syntax error at -e line 1, next char ^E
syntax error at -e line 1, next char \225
syntax error at -e line 1, at EOF
Execution of -e aborted due to compilation errors.
Segmentation fault (core dumped)

(Core was generated by `perl -e s)$0{0h());qx(@​0);qx(@​0);qx[-]'.
Program terminated with signal 11, Segmentation fault.
#0 0x00000000004f5b53 in S_gv_magicalize_isa (gv=0xe34e30) at gv.c​:1532
1532 av = GvAVn(gv);
(gdb) bt
#0 0x00000000004f5b53 in S_gv_magicalize_isa (gv=0xe34e30) at gv.c​:1532
#1 S_gv_magicalize (sv_type=14959792, addmg=7, len=<optimized out>,
  name=0xe3ae90 "\200\316", <incomplete sequence \343>, stash=0x0,
  gv=0xe34e30) at gv.c​:1825
#2 Perl_gv_fetchpvn_flags (nambeg=0x4fb3a5 "D", full_len=<optimized out>,
  flags=<optimized out>, sv_type=14959792) at gv.c​:2348
#3 0x0000000000e3a638 in ?? ()
#4 0x0000000000000004 in ?? ()
#5 0x0000000000e3ae90 in ?? ()
#6 0x0000000000e3a638 in ?? ()
#7 0x0000000000509129 in S_gv_fetchmeth_internal (flags=0, level=-1,
  len=11079778, name=0x7ffff70aa9bc <Address 0x7ffff70aa9bc out of
bounds>,
  meth=0x0, stash=0x7e76e2) at gv.c​:793
#8 Perl_gv_fetchmeth_pvn (flags=0, level=-1,
  len=<error reading variable​: Cannot access memory at address
0x9019df631>,
  name=<error reading variable​: Cannot access memory at address
0x4807db35a8>, stash=0x7e76e2) at gv.c​:862
#9 Perl_Gv_AMupdate (stash=0x7e76e2, destructing=false) at gv.c​:2695
#10 0xdbb97c8a9c1ee400 in ?? ()
#11 0x0000000000000000 in ?? ()
(gdb) i r
rax 0x0 0
rbx 0xe34e30 14896688
rcx 0x0 0
rdx 0xe44378 14959480
rsi 0xe44418 14959640
rdi 0x0 0
rbp 0xe3ae90 0xe3ae90
rsp 0x7fffffffda80 0x7fffffffda80
r8 0x58 88
r9 0x101010101010101 72340172838076673
r10 0x0 0
r11 0x7ffff6ffc532 140737337345330
r12 0x2 2
r13 0x0 0
r14 0xe3ae90 14921360
r15 0x7 7
rip 0x4f5b53 0x4f5b53 <Perl_gv_fetchpvn_flags+9115>
eflags 0x10206 [ PF IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0

Bareword found where operator expected at -e line 1, near "0h"
(Missing operator before h?)
syntax error at -e line 1, near "0h"
syntax error at -e line 1, next char ^E
syntax error at -e line 1, next char \225
syntax error at -e line 1, at EOF
Execution of -e aborted due to compilation errors.
==19553== Invalid read of size 8
==19553== at 0x4F5B53​: Perl_newGP (gv.c​:194)
==19553== by 0x4FB3A4​: Perl_gv_init_pvn (gv.c​:412)
==19553== by 0x509128​: S_gv_fetchmeth_internal (gv.c​:755)
==19553== by 0x50DA1B​: Perl_gv_fetchmeth_pvn_autoload (gv.c​:862)
==19553== by 0x7B3056​: S_curse (sv.c​:6832)
==19553== by 0x7B9046​: Perl_sv_clear (sv.c​:6499)
==19553== by 0x7B1117​: Perl_sv_free2 (sv.c​:6972)
==19553== by 0x525DF4​: Perl_parser_free (inline.h​:166)
==19553== by 0x8B8ECF​: Perl_leave_scope (scope.c​:1250)
==19553== by 0x4CF966​: S_my_exit_jump (perl.c​:5013)
==19553== by 0x4F4434​: Perl_my_failure_exit (perl.c​:5000)
==19553== by 0x903344​: Perl_die_unwind (pp_ctl.c​:1684)
==19553== Address 0x20 is not stack'd, malloc'd or (recently) free'd
==19553==
==19553==
==19553== Process terminating with default action of signal 11 (SIGSEGV)​:
dumping core
==19553== Access not within mapped region at address 0x20
==19553== at 0x4F5B53​: Perl_newGP (gv.c​:194)
==19553== by 0x4FB3A4​: Perl_gv_init_pvn (gv.c​:412)
==19553== by 0x509128​: S_gv_fetchmeth_internal (gv.c​:755)
==19553== by 0x50DA1B​: Perl_gv_fetchmeth_pvn_autoload (gv.c​:862)
==19553== by 0x7B3056​: S_curse (sv.c​:6832)
==19553== by 0x7B9046​: Perl_sv_clear (sv.c​:6499)
==19553== by 0x7B1117​: Perl_sv_free2 (sv.c​:6972)
==19553== by 0x525DF4​: Perl_parser_free (inline.h​:166)
==19553== by 0x8B8ECF​: Perl_leave_scope (scope.c​:1250)
==19553== by 0x4CF966​: S_my_exit_jump (perl.c​:5013)
==19553== by 0x4F4434​: Perl_my_failure_exit (perl.c​:5000)
==19553== by 0x903344​: Perl_die_unwind (pp_ctl.c​:1684)
==19553== If you believe this happened as a result of a stack
==19553== overflow in your program's main thread (unlikely but
==19553== possible), you can try to increase the size of the
==19553== main thread stack using the --main-stacksize= flag.
==19553== The main thread stack size used in this run was 8388608.
Segmentation fault

@p5pRT
Copy link
Author

p5pRT commented Jan 26, 2015

From @geeknik

On Mon Jan 26 03​:40​:33 2015, brian.carpenter@​gmail.com wrote​:

s)$0{0h());qx(@​0);qx(@​0);qx(@​0)

Crashes Perl 5.21.7 (v5.21-6-602-ge9d2bd8))

s)$0{0h());qx(@​0);qx(@​0);qx[-]

Does not crash Perl 5.21.7

@p5pRT
Copy link
Author

p5pRT commented Feb 4, 2015

From @geeknik

This crash is still present in v5.21.9 (v5.21.8-200-ga57d3d4).

@p5pRT
Copy link
Author

p5pRT commented Feb 8, 2015

From @cpansprout

On Mon Jan 26 03​:40​:33 2015, brian.carpenter@​gmail.com wrote​:

Good morning. The fuzzing attack against Perl continues with an interesting
(at least to me) test case.

Yes, very interesting.

Test case​:
s)$0{0h());qx(@​0);qx(@​0);qx(@​0)

This is a case where a syntax error causes scopes to be popped when the lexing state is LEX_KNOWNEXT, and it changes to LEX_NORMAL, somehow corrupting the pending token stack. I suspect the fix will be to eliminate the LEX_KNOWNEXT state and check the number of items on the pending token stack instead.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Feb 8, 2015

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Feb 8, 2015

From @wolfsage

On Sat Feb 07 17​:39​:18 2015, sprout wrote​:

Test case​:
s)$0{0h());qx(@​0);qx(@​0);qx(@​0)

This is a case where a syntax error causes scopes to be popped when
the lexing state is LEX_KNOWNEXT, and it changes to LEX_NORMAL,
somehow corrupting the pending token stack. I suspect the fix will be
to eliminate the LEX_KNOWNEXT state and check the number of items on
the pending token stack instead.

For what it's worth, I bisected this test case to​:

  eae48c8 is the first bad commit
  commit eae48c8
  Author​: Zefram <zefram@​fysh.org>
  Date​: Tue Oct 19 21​:16​:11 2010 +0100
 
  refactor and regularise label/statement grammar

which is what the '$1=eval{a​:}' case bisected to - https://rt-archive.perl.org/perl5/Ticket/Display.html?id=123652.

The bisect was...

  mhorsfall@​dory​:~/p5/perl$ cat ~/runner
  my $cmd = 's)$0{0h());qx(@​0);qx(@​0);qx[-]';
  my $what = system("./perl -Ilib -e '$cmd'");
  my $res = ($? >> 8) & 127;
 
  if ($res == 11) {
  die "Segfault!\n";
  } else {
  print "Okay!\n";
  }

  mhorfall@​dory​:~/p5/perl$ /home/mhorsfall/perl-1/Porting/bisect.pl --start=v5.13.6 --end=v5.13.7 -j 8 -- ./perl -Ilib /home/mhorsfall/runner

I had to hack /home/mhorsfall/perl-1/Porting/bisect-runner.pl to comment out​:
  # optimize => '-g',

I can't get this bug to trigger if I compile with -D optimize=-g. It triggers with

  ./Configure -des -Dusedevel

though. Also, I can't trigger it with threads​:

  ./Configure -des -Dusedevel -Dusethreads

-- Matthew Horsfall (alh)

@p5pRT
Copy link
Author

p5pRT commented Feb 8, 2015

From @cpansprout

On Sun Feb 08 12​:54​:38 2015, alh wrote​:

mhorfall@​dory​:~/p5/perl$ /home/mhorsfall/perl-1/Porting/bisect.pl
--start=v5.13.6 --end=v5.13.7 -j 8 -- ./perl -Ilib
/home/mhorsfall/runner

I had to hack /home/mhorsfall/perl-1/Porting/bisect-runner.pl to
comment out​:
# optimize => '-g',

I can't get this bug to trigger if I compile with -D optimize=-g. It
triggers with

./Configure -des -Dusedevel

though. Also, I can't trigger it with threads​:

./Configure -des -Dusedevel -Dusethreads

-- Matthew Horsfall (alh)

Even if it doesn’t crash, the -DT output gets scrambled with lines like​:

### 1​:LEX_KNOWNEXT/XTERM "@​0"
### <== ?? 63008

What happens if you bisect with -DT and check for ‘<== ??’ in the output?

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Feb 9, 2015

From @cpansprout

OK, I’ve now fixed this one in 7aa8cb0.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Feb 9, 2015

@cpansprout - Status changed from 'open' to 'pending release'

@p5pRT
Copy link
Author

p5pRT commented Feb 9, 2015

From @wolfsage

On Sun, Feb 8, 2015 at 5​:56 PM, Father Chrysostomos via RT
<perlbug-followup@​perl.org> wrote​:

Even if it doesn’t crash, the -DT output gets scrambled with lines like​:

### 1​:LEX_KNOWNEXT/XTERM "@​0"
### <== ?? 63008

What happens if you bisect with -DT and check for ‘<== ??’ in the output?

More fun here. I had to compile all versions with -O2 -g to get this
bug to trigger. It led to this​:

  mhorsfall@​dory​:~/perl-1$ git show f05d700
  commit f05d700
  Author​: Rafael Garcia-Suarez <rgarciasuarez@​gmail.com>
  Date​: Fri May 16 14​:13​:23 2008 +0200

  Prevent the tokenizer from segfaulting in debug mode when a FUNC
token is forced
  From​: "Rafael Garcia-Suarez" <rgarciasuarez@​gmail.com>
  Message-ID​:
<b77c1dce0805160313r78cb1b2bxfeb64460d2e9a7df@​mail.gmail.com>

  p4raw-id​: //depot/perl@​33833

  diff --git a/toke.c b/toke.c
  index abdc54d..2a63a90 100644
  --- a/toke.c
  +++ b/toke.c
  @​@​ -1359,7 +1359,7 @​@​ S_force_next(pTHX_ I32 type)
  #ifdef DEBUGGING
  if (DEBUG_T_TEST) {
  PerlIO_printf(Perl_debug_log, "### forced token​:\n");
  - tokereport(THING, &NEXTVAL_NEXTTOKE);
  + tokereport(type, &NEXTVAL_NEXTTOKE);
  }
  #endif
  #ifdef PERL_MAD

Attached are the -DT output from before the commit and after the
commit for comparison if it's of any interest.

-- Matthew Horsfall (alh)

@p5pRT
Copy link
Author

p5pRT commented Feb 9, 2015

From @wolfsage

### 0​:LEX_NORMAL/XSTATE "\n;"
### <== PMFUNC(opval=op_subst)

### 1​:LEX_INTERPPUSH/XTERM ";qx(@​0);qx(@​0);qx[-]\n"
### <== '('

### 1​:LEX_INTERPCONCAT/XTERM "$0{0h("
### 1​:LEX_INTERPSTART/XTERM "$0{0h("
### Interpolated variable
### 1​:LEX_INTERPNORMAL/XTERM "$0{0h("
### <== '$'

### 1​:LEX_INTERPENDMAYBE/XOPERATOR "{0h("
### Pending identifier '%0'
### <== WORD(opval=op_const) PV("0"\0)

### 1​:LEX_INTERPENDMAYBE/XOPERATOR "{0h("
### <== '{'

### 1​:LEX_INTERPNORMAL/XSTATE "0h("
### Saw number in "h("
### <== THING(opval=op_const) IV(0)

### 1​:LEX_INTERPNORMAL/XOPERATOR "h("
Bareword found where operator expected at -e line 1, near "0h"
  (Missing operator before h?)
### forced token​:
### <== THING(opval=op_const) PV("h"\0)

### <== '&'

### 1​:LEX_NORMAL/XOPERATOR ";qx(@​0);qx(@​0);qx[-]\n"
### <== ';'

### 1​:LEX_NORMAL/XSTATE "qx(@​0);qx(@​0);qx[-]\n"
### <== FUNC(ival=op_backtick)

### 1​:LEX_INTERPPUSH/XTERM ";qx(@​0);qx[-]\n"
### <== '('

### 1​:LEX_INTERPCONCAT/XTERM "@​0"
### 1​:LEX_INTERPSTART/XTERM "@​0"
### Interpolated variable
### forced token​:
### <== THING(opval=null)

### forced token​:
### <== THING(opval=op_const) PV("\""\0)

### forced token​:
### <== THING(opval=null)

### forced token​:
### <== THING(opval=null)

### forced token​:

@p5pRT
Copy link
Author

p5pRT commented Feb 9, 2015

From @wolfsage

### 0​:LEX_NORMAL/XSTATE "\n;"
### <== PMFUNC(opval=op_subst)

### 1​:LEX_INTERPPUSH/XTERM ";qx(@​0);qx(@​0);qx[-]\n"
### <== '('

### 1​:LEX_INTERPCONCAT/XTERM "$0{0h("
### 1​:LEX_INTERPSTART/XTERM "$0{0h("
### Interpolated variable
### 1​:LEX_INTERPNORMAL/XTERM "$0{0h("
### <== '$'

### 1​:LEX_INTERPENDMAYBE/XOPERATOR "{0h("
### Pending identifier '%0'
### <== WORD(opval=op_const) PV("0"\0)

### 1​:LEX_INTERPENDMAYBE/XOPERATOR "{0h("
### <== '{'

### 1​:LEX_INTERPNORMAL/XSTATE "0h("
### Saw number in "h("
### <== THING(opval=op_const) IV(0)

### 1​:LEX_INTERPNORMAL/XOPERATOR "h("
Bareword found where operator expected at -e line 1, near "0h"
  (Missing operator before h?)
### forced token​:
### <== WORD(opval=op_const) PV("h"\0)

### <== '&'

### 1​:LEX_NORMAL/XOPERATOR ";qx(@​0);qx(@​0);qx[-]\n"
### <== ';'

### 1​:LEX_NORMAL/XSTATE "qx(@​0);qx(@​0);qx[-]\n"
### <== FUNC(ival=op_backtick)

### 1​:LEX_INTERPPUSH/XTERM ";qx(@​0);qx[-]\n"
### <== '('

### 1​:LEX_INTERPCONCAT/XTERM "@​0"
### 1​:LEX_INTERPSTART/XTERM "@​0"
### Interpolated variable
### forced token​:
### <== ','

### forced token​:
### <== WORD(opval=op_const) PV("\""\0)

### forced token​:
### <== '$'

### forced token​:
### <== '('

### forced token​:
### <== FUNC(ival=op_join)

### 1​:LEX_KNOWNEXT/XTERM "@​0"
### <== ?? 5

### 1​:LEX_NORMAL/XTERM ";qx(@​0);qx[-]\n"
### <== ';'

### 1​:LEX_NORMAL/XSTATE "qx(@​0);qx[-]\n"
### <== FUNC(ival=op_backtick)

### 1​:LEX_INTERPPUSH/XTERM ";qx[-]\n"
### <== '('

### 1​:LEX_INTERPCONCAT/XTERM "@​0"
### 1​:LEX_INTERPSTART/XTERM "@​0"
### Interpolated variable
### forced token​:
### <== ','

### forced token​:
### <== WORD(opval=op_const) PV("\""\0)

### forced token​:
### <== '$'

### forced token​:
### <== '('

### forced token​:
### <== FUNC(ival=op_join)

### 1​:LEX_KNOWNEXT/XTERM "@​0"
### <== FUNC(ival=op_join)

### 1​:LEX_KNOWNEXT/XTERM "@​0"
### <== ?? 144

### 1​:LEX_NORMAL/XTERM ";qx[-]\n"
### <== ';'

### 1​:LEX_NORMAL/XSTATE "qx[-]\n"
### <== FUNC(ival=op_backtick)

### 1​:LEX_INTERPPUSH/XTERM "\n"
### <== '('

### 1​:LEX_INTERPCONCAT/XTERM "-"
### forced token​:
### <== THING(opval=op_const) PV("-"\0)

### 1​:LEX_KNOWNEXT/XTERM ""
### <== THING(opval=op_const) PV("-"\0)

### 1​:LEX_KNOWNEXT/XTERM ""
### <== EOF

syntax error at -e line 1, near "0h"
syntax error at -e line 1, next char ^E
syntax error at -e line 1, next char \220
syntax error at -e line 1, at EOF
Execution of -e aborted due to compilation errors.

@p5pRT
Copy link
Author

p5pRT commented Feb 9, 2015

From @cpansprout

On Mon Feb 09 07​:08​:38 2015, alh wrote​:

On Sun, Feb 8, 2015 at 5​:56 PM, Father Chrysostomos via RT
<perlbug-followup@​perl.org> wrote​:

Even if it doesn’t crash, the -DT output gets scrambled with lines like​:

### 1​:LEX_KNOWNEXT/XTERM "@​0"
### <== ?? 63008

What happens if you bisect with -DT and check for ‘<== ??’ in the output?

More fun here. I had to compile all versions with -O2 -g to get this
bug to trigger. It led to this​:

mhorsfall@​dory​:~/perl-1$ git show f05d700
commit f05d700
Author​: Rafael Garcia-Suarez <rgarciasuarez@​gmail.com>
Date​: Fri May 16 14​:13​:23 2008 +0200

  Prevent the tokenizer from segfaulting in debug mode when a FUNC

token is forced
From​: "Rafael Garcia-Suarez" <rgarciasuarez@​gmail.com>
Message-ID​:
<b77c1dce0805160313r78cb1b2bxfeb64460d2e9a7df@​mail.gmail.com>

  p4raw\-id&#8203;: //depot/perl@&#8203;33833

diff --git a/toke.c b/toke.c
index abdc54d..2a63a90 100644
--- a/toke.c
+++ b/toke.c
@​@​ -1359,7 +1359,7 @​@​ S_force_next(pTHX_ I32 type)
#ifdef DEBUGGING
if (DEBUG_T_TEST) {
PerlIO_printf(Perl_debug_log, "### forced token​:\n");
- tokereport(THING, &NEXTVAL_NEXTTOKE);
+ tokereport(type, &NEXTVAL_NEXTTOKE);
}
#endif
#ifdef PERL_MAD

Attached are the -DT output from before the commit and after the
commit for comparison if it's of any interest.

Well, it is certainly interesting. The first one stops abruptly at the buffer overflow. Presumably it crashed because of the bug that 05d7009fff fixed. The second one shows definitely buggy output.

When the overflow happens, nextval overflows into nexttype and nexttype overflows into nexttoke. Since nexttoke is an offset into the nexttype and nextval arrays, it is possible to read ahead into save_curcop, which is a memory address. That would explain why the bug is intermittent.

I suspect this bug is *old* and predates -DT output.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Feb 9, 2015

From @wolfsage

On Mon, Feb 9, 2015 at 12​:34 PM, Father Chrysostomos via RT
<perlbug-followup@​perl.org> wrote​:

Well, it is certainly interesting. The first one stops abruptly at the buffer overflow. Presumably it crashed because of the bug that 05d7009fff fixed. The second one shows definitely buggy output.

When the overflow happens, nextval overflows into nexttype and nexttype overflows into nexttoke. Since nexttoke is an offset into the nexttype and nextval arrays, it is possible to read ahead into save_curcop, which is a memory address. That would explain why the bug is intermittent.

I suspect this bug is *old* and predates -DT output.

Yeah. Thanks for the explanations. I'm done digging I think :)

-- Matthew Horsfall (alh)

@p5pRT
Copy link
Author

p5pRT commented Jun 2, 2015

From @khwilliamson

Thanks for submitting this ticket

The issue should be resolved with the release today of Perl v5.22, available at http​://www.perl.org/get.html
If you find that the problem persists, feel free to reopen this ticket

--
Karl Williamson for the Perl 5 porters team

@p5pRT p5pRT closed this as completed Jun 2, 2015
@p5pRT
Copy link
Author

p5pRT commented Jun 2, 2015

@khwilliamson - Status changed from 'pending release' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant