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

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

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



To: perl5-security-report [...] perl.org
Subject: heap-use-after-free Perl_yyerror_pvn (toke.c:11015)
From: "Brian 'geeknik' Carpenter" <brian.carpenter [...] gmail.com>
Date: Thu, 18 Aug 2016 15:16:08 -0500
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


Download test01
application/octet-stream 15b

Message body not shown because it is not plain text.

RT-Send-CC: rt-deliver-to-perl5-security-report [...] rt.perl.org
Download (untitled) / with headers
text/plain 452b
On Thu Aug 18 13:17:17 2016, brian.carpenter@gmail.com wrote: Show quoted text
> 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
Subject: 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
Date: Sun, 21 Aug 2016 23:09:46 -0500
From: "Brian 'geeknik' Carpenter" <brian.carpenter [...] gmail.com>
To: perl5-security-report [...] perl.org
Subject: Re: [perl #128988] heap-use-after-free Perl_yyerror_pvn (toke.c:11015)
Download (untitled) / with headers
text/plain 3.1k
lgtm

On Sun, Aug 21, 2016 at 10:58 PM, Tony Cook via RT <perl5-security-report@perl.org> wrote:
Show quoted text
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



Subject: Re: [perl #128988] heap-use-after-free Perl_yyerror_pvn (toke.c:11015)
To: Tony Cook via RT <perl5-security-report [...] perl.org>
From: Dave Mitchell <davem [...] iabyn.com>
CC: rt-deliver-to-perl5-security-report [...] rt.perl.org
Date: Thu, 25 Aug 2016 16:46:17 +0100
Download (untitled) / with headers
text/plain 587b
On Sun, Aug 21, 2016 at 08:58:15PM -0700, Tony Cook via RT wrote: Show quoted text
> 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"
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 352b
On Sun Aug 21 21:11:02 2016, brian.carpenter@gmail.com wrote: Show quoted text
> lgtm
Applied as 382450a68fa9cdd5206e8c46383bd92e63aeb392. On Thu Aug 25 08:46:42 2016, davem wrote: Show quoted text
> > 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
Download (untitled) / with headers
text/plain 313b
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.


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