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

heap-use-after-free Perl_yyerror_pvn (toke.c:11015) #15527

Closed
p5pRT opened this issue Aug 18, 2016 · 11 comments
Closed

heap-use-after-free Perl_yyerror_pvn (toke.c:11015) #15527

p5pRT opened this issue Aug 18, 2016 · 11 comments

Comments

@p5pRT
Copy link

p5pRT commented Aug 18, 2016

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

Searchable as RT128988$

@p5pRT
Copy link
Author

p5pRT commented Aug 18, 2016

From @geeknik

The attached test case triggers a heap-use-after-free in Perl_yyerror_pvn
(toke.c​:11015). This was found with AFL, ASAN and libdislocator.so and
affects v5.25.4 (v5.25.3-291-g0cf18b7). Does not seem to affect Perl
v5.20.2.

geeknik@​debian​:~/perl-tmp/out/2/crashes$ ./perl test01
Use of bare << to mean <<"" is deprecated at test01 line 1.

==31481==ERROR​: AddressSanitizer​: heap-use-after-free on address
0x60300000e680 at pc 0x0000006a3710 bp 0x7fff46c82f50 sp 0x7fff46c82f48
READ of size 1 at 0x60300000e680 thread T0
  #0 0x6a370f in Perl_yyerror_pvn /home/geeknik/perl/toke.c​:11015​:2
  #1 0x68426c in Perl_yyerror /home/geeknik/perl/toke.c​:10978​:12
  #2 0x6acb88 in Perl_yyparse /home/geeknik/perl/perly.c​:470​:2
  #3 0x59bf82 in S_parse_body /home/geeknik/perl/perl.c​:2372​:9
  #4 0x5922cc in perl_parse /home/geeknik/perl/perl.c​:1688​:2
  #5 0x4de835 in main /home/geeknik/perl/perlmain.c​:121​:18
  #6 0x7f8514419b44 in __libc_start_main
/build/glibc-uPj9cH/glibc-2.19/csu/libc-start.c​:287
  #7 0x4de4cc in _start (/home/geeknik/perl/perl+0x4de4cc)

0x60300000e680 is located 0 bytes inside of 24-byte region
[0x60300000e680,0x60300000e698)
freed by thread T0 here​:
  #0 0x4c0bcb in __interceptor_free (/home/geeknik/perl/perl+0x4c0bcb)
  #1 0x7f5964 in Perl_safesysfree /home/geeknik/perl/util.c​:388​:2
  #2 0x94a252 in Perl_sv_free2 /home/geeknik/perl/sv.c​:6956​:9

previously allocated by thread T0 here​:
  #0 0x4c113e in realloc (/home/geeknik/perl/perl+0x4c113e)
  #1 0x7f5186 in Perl_safesysrealloc /home/geeknik/perl/util.c​:274​:18

SUMMARY​: AddressSanitizer​: heap-use-after-free
/home/geeknik/perl/toke.c​:11015 Perl_yyerror_pvn
Shadow bytes around the buggy address​:
  0x0c067fff9c80​: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9c90​: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9ca0​: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9cb0​: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9cc0​: fa fa fa fa fa fa fa fa fa fa fd fd fd fd fa fa
=>0x0c067fff9cd0​:[fd]fd fd fa fa fa 00 00 00 fa fa fa 00 00 00 03
  0x0c067fff9ce0​: fa fa 00 00 04 fa fa fa 00 00 03 fa fa fa 00 00
  0x0c067fff9cf0​: 00 01 fa fa 00 00 02 fa fa fa 00 00 05 fa fa fa
  0x0c067fff9d00​: 00 00 00 06 fa fa 00 00 02 fa fa fa 00 00 02 fa
  0x0c067fff9d10​: fa fa 00 00 01 fa fa fa 00 00 02 fa fa fa 00 00
  0x0c067fff9d20​: 05 fa fa fa 00 00 00 07 fa fa 00 00 00 00 fa fa
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
  ASan internal​: fe
==31481==ABORTING

@p5pRT
Copy link
Author

p5pRT commented Aug 18, 2016

From @geeknik

test01

@p5pRT
Copy link
Author

p5pRT commented Aug 22, 2016

From @tonycoz

On Thu Aug 18 13​:17​:17 2016, brian.carpenter@​gmail.com wrote​:

The attached test case triggers a heap-use-after-free in Perl_yyerror_pvn
(toke.c​:11015). This was found with AFL, ASAN and libdislocator.so and
affects v5.25.4 (v5.25.3-291-g0cf18b7). Does not seem to affect Perl
v5.20.2.

I don't think this is a security issue.

It requires feeding code to perl, at which point an attacker has control
anyway.

The attached fixes it for me.

Tony

@p5pRT
Copy link
Author

p5pRT commented Aug 22, 2016

From @tonycoz

0001-perl-128988-preserve-PL_oldoldbufptr-is-preserved-in.patch
From f6abce1cfb2cb88aea8bef8ca46d7fa159eb29da Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Mon, 22 Aug 2016 13:56:26 +1000
Subject: [PATCH] (perl #128988) preserve PL_oldoldbufptr is preserved in
 scan_heredoc()

In some cases this is used in building error messages.
---
 t/op/heredoc.t | 11 ++++++++++-
 toke.c         |  4 ++++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/t/op/heredoc.t b/t/op/heredoc.t
index 90ba606..f47f7ce 100644
--- a/t/op/heredoc.t
+++ b/t/op/heredoc.t
@@ -7,7 +7,7 @@ BEGIN {
 }
 
 use strict;
-plan(tests => 41);
+plan(tests => 42);
 
 
 # heredoc without newline (#65838)
@@ -99,6 +99,15 @@ HEREDOC
         "don't use an invalid oldoldbufptr"
     );
 
+    # also read freed memory, but got an invalid oldoldbufptr in a different way
+    fresh_perl_like(
+        qq(<<\n\$          \n),
+        # valgrind and asan reports an error between these two lines
+        qr/^Use of bare << to mean <<"" is deprecated at - line 1\.\s+Final \$/,
+        {},
+        "don't use an invalid oldoldbufptr (some more)"
+    );
+
     # [perl #125540] this asserted or crashed
     fresh_perl_like(
 	q(map d$#<<<<),
diff --git a/toke.c b/toke.c
index 2da8366..7d2a289 100644
--- a/toke.c
+++ b/toke.c
@@ -9721,6 +9721,7 @@ S_scan_heredoc(pTHX_ char *s)
     {
       SV *linestr_save;
       char *oldbufptr_save;
+      char **oldoldbufptr_save;
      streaming:
       sv_setpvs(tmpstr,"");   /* avoid "uninitialized" warning */
       term = PL_tokenbuf[1];
@@ -9728,6 +9729,7 @@ S_scan_heredoc(pTHX_ char *s)
       linestr_save = PL_linestr; /* must restore this afterwards */
       d = s;			 /* and this */
       oldbufptr_save = PL_oldbufptr;
+      oldoldbufptr_save = PL_oldoldbufptr;
       PL_linestr = newSVpvs("");
       PL_bufend = SvPVX(PL_linestr);
       while (1) {
@@ -9745,6 +9747,7 @@ S_scan_heredoc(pTHX_ char *s)
 	    SvREFCNT_dec_NN(PL_linestr);
 	    PL_linestr = linestr_save;
             PL_oldbufptr = oldbufptr_save;
+            PL_oldoldbufptr = oldoldbufptr_save;
 	    goto interminable;
 	}
 	CopLINE_set(PL_curcop, origline);
@@ -9780,6 +9783,7 @@ S_scan_heredoc(pTHX_ char *s)
 	    PL_linestart = SvPVX(linestr_save);
 	    PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr);
             PL_oldbufptr = oldbufptr_save;
+            PL_oldoldbufptr = oldoldbufptr_save;
 	    s = d;
 	    break;
 	}
-- 
2.1.4

@p5pRT
Copy link
Author

p5pRT commented Aug 22, 2016

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

@p5pRT
Copy link
Author

p5pRT commented Aug 22, 2016

From @geeknik

lgtm

On Sun, Aug 21, 2016 at 10​:58 PM, Tony Cook via RT <
perl5-security-report@​perl.org> wrote​:

On Thu Aug 18 13​:17​:17 2016, brian.carpenter@​gmail.com wrote​:

The attached test case triggers a heap-use-after-free in Perl_yyerror_pvn
(toke.c​:11015). This was found with AFL, ASAN and libdislocator.so and
affects v5.25.4 (v5.25.3-291-g0cf18b7). Does not seem to affect Perl
v5.20.2.

I don't think this is a security issue.

It requires feeding code to perl, at which point an attacker has control
anyway.

The attached fixes it for me.

Tony

From f6abce1cfb2cb88aea8bef8ca46d7fa159eb29da Mon Sep 17 00​:00​:00 2001
From​: Tony Cook <tony@​develop-help.com>
Date​: Mon, 22 Aug 2016 13​:56​:26 +1000
Subject​: [PATCH] (perl #128988) preserve PL_oldoldbufptr is preserved in
scan_heredoc()

In some cases this is used in building error messages.
---
t/op/heredoc.t | 11 ++++++++++-
toke.c | 4 ++++
2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/t/op/heredoc.t b/t/op/heredoc.t
index 90ba606..f47f7ce 100644
--- a/t/op/heredoc.t
+++ b/t/op/heredoc.t
@​@​ -7,7 +7,7 @​@​ BEGIN {
}

use strict;
-plan(tests => 41);
+plan(tests => 42);

# heredoc without newline (#65838)
@​@​ -99,6 +99,15 @​@​ HEREDOC
"don't use an invalid oldoldbufptr"
);

+ # also read freed memory, but got an invalid oldoldbufptr in a
different way
+ fresh_perl_like(
+ qq(<<\n\$ \n),
+ # valgrind and asan reports an error between these two lines
+ qr/^Use of bare << to mean <<"" is deprecated at - line
1\.\s+Final \$/,
+ {},
+ "don't use an invalid oldoldbufptr (some more)"
+ );
+
# [perl #125540] this asserted or crashed
fresh_perl_like(
q(map d$#<<<<),
diff --git a/toke.c b/toke.c
index 2da8366..7d2a289 100644
--- a/toke.c
+++ b/toke.c
@​@​ -9721,6 +9721,7 @​@​ S_scan_heredoc(pTHX_ char *s)
{
SV *linestr_save;
char *oldbufptr_save;
+ char **oldoldbufptr_save;
streaming​:
sv_setpvs(tmpstr,""); /* avoid "uninitialized" warning */
term = PL_tokenbuf[1];
@​@​ -9728,6 +9729,7 @​@​ S_scan_heredoc(pTHX_ char *s)
linestr_save = PL_linestr; /* must restore this afterwards */
d = s; /* and this */
oldbufptr_save = PL_oldbufptr;
+ oldoldbufptr_save = PL_oldoldbufptr;
PL_linestr = newSVpvs("");
PL_bufend = SvPVX(PL_linestr);
while (1) {
@​@​ -9745,6 +9747,7 @​@​ S_scan_heredoc(pTHX_ char *s)
SvREFCNT_dec_NN(PL_linestr);
PL_linestr = linestr_save;
PL_oldbufptr = oldbufptr_save;
+ PL_oldoldbufptr = oldoldbufptr_save;
goto interminable;
}
CopLINE_set(PL_curcop, origline);
@​@​ -9780,6 +9783,7 @​@​ S_scan_heredoc(pTHX_ char *s)
PL_linestart = SvPVX(linestr_save);
PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr);
PL_oldbufptr = oldbufptr_save;
+ PL_oldoldbufptr = oldoldbufptr_save;
s = d;
break;
}
--
2.1.4

@p5pRT
Copy link
Author

p5pRT commented Aug 25, 2016

From @iabyn

On Sun, Aug 21, 2016 at 08​:58​:15PM -0700, Tony Cook via RT wrote​:

On Thu Aug 18 13​:17​:17 2016, brian.carpenter@​gmail.com wrote​:

The attached test case triggers a heap-use-after-free in Perl_yyerror_pvn
(toke.c​:11015). This was found with AFL, ASAN and libdislocator.so and
affects v5.25.4 (v5.25.3-291-g0cf18b7). Does not seem to affect Perl
v5.20.2.

I don't think this is a security issue.

It requires feeding code to perl, at which point an attacker has control
anyway.

Agreed.

--
O Unicef Clearasil!
Gibberish and Drivel!
  -- "Bored of the Rings"

@p5pRT
Copy link
Author

p5pRT commented Sep 7, 2016

From @tonycoz

On Sun Aug 21 21​:11​:02 2016, brian.carpenter@​gmail.com wrote​:

lgtm

Applied as 382450a.

On Thu Aug 25 08​:46​:42 2016, davem wrote​:

I don't think this is a security issue.

It requires feeding code to perl, at which point an attacker has
control
anyway.

Agreed.

Making the ticket public.

Tony

@p5pRT
Copy link
Author

p5pRT commented Sep 7, 2016

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

@p5pRT
Copy link
Author

p5pRT commented May 30, 2017

From @khwilliamson

Thank you for filing this report. You have helped make Perl better.

With the release today of Perl 5.26.0, this and 210 other issues have been
resolved.

Perl 5.26.0 may be downloaded via​:
https://metacpan.org/release/XSAWYERX/perl-5.26.0

If you find that the problem persists, feel free to reopen this ticket.

@p5pRT p5pRT closed this as completed May 30, 2017
@p5pRT
Copy link
Author

p5pRT commented May 30, 2017

@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