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-buffer-overflow Perl_sv_vcatpvfn_flags (sv.c:12912) #15599

Closed
p5pRT opened this issue Sep 15, 2016 · 15 comments

Comments

@p5pRT
Copy link

commented Sep 15, 2016

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

Searchable as RT129274$

@p5pRT

This comment has been minimized.

Copy link
Author

commented Sep 15, 2016

From @geeknik

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

@p5pRT

This comment has been minimized.

Copy link
Author

commented Sep 15, 2016

@p5pRT

This comment has been minimized.

Copy link
Author

commented Sep 15, 2016

From @geeknik

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

@p5pRT

This comment has been minimized.

Copy link
Author

commented Sep 15, 2016

@p5pRT

This comment has been minimized.

Copy link
Author

commented Oct 5, 2016

From @hvds

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

@p5pRT

This comment has been minimized.

Copy link
Author

commented Oct 5, 2016

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

@p5pRT

This comment has been minimized.

Copy link
Author

commented Oct 6, 2016

From @hvds

I think this has the same root cause as #129274, just taking a different route after the call to skipspace() from intuit_method().

Hugo

@p5pRT

This comment has been minimized.

Copy link
Author

commented Oct 6, 2016

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

@p5pRT

This comment has been minimized.

Copy link
Author

commented Nov 30, 2016

From @tonycoz

On Wed, 05 Oct 2016 06​:04​:14 -0700, hv wrote​:

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

@p5pRT

This comment has been minimized.

Copy link
Author

commented Nov 30, 2016

From @tonycoz

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

@p5pRT

This comment has been minimized.

Copy link
Author

commented Jan 24, 2017

From @tonycoz

On Tue, 29 Nov 2016 20​:31​:40 -0800, tonyc wrote​:

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 71776ae.

Please open a new ticket if you manage to find a similar issue this commit
doesn't fix.

Closing this ticket.

Tony

@p5pRT

This comment has been minimized.

Copy link
Author

commented Jan 24, 2017

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

@p5pRT

This comment has been minimized.

Copy link
Author

commented Jan 24, 2017

From @tonycoz

On Thu, 06 Oct 2016 07​:17​:42 -0700, hv wrote​:

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

@p5pRT

This comment has been minimized.

Copy link
Author

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

This comment has been minimized.

Copy link
Author

commented May 30, 2017

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

@p5pRT p5pRT closed this May 30, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.