Skip Menu |
Report information
Id: 131793
Status: pending release
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: gy741.kim [at] gmail.com
quangnh89 [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-buffer-overflow in Perl_sv_vcatpvfn_flags
From: GwanYeong Kim <gy741.kim [...] gmail.com>
Date: Tue, 25 Jul 2017 13:23:01 +0900
Download (untitled) / with headers
text/plain 3.1k

Hi.

I found a heap-buffer-overflow bug in perl.

Please confirm.

Thanks.

Version: This is perl 5, version 27, subversion 2 (v5.27.2) built for i686-linux
OS: Ubuntu 16.04.2 32bit
Steps to reproduce:
 1.Download the PoC files.
 2.Compile the source code with ASan.
 3.Execute the following command
   : ./perl $PoC
=================================================================
==18930==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xb5302bb9 at pc 0x08102b95 bp 0xbf8d9d08 sp 0xbf8d98e0
READ of size 10 at 0xb5302bb9 thread T0
    #0 0x8102b94 in __asan_memcpy (/root/perl5-blead/perl+0x8102b94)
    #1 0x86bab6a in Perl_sv_vcatpvfn_flags /root/perl5-blead/sv.c:13346:17
    #2 0x869dc07 in Perl_sv_vsetpvfn /root/perl5-blead/sv.c:10961:5
    #3 0x84e2d2a in Perl_vmess /root/perl5-blead/util.c:1487:5
    #4 0x84e2d2a in Perl_vcroak /root/perl5-blead/util.c:1716
    #5 0x84e2d2a in Perl_croak /root/perl5-blead/util.c:1763
    #6 0x82dc5cc in Perl_yylex /root/perl5-blead/toke.c:5167:9
    #7 0x835df10 in Perl_yyparse /root/perl5-blead/perly.c:340:34
    #8 0x8232350 in S_parse_body /root/perl5-blead/perl.c:2401:9
    #9 0x82285e3 in perl_parse /root/perl5-blead/perl.c:1719:2
    #10 0x81494a6 in main /root/perl5-blead/perlmain.c:121:18
    #11 0xb747d636 in __libc_start_main /build/glibc-KM3i_a/glibc-2.23/csu/../csu/libc-start.c:291
    #12 0x8075847 in _start (/root/perl5-blead/perl+0x8075847)

0xb5302bb9 is located 7 bytes to the left of 120-byte region [0xb5302bc0,0xb5302c38)
allocated by thread T0 here:
    #0 0x8119ef4 in realloc (/root/perl5-blead/perl+0x8119ef4)
    #1 0x84e3394 in Perl_safesysrealloc /root/perl5-blead/util.c:274:18

SUMMARY: AddressSanitizer: heap-buffer-overflow (/root/perl5-blead/perl+0x8102b94) in __asan_memcpy
Shadow bytes around the buggy address:
  0x36a60520: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36a60530: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36a60540: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36a60550: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36a60560: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x36a60570: fa fa fa fa fa fa fa[fa]00 00 00 00 00 00 00 00
  0x36a60580: 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa fa
  0x36a60590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa
  0x36a605a0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x36a605b0: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa
  0x36a605c0: 00 00 00 00 00 00 00 00 00 00 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
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==18930==ABORTING

Download PoC_07_25
application/octet-stream 115b

Message body not shown because it is not plain text.

Date: Tue, 25 Jul 2017 11:43:58 +0100
From: Dave Mitchell <davem [...] iabyn.com>
To: perl5-security-report [...] perl.org
Subject: Re: [perl #131793] heap-buffer-overflow in Perl_sv_vcatpvfn_flags
Download (untitled) / with headers
text/plain 1.6k
On Mon, Jul 24, 2017 at 09:23:22PM -0700, GwanYeong Kim wrote: Show quoted text
> I found a heap-buffer-overflow bug in perl. > > Please confirm. > Thanks. > > Version: This is perl 5, version 27, subversion 2 (v5.27.2) built for > i686-linux > OS: Ubuntu 16.04.2 32bit > Steps to reproduce: > 1.Download the PoC files. > 2.Compile the source code with ASan. > 3.Execute the following command > : ./perl $PoC > ================================================================= > ==18930==ERROR: AddressSanitizer: heap-buffer-overflow on address > 0xb5302bb9 at pc 0x08102b95 bp 0xbf8d9d08 sp 0xbf8d98e0 > READ of size 10 at 0xb5302bb9 thread T0 > #0 0x8102b94 in __asan_memcpy (/root/perl5-blead/perl+0x8102b94) > #1 0x86bab6a in Perl_sv_vcatpvfn_flags /root/perl5-blead/sv.c:13346:17
I've had a quick look, and it's a lexer issue rather than a problem in _sv_vcatpvfn_flags(). yylex is doing this: Perl_croak(aTHX_ "Unrecognized character %s; marked by <-- HERE after %" UTF8f "<-- HERE near column %d", c, UTF8fARG(UTF, (s - d), d), (int) len + 1); where d and s are supposed to delineate part of the src code, but according to valgrind, d at this point is a wild pointer 7 bytes before the start of a malloced buffer. Since it probably requires feeding attacker-controlled src code into the lexer, I suspect that it isn't a security issue. I *hate* the lexer. If anyone else wants to fix this, feel free. -- The Enterprise is involved in a bizarre time-warp experience which is in some way unconnected with the Late 20th Century. -- Things That Never Happen in "Star Trek" #14
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 1.9k
On Tue, 25 Jul 2017 03:44:14 -0700, davem wrote: Show quoted text
> On Mon, Jul 24, 2017 at 09:23:22PM -0700, GwanYeong Kim wrote:
> > I found a heap-buffer-overflow bug in perl. > > > > Please confirm. > > Thanks. > > > > Version: This is perl 5, version 27, subversion 2 (v5.27.2) built for > > i686-linux > > OS: Ubuntu 16.04.2 32bit > > Steps to reproduce: > > 1.Download the PoC files. > > 2.Compile the source code with ASan. > > 3.Execute the following command > > : ./perl $PoC > > ================================================================= > > ==18930==ERROR: AddressSanitizer: heap-buffer-overflow on address > > 0xb5302bb9 at pc 0x08102b95 bp 0xbf8d9d08 sp 0xbf8d98e0 > > READ of size 10 at 0xb5302bb9 thread T0 > > #0 0x8102b94 in __asan_memcpy (/root/perl5-blead/perl+0x8102b94) > > #1 0x86bab6a in Perl_sv_vcatpvfn_flags /root/perl5- > > blead/sv.c:13346:17
> > I've had a quick look, and it's a lexer issue rather than a problem > in _sv_vcatpvfn_flags(). > > yylex is doing this: > > Perl_croak(aTHX_ "Unrecognized character %s; marked by <-- HERE after > %" UTF8f "<-- HERE near column %d", c, > UTF8fARG(UTF, (s - d), d), > (int) len + 1); > > where d and s are supposed to delineate part of the src code, but > according to valgrind, d at this point is a wild pointer 7 bytes > before > the start of a malloced buffer.
d gets that value because PL_linestart is after s (aka PL_bufptr at this point), which happens due to a failed attempt to parse a ${identifier} (identifier in this case starts with a "\xd5", supported presumably for ${^Xxxx} reasons.) Show quoted text
> Since it probably requires feeding attacker-controlled src code into > the > lexer, I suspect that it isn't a security issue.
Agreed, this ticket is now public. Show quoted text
> I *hate* the lexer. If anyone else wants to fix this, feel free.
The attached fixes the symptom, I don't know if scan_ident() should be working harder to avoid advancing PL_linestart when it fails to parse an identifier. Tony
Subject: 0001-perl-131793-sanely-handle-PL_linestart-PL_bufptr.patch
From 77a3e1e5a81d1492a86bac337a93a1247994837d Mon Sep 17 00:00:00 2001 From: Tony Cook <tony@develop-help.com> Date: Wed, 26 Jul 2017 12:04:18 +1000 Subject: (perl #131793) sanely handle PL_linestart > PL_bufptr In the test case, scan_ident() ends up fetching another line (updating PL_linestart), and since in this case we don't successfully parse ${identifier} s (and PL_bufptr) end up being before PL_linestart. --- t/comp/parser_run.t | 9 ++++++++- toke.c | 19 +++++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/t/comp/parser_run.t b/t/comp/parser_run.t index e74644d..0fca5b2 100644 --- a/t/comp/parser_run.t +++ b/t/comp/parser_run.t @@ -10,7 +10,7 @@ BEGIN { } require './test.pl'; -plan(1); +plan(2); # [perl #130814] can reallocate lineptr while looking ahead for # "Missing $ on loop variable" diagnostic. @@ -24,5 +24,12 @@ syntax error at - line 3, near "foreach m0 Identifier too long at - line 3. EXPECT +fresh_perl_is(<<EOS, <<'EXPECT', {}, "linestart before bufptr"); +\${ \xD5eeeeeeeeeeee +'x +EOS +Unrecognized character \xD5; marked by <-- HERE after ${ <-- HERE near column 4 at - line 1. +EXPECT + __END__ # ex: set ts=8 sts=4 sw=4 et: diff --git a/toke.c b/toke.c index 6aa5f26..1b203cd 100644 --- a/toke.c +++ b/toke.c @@ -5158,12 +5158,23 @@ Perl_yylex(pTHX) else { c = Perl_form(aTHX_ "\\x%02X", (unsigned char)*s); } - len = UTF ? Perl_utf8_length(aTHX_ (U8 *) PL_linestart, (U8 *) s) : (STRLEN) (s - PL_linestart); - if (len > UNRECOGNIZED_PRECEDE_COUNT) { - d = UTF ? (char *) utf8_hop_back((U8 *) s, -UNRECOGNIZED_PRECEDE_COUNT, (U8 *)PL_linestart) : s - UNRECOGNIZED_PRECEDE_COUNT; - } else { + + if (s >= PL_linestart) { d = PL_linestart; } + else { + /* somehow (probably due to a parse failure), PL_linestart has advanced + * pass PL_bufptr, get a reasonable beginning of line + */ + d = s; + while (d > SvPVX(PL_linestr) && d[-1] && d[-1] != '\n') + --d; + } + len = UTF ? Perl_utf8_length(aTHX_ (U8 *) d, (U8 *) s) : (STRLEN) (s - d); + if (len > UNRECOGNIZED_PRECEDE_COUNT) { + d = UTF ? (char *) utf8_hop_back((U8 *) s, -UNRECOGNIZED_PRECEDE_COUNT, (U8 *)d) : s - UNRECOGNIZED_PRECEDE_COUNT; + } + Perl_croak(aTHX_ "Unrecognized character %s; marked by <-- HERE after %" UTF8f "<-- HERE near column %d", c, UTF8fARG(UTF, (s - d), d), (int) len + 1); -- 2.1.4
Date: Wed, 16 Aug 2017 09:43:37 +0700
To: perl5-security-report [...] perl.org
Subject: integer overflow leads to heap overflow in php5
From: Quang Nguyen <quangnh89 [...] gmail.com>
Download (untitled) / with headers
text/plain 4.3k
The attached script triggers a heap-buffer-overflow Perl_sv_vcatpvfn (sv.c:13353:17). This was found with ASAN.

=================================================================
==1380==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000fa8 at pc 0x0000004c6337 bp 0x7ffc3713f3f0 sp 0x7ffc3713eba0
READ of size 10 at 0x602000000fa8 thread T0
    #0 0x4c6336 in __asan_memcpy /scratch/llvm/clang-4/xenial/final/llvm.src/projects/compiler-rt/lib/asan/asan_interceptors.cc:453:3
    #1 0xd46667 in Perl_sv_vcatpvfn_flags /root/fuzz/perl5/perl-new/sv.c:13353:17
    #2 0xd16cd2 in Perl_sv_vsetpvfn /root/fuzz/perl5/perl-new/sv.c:10970:5
    #3 0xa405dd in Perl_vmess /root/fuzz/perl5/perl-new/util.c:1487:5
    #4 0xa45bda in Perl_vcroak /root/fuzz/perl5/perl-new/util.c:1716:14
    #5 0xa36cfb in Perl_croak /root/fuzz/perl5/perl-new/util.c:1763:5
    #6 0x71f7d6 in Perl_yylex /root/fuzz/perl5/perl-new/toke.c:5167:9
    #7 0x80cb4c in Perl_yyparse /root/fuzz/perl5/perl-new/perly.c:340:34
    #8 0x631f27 in S_parse_body /root/fuzz/perl5/perl-new/perl.c:2414:9
    #9 0x627a05 in perl_parse /root/fuzz/perl5/perl-new/perl.c:1732:2
    #10 0x5095f8 in main /root/fuzz/perl5/perl-new/perlmain.c:121:18
    #11 0x7f8e7d94782f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #12 0x4359f8 in _start (/root/fuzz/perl5/perl-asan/perl+0x4359f8)

0x602000000fa8 is located 8 bytes to the left of 10-byte region [0x602000000fb0,0x602000000fba)
allocated by thread T0 here:
    #0 0x4dc6fc in malloc /scratch/llvm/clang-4/xenial/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:66:3
    #1 0xa3684f in Perl_safesysmalloc /root/fuzz/perl5/perl-new/util.c:153:21
    #2 0xc03d09 in Perl_sv_grow /root/fuzz/perl5/perl-new/sv.c:1603:17
    #3 0xc3a983 in Perl_sv_setpvn /root/fuzz/perl5/perl-new/sv.c:5000:12
    #4 0xd0d99d in Perl_newSVpvn /root/fuzz/perl5/perl-new/sv.c:9395:5
    #5 0x6f658b in Perl_lex_start /root/fuzz/perl5/perl-new/toke.c:762:20
    #6 0x631e15 in S_parse_body /root/fuzz/perl5/perl-new/perl.c:2403:5
    #7 0x627a05 in perl_parse /root/fuzz/perl5/perl-new/perl.c:1732:2
    #8 0x5095f8 in main /root/fuzz/perl5/perl-new/perlmain.c:121:18
    #9 0x7f8e7d94782f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-buffer-overflow /scratch/llvm/clang-4/xenial/final/llvm.src/projects/compiler-rt/lib/asan/asan_interceptors.cc:453:3 in __asan_memcpy
Shadow bytes around the buggy address:
  0x0c047fff81a0: fa fa 00 01 fa fa 00 02 fa fa 06 fa fa fa 00 02
  0x0c047fff81b0: fa fa 05 fa fa fa 00 02 fa fa 00 fa fa fa 00 07
  0x0c047fff81c0: fa fa 00 01 fa fa 00 05 fa fa 00 00 fa fa 00 02
  0x0c047fff81d0: fa fa 00 02 fa fa 00 fa fa fa 00 02 fa fa 00 fa
  0x0c047fff81e0: fa fa 00 00 fa fa 02 fa fa fa 00 04 fa fa 07 fa
=>0x0c047fff81f0: fa fa 00 04 fa[fa]00 02 fa fa 00 02 fa fa 00 02
  0x0c047fff8200: fa fa 00 02 fa fa fd fd fa fa fa fa fa fa fa fa
  0x0c047fff8210: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8220: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8230: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8240: fa fa fa fa fa fa fa fa fa fa fa fa fa fa 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
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==1380==ABORTING


toke.c:5161:9:

        len = UTF ? Perl_utf8_length(aTHX_ (U8 *) PL_linestart, (U8 *) s) : (STRLEN) (s - PL_linestart);
        if (len > UNRECOGNIZED_PRECEDE_COUNT) {
            d = UTF ? (char *) utf8_hop_back((U8 *) s, -UNRECOGNIZED_PRECEDE_COUNT, (U8 *)PL_linestart) : s - UNRECOGNIZED_PRECEDE_COUNT;
        } else {
            d = PL_linestart;
        }



if `UTF` is equal to false, the `len` will be `(STRLEN) (s - PL_linestart)`. Due to `s` is less than `PL_linestart`, the difference is negative. `len` is huge and a heap-buffer-overflow occurs.

Best regards,

Nguyễn Hồng Quang

Download a.pl
text/x-perl 5b

Message body is not shown because sender requested not to inline it.

RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 799b
On Tue, 15 Aug 2017 19:44:10 -0700, quangnh89@gmail.com wrote: Show quoted text
> The attached script triggers a heap-buffer-overflow Perl_sv_vcatpvfn > (sv.c:13353:17). This was found with ASAN. > > ================================================================= > ==1380==ERROR: AddressSanitizer: heap-buffer-overflow on address > 0x602000000fa8 at pc 0x0000004c6337 bp 0x7ffc3713f3f0 sp > 0x7ffc3713eba0 > READ of size 10 at 0x602000000fa8 thread T0 > #0 0x4c6336 in __asan_memcpy > /scratch/llvm/clang-4/xenial/final/llvm.src/projects/compiler- > rt/lib/asan/asan_interceptors.cc:453:3 > #1 0xd46667 in Perl_sv_vcatpvfn_flags > /root/fuzz/perl5/perl-new/sv.c:13353:17
This is a duplicate of #131793 and is fixed by my patch there. As with #131793 this isn't a security issue and is now public. Tony
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 894b
On Wed, 16 Aug 2017 17:58:23 -0700, tonyc wrote: Show quoted text
> On Tue, 15 Aug 2017 19:44:10 -0700, quangnh89@gmail.com wrote:
> > The attached script triggers a heap-buffer-overflow Perl_sv_vcatpvfn > > (sv.c:13353:17). This was found with ASAN. > > > > ================================================================= > > ==1380==ERROR: AddressSanitizer: heap-buffer-overflow on address > > 0x602000000fa8 at pc 0x0000004c6337 bp 0x7ffc3713f3f0 sp > > 0x7ffc3713eba0 > > READ of size 10 at 0x602000000fa8 thread T0 > > #0 0x4c6336 in __asan_memcpy > > /scratch/llvm/clang-4/xenial/final/llvm.src/projects/compiler- > > rt/lib/asan/asan_interceptors.cc:453:3 > > #1 0xd46667 in Perl_sv_vcatpvfn_flags > > /root/fuzz/perl5/perl-new/sv.c:13353:17
> > This is a duplicate of #131793 and is fixed by my patch there.
Which I've now applied to blead as 36000cd1c47863d8412b285701db7232dd450239. Tony
Date: Tue, 22 Aug 2017 14:26:58 +0200
From: "Vincent Pit (VPIT)" <perl [...] profvince.com>
Subject: Re: [perl #131904] integer overflow leads to heap overflow in php5
To: perl5-security-report [...] perl.org
Download (untitled) / with headers
text/plain 519b
Show quoted text
> > toke.c:5161:9: > > len = UTF ? Perl_utf8_length(aTHX_ (U8 *) PL_linestart, (U8 *) s) : > (STRLEN) (s - PL_linestart); > if (len > UNRECOGNIZED_PRECEDE_COUNT) { > d = UTF ? (char *) utf8_hop_back((U8 *) s, > -UNRECOGNIZED_PRECEDE_COUNT, (U8 *)PL_linestart) : s - > UNRECOGNIZED_PRECEDE_COUNT; > } else { > d = PL_linestart; > } >
This has probably been fixed by commit 36000cd1c, which was included in yesterday's release of perl 5.27.3. Vincent
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 582b
On Tue, 22 Aug 2017 05:42:52 -0700, perl@profvince.com wrote: Show quoted text
>
> > > > toke.c:5161:9: > > > > len = UTF ? Perl_utf8_length(aTHX_ (U8 *) PL_linestart, (U8 *) s) : > > (STRLEN) (s - PL_linestart); > > if (len > UNRECOGNIZED_PRECEDE_COUNT) { > > d = UTF ? (char *) utf8_hop_back((U8 *) s, > > -UNRECOGNIZED_PRECEDE_COUNT, (U8 *)PL_linestart) : s - > > UNRECOGNIZED_PRECEDE_COUNT; > > } else { > > d = PL_linestart; > > } > >
> > This has probably been fixed by commit 36000cd1c, which was included > in > yesterday's release of perl 5.27.3.
Yes, I forgot to close it. Tony


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