Skip Menu |
Report information
Id: 129274
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)



From: "Brian 'geeknik' Carpenter" <brian.carpenter [...] gmail.com>
Subject: heap-use-after-free in Perl_yylex (toke.c:4880)
Date: Thu, 15 Sep 2016 01:14:24 -0500
To: perl5-security-report [...] perl.org
Download (untitled) / with headers
text/plain 2.6k
The attached test case triggers a heap-use-after-free in Perl_yylex (toke.c:4880) in v5.25.5 (v5.25.4-130-g7aa7bbc). Perl 5.20.2 complains about $# no longer being supported.

od -tx1 test16
0000000 73 74 61 74 09 74 24 23 30
0000011

=================================================================
==28052==ERROR: AddressSanitizer: heap-use-after-free on address 0x60200000e276 at pc 0x000000659334 bp 0x7ffc08f3c7b0 sp 0x7ffc08f3c7a8
READ of size 1 at 0x60200000e276 thread T0
    #0 0x659333 in Perl_yylex /root/perl/toke.c:4880:5
    #1 0x6add4e in Perl_yyparse /root/perl/perly.c:334:19
    #2 0x59c491 in S_parse_body /root/perl/perl.c:2373:9
    #3 0x59283c in perl_parse /root/perl/perl.c:1689:2
    #4 0x4de5d5 in main /root/perl/perlmain.c:121:18
    #5 0x7f5a33120b44 in __libc_start_main /build/glibc-uPj9cH/glibc-2.19/csu/libc-start.c:287
    #6 0x4de26c in _start (/root/perl/perl+0x4de26c)

0x60200000e276 is located 6 bytes inside of 10-byte region [0x60200000e270,0x60200000e27a)
freed by thread T0 here:
    #0 0x4c0ede in realloc (/root/perl/perl+0x4c0ede)
    #1 0x7f8a46 in Perl_safesysrealloc /root/perl/util.c:274:18

previously allocated by thread T0 here:
    #0 0x4c0beb in malloc (/root/perl/perl+0x4c0beb)
    #1 0x7f8357 in Perl_safesysmalloc /root/perl/util.c:153:21

SUMMARY: AddressSanitizer: heap-use-after-free /root/perl/toke.c:4880 Perl_yylex
Shadow bytes around the buggy address:
  0x0c047fff9bf0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9c00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9c10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9c20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9c30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c047fff9c40: fa fa fa fa fa fa 00 02 fa fa 00 02 fa fa[fd]fd
  0x0c047fff9c50: fa fa 00 04 fa fa 02 fa fa fa 00 02 fa fa 00 07
  0x0c047fff9c60: fa fa 00 fa fa fa 00 02 fa fa 05 fa fa fa 00 02
  0x0c047fff9c70: fa fa 06 fa fa fa 00 02 fa fa 05 fa fa fa 00 05
  0x0c047fff9c80: fa fa 04 fa fa fa 05 fa fa fa 05 fa fa fa 00 00
  0x0c047fff9c90: fa fa 00 02 fa fa 05 fa fa fa 00 02 fa fa 00 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
==28052==ABORTING

Download test16.gz
application/x-gzip 36b

Message body not shown because it is not plain text.

Date: Thu, 15 Sep 2016 01:19:36 -0500
To: perl5-security-report [...] perl.org
From: "Brian 'geeknik' Carpenter" <brian.carpenter [...] gmail.com>
Subject: heap-buffer-overflow Perl_sv_vcatpvfn_flags (sv.c:12912)
Download (untitled) / with headers
text/plain 2.9k
The attached test case triggers a heap-buffer-overflow in Perl_sv_vcatpvfn_flags (sv.c:12912) in v5.25.5 (v5.25.4-130-g7aa7bbc). Perl 5.20.2 complains about $# no longer being supported.

od -tx1 test17
0000000 73 74 61 74 09 74 24 23 10 24 24 24 24 6d 8d 2c
0000020 24 23 24 6d 6e 70 72 74 2c 70 6f 72 74 2c 73 6f
0000040 72 74 0a 73 6f 72 74 59
0000050

==21100==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60400000a40e at pc 0x0000004a9680 bp 0x7ffd54be2db0 sp 0x7ffd54be2570
READ of size 10 at 0x60400000a40e thread T0
    #0 0x4a967f in __asan_memcpy (/root/perl/perl+0x4a967f)
    #1 0x98cc46 in Perl_sv_vcatpvfn_flags /root/perl/sv.c:12912:6
    #2 0x96d6d6 in Perl_sv_vsetpvfn /root/perl/sv.c:10809:5
    #3 0x802802 in Perl_vmess /root/perl/util.c:1586:5
    #4 0x802802 in Perl_vcroak /root/perl/util.c:1815
    #5 0x7f86fc in Perl_croak /root/perl/util.c:1862:5
    #6 0x62ca1e in Perl_yylex /root/perl/toke.c:4910:9
    #7 0x6add4e in Perl_yyparse /root/perl/perly.c:334:19
    #8 0x59c491 in S_parse_body /root/perl/perl.c:2373:9
    #9 0x59283c in perl_parse /root/perl/perl.c:1689:2
    #10 0x4de5d5 in main /root/perl/perlmain.c:121:18
    #11 0x7fbb50d10b44 in __libc_start_main /build/glibc-uPj9cH/glibc-2.19/csu/libc-start.c:287
    #12 0x4de26c in _start (/root/perl/perl+0x4de26c)

0x60400000a40e is located 2 bytes to the left of 48-byte region [0x60400000a410,0x60400000a440)
allocated by thread T0 here:
    #0 0x4c0ede in realloc (/root/perl/perl+0x4c0ede)
    #1 0x7f8a46 in Perl_safesysrealloc /root/perl/util.c:274:18

SUMMARY: AddressSanitizer: heap-buffer-overflow ??:0 __asan_memcpy
Shadow bytes around the buggy address:
  0x0c087fff9430: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9440: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9450: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9460: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9470: fa fa fa fa fa fa fa fa fa fa 00 00 00 00 03 fa
=>0x0c087fff9480: fa[fa]00 00 00 00 00 00 fa fa 00 00 00 00 00 fa
  0x0c087fff9490: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00 00
  0x0c087fff94a0: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 06 fa
  0x0c087fff94b0: fa fa 00 00 00 00 00 01 fa fa 00 00 00 00 00 00
  0x0c087fff94c0: fa fa 00 00 00 00 06 fa fa fa 00 00 00 00 00 00
  0x0c087fff94d0: fa fa 00 00 00 00 07 fa fa fa 00 00 00 00 00 00
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
==21100==ABORTING

Download test17.gz
application/x-gzip 60b

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 652b
A shorter test case (failure indicated by "column -1"): % perl -le 'print "stat t\$#\x{10}"' | ./miniperl $# is no longer supported at - line 1. Unrecognized character \x10; marked by <-- HERE after stat t$#<-- HERE near column -1 at - line 1. % This is a lexer issue that I do not have sufficient knowledge to fix: at the point toke.c:4910 wants to report that \x{10} is an unrecognized character, PL_linestart is already pointing at the following line. This was advanced by S_intuit_method calling skipspace() at the '#' after seeing the '$', which skipspace then treated as a comment. I don't think this is likely to be a security concern. Hugo
RT-Send-CC: rt-deliver-to-perl5-security-report [...] rt.perl.org
Download (untitled) / with headers
text/plain 136b
I think this has the same root cause as #129274, just taking a different route after the call to skipspace() from intuit_method(). Hugo
RT-Send-CC: perl5-porters [...] perl.org
On Wed, 05 Oct 2016 06:04:14 -0700, hv wrote: Show quoted text
> A shorter test case (failure indicated by "column -1"): > > % perl -le 'print "stat t\$#\x{10}"' | ./miniperl > $# is no longer supported at - line 1. > Unrecognized character \x10; marked by <-- HERE after stat t$#<-- HERE > near column -1 at - line 1. > % > > This is a lexer issue that I do not have sufficient knowledge to fix: > at the point toke.c:4910 wants to report that \x{10} is an > unrecognized character, PL_linestart is already pointing at the > following line. This was advanced by S_intuit_method calling > skipspace() at the '#' after seeing the '$', which skipspace then > treated as a comment. > > I don't think this is likely to be a security concern.
I agree, so I've move the ticket to the public queue. Treating the # immediately following the $ as a comment in intuit_method() strikes me as a bug in itself, which I think the attached fixes. I don't think this fixes the base issue though - I'm not sure how to fix that, perhaps intuit_method() should be restoring PL_linestart. Tony
Subject: 0001-perl-129274-avoid-treating-the-in-as-a-comment-intro.patch
From e30a508ca4fb9d4cd2164e495ea9f76420d6dae4 Mon Sep 17 00:00:00 2001 From: Tony Cook <tony@develop-help.com> Date: Wed, 30 Nov 2016 15:28:16 +1100 Subject: (perl #129274) avoid treating the # in $# as a comment intro --- toke.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/toke.c b/toke.c index 11abf2b..2a7b374 100644 --- a/toke.c +++ b/toke.c @@ -4092,7 +4092,9 @@ S_intuit_method(pTHX_ char *start, SV *ioname, CV *cv) if (cv || PL_last_lop_op == OP_PRINT || PL_last_lop_op == OP_SAY || isUPPER(*PL_tokenbuf)) return 0; - s = skipspace(s); + /* this could be $# */ + if (isSPACE(*s)) + s = skipspace(s); PL_bufptr = start; PL_expect = XREF; return *s == '(' ? FUNCMETH : METHOD; -- 2.1.4
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 806b
On Tue, 29 Nov 2016 20:31:40 -0800, tonyc wrote: Show quoted text
> On Wed, 05 Oct 2016 06:04:14 -0700, hv wrote:
> > I don't think this is likely to be a security concern.
> > I agree, so I've move the ticket to the public queue. > > Treating the # immediately following the $ as a comment in > intuit_method() strikes me as a bug in itself, which I think > the attached fixes. > > I don't think this fixes the base issue though - I'm not sure > how to fix that, perhaps intuit_method() should be restoring > PL_linestart.
I spent some time trying to make this crash with my patch in place but couldn't manage it. I've applied my patch (with a test added) as 71776ae4fad9a7659deefe0c2376d45b873ffd6a. Please open a new ticket if you manage to find a similar issue this commit doesn't fix. Closing this ticket. Tony
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 251b
On Thu, 06 Oct 2016 07:17:42 -0700, hv wrote: Show quoted text
> I think this has the same root cause as #129274, just taking a > different route after the call to skipspace() from intuit_method().
I agree, merging into 129274, which is public and fixed/closed. 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