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_pp_split (pp.c:6145) #15749

Closed
p5pRT opened this issue Dec 4, 2016 · 12 comments
Closed

heap-buffer-overflow Perl_pp_split (pp.c:6145) #15749

p5pRT opened this issue Dec 4, 2016 · 12 comments

Comments

@p5pRT
Copy link

p5pRT commented Dec 4, 2016

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

Searchable as RT130262$

@p5pRT
Copy link
Author

p5pRT commented Dec 4, 2016

From @geeknik

Triggered with Perl v5.25.7-26-g7332835.

./perl -e 'map{int"";split//.0>60for"0000000000000000"}split//
for"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"'

==8844==ERROR​: AddressSanitizer​: heap-buffer-overflow on address
0x61d00001dfa8 at pc 0x000000a1e147 bp 0x7ffdd386dc50 sp 0x7ffdd386dc48
WRITE of size 8 at 0x61d00001dfa8 thread T0
  #0 0xa1e146 in Perl_pp_split /root/perl/pp.c​:6145​:5
  #1 0x7f63bb in Perl_runops_debug /root/perl/dump.c​:2260​:23
  #2 0x5a06c3 in S_run_body /root/perl/perl.c​:2526​:2
  #3 0x5a06c3 in perl_run /root/perl/perl.c​:2449
  #4 0x4de6cd in main /root/perl/perlmain.c​:123​:9
  #5 0x7f37e05a4b44 in __libc_start_main
/build/glibc-daoqzt/glibc-2.19/csu/libc-start.c​:287
  #6 0x4de33c in _start (/root/perl/perl+0x4de33c)

0x61d00001dfa8 is located 0 bytes to the right of 2344-byte region
[0x61d00001d680,0x61d00001dfa8)
allocated by thread T0 here​:
  #0 0x4c0fae in realloc (/root/perl/perl+0x4c0fae)
  #1 0x7fa916 in Perl_safesysrealloc /root/perl/util.c​:274​:18

SUMMARY​: AddressSanitizer​: heap-buffer-overflow /root/perl/pp.c​:6145
Perl_pp_split
Shadow bytes around the buggy address​:
  0x0c3a7fffbba0​: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c3a7fffbbb0​: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c3a7fffbbc0​: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c3a7fffbbd0​: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c3a7fffbbe0​: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c3a7fffbbf0​: 00 00 00 00 00[fa]fa fa fa fa fa fa fa fa fa fa
  0x0c3a7fffbc00​: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c3a7fffbc10​: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c3a7fffbc20​: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c3a7fffbc30​: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c3a7fffbc40​: 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
  ASan internal​: fe
==8844==ABORTING

@p5pRT
Copy link
Author

p5pRT commented Dec 5, 2016

From @tonycoz

On Sun, 04 Dec 2016 13​:56​:12 -0800, brian.carpenter@​gmail.com wrote​:

Triggered with Perl v5.25.7-26-g7332835.

./perl -e 'map{int"";split//.0>60for"0000000000000000"}split//
for"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"'

From valgrind​:

==26813== Invalid write of size 8
==26813== at 0x64602D​: Perl_pp_split (pp.c​:6145)
==26813== by 0x556DAA​: Perl_runops_debug (dump.c​:2260)
==26813== by 0x460EB1​: S_run_body (perl.c​:2526)
==26813== by 0x460494​: perl_run (perl.c​:2449)
==26813== by 0x41EFDD​: main (perlmain.c​:123)
==26813== Address 0x5f86b88 is 0 bytes after a block of size 2,344 alloc'd
==26813== at 0x4C2AF2E​: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26813== by 0x5586EE​: Perl_safesysrealloc (util.c​:274)
==26813== by 0x59A2AF​: Perl_av_extend_guts (av.c​:163)
==26813== by 0x599FDB​: Perl_av_extend (av.c​:80)
==26813== by 0x64AE56​: Perl_stack_grow (scope.c​:57)
==26813== by 0x644D6E​: Perl_pp_split (pp.c​:5913)
==26813== by 0x556DAA​: Perl_runops_debug (dump.c​:2260)
==26813== by 0x460EB1​: S_run_body (perl.c​:2526)
==26813== by 0x460494​: perl_run (perl.c​:2449)
==26813== by 0x41EFDD​: main (perlmain.c​:123)

This is a stack overflow from the final​:

  PUSHi(iters);

in pp_split.

An attacker has no control over the value stored, and it's always stored
at the end of the stack. I don't believe this is a security issue.

Fixed by the attached.

Tony

@p5pRT
Copy link
Author

p5pRT commented Dec 5, 2016

From @tonycoz

0001-perl-130262-split-scalar-context-stack-overflow-fix.patch
From 071b4693c6bfb5496be82ae23e136b7f58c7e86d Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Mon, 5 Dec 2016 11:48:14 +1100
Subject: (perl #130262) split scalar context stack overflow fix

pp_split didn't ensure there was space for its return value
in scalar context.
---
 pp.c         | 2 +-
 t/op/split.t | 6 +++++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/pp.c b/pp.c
index b198b47..737111a 100644
--- a/pp.c
+++ b/pp.c
@@ -6142,7 +6142,7 @@ PP(pp_split)
     }
 
     GETTARGET;
-    PUSHi(iters);
+    XPUSHi(iters);
     RETURN;
 }
 
diff --git a/t/op/split.t b/t/op/split.t
index ceaea00..6d1ed25 100644
--- a/t/op/split.t
+++ b/t/op/split.t
@@ -7,7 +7,7 @@ BEGIN {
     set_up_inc('../lib');
 }
 
-plan tests => 161;
+plan tests => 162;
 
 $FS = ':';
 
@@ -621,3 +621,7 @@ is "@a", '1 2 3', 'assignment to split-to-array (stacked)';
     ok eval { $a[0] = 'a'; 1; }, "array split filling AvARRAY: assign 0";
     is "@a", "a b", "array split filling AvARRAY: result";
 }
+
+fresh_perl_is(<<'CODE', '', {}, "scalar split stack overflow");
+map{int"";split//.0>60for"0000000000000000"}split// for"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+CODE
-- 
2.1.4

@p5pRT
Copy link
Author

p5pRT commented Dec 5, 2016

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

@p5pRT
Copy link
Author

p5pRT commented Jan 14, 2017

From @dur-randir

Created by @dur-randir

While fuzzing perl v5.25.8-207-gcbe2fc5001 built with afl and run
under libdislocator, I found the following program

@​0=s//000000000000000000000000000000000000000000000000000000000000000000000000000000000\000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000000000000/;
s//$_"f0/g;
split /f/;

to perform an access outside of an allocated memory slot. ASAN diagnostics are​:

% ./perl /tmp/0002

==18293==ERROR​: AddressSanitizer​: heap-buffer-overflow on address
0x62400000bed8 at pc 0x000000a93240 bp 0x7fff8c21d070 sp
0x7fff8c21d068
WRITE of size 8 at 0x62400000bed8 thread T0
  #0 0xa9323f in Perl_pp_split /home/afl/perl-git/pp.c​:6145​:5
  #1 0x847e81 in Perl_runops_debug /home/afl/perl-git/dump.c​:2260​:23
  #2 0x5f0305 in S_run_body /home/afl/perl-git/perl.c​:2528​:2
  #3 0x5f0305 in perl_run /home/afl/perl-git/perl.c​:2451
  #4 0x522402 in main /home/afl/perl-git/perlmain.c​:123​:9
  #5 0x7ff27fcd02b0 in __libc_start_main
(/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
  #6 0x43ace9 in _start (/home/afl/perl-git/perl+0x43ace9)

0x62400000bed8 is located 0 bytes to the right of 7640-byte region
[0x62400000a100,0x62400000bed8)
allocated by thread T0 here​:
  #0 0x4eaa10 in realloc (/home/afl/perl-git/perl+0x4eaa10)
  #1 0x84cab6 in Perl_safesysrealloc /home/afl/perl-git/util.c​:274​:18

SUMMARY​: AddressSanitizer​: heap-buffer-overflow
/home/afl/perl-git/pp.c​:6145​:5 in Perl_pp_split

GDB reports the following program state​:
(gdb) bt
#0 0x00007f165a096d39 in Perl_pp_split () at pp.c​:6145
#1 0x00007f1659f99b57 in Perl_runops_debug () at dump.c​:2260
#2 0x00007f1659e940fd in S_run_body (oldscope=1) at perl.c​:2528
#3 0x00007f1659e9367b in perl_run (my_perl=0x7f165a47afff) at perl.c​:2451
#4 0x00007f1659e4ed3e in main (argc=2, argv=0x7fffd50da758,
env=0x7fffd50da770) at perlmain.c​:123
(gdb) f 0
#0 0x00007f165a096d39 in Perl_pp_split () at pp.c​:6145
6145 PUSHi(iters);
(gdb) info locals
sp = 0x7f1657c50000
targ = 0x7f1658859fb8
ary = 0x0
limit = 100497
__PRETTY_FUNCTION__ = "Perl_pp_split"
sv = 0x7f1658859f70
len = 1
s = 0x7f165821a25e "0"
do_utf8 = false
strend = 0x7f165821a25f ""
pm = 0x7f165854ef50
rx = 0x7f1658859f28
dstr = 0x7f1657af48f8
m = 0x7f165821a25f ""
iters = 954
slen = 101439
maxiters = 101449
trailing_empty = 0
orig = 0x7f1658201620 '0' <repeats 81 times>
origlimit = 0
realarray = 0
base = 0
gimme = 1 '\001'
gimme_scalar = false
oldsave = 0
make_mortal = 524288
multiline = false
mg = 0x0

Perl Info

Flags:
    category=core
    severity=high

Site configuration information for perl 5.25.9:

Configured by root at Sat Jan 14 02:25:05 MSK 2017.

Summary of my perl5 (revision 5 version 25 subversion 9) configuration:
  Commit id: cbe2fc5001aa59cdc73e04cc35e097a2ecfbeec0
  Platform:
    osname=linux
    osvers=3.16.0-4-amd64
    archname=x86_64-linux
    uname='linux dorothy 3.16.0-4-amd64 #1 smp debian 3.16.36-1+deb8u2
(2016-10-19) x86_64 gnulinux '
    config_args='-des -Dusedevel -DDEBUGGING -Dcc=afl-clang-fast
-Doptimize=-O0 -g -ggdb3'
    hint=recommended
    useposix=true
    d_sigaction=define
    useithreads=undef
    usemultiplicity=undef
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    bincompat5005=undef
  Compiler:
    cc='afl-clang-fast'
    ccflags ='-DDEBUGGING -fno-strict-aliasing -pipe
-fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'
    optimize='-O0 -g -ggdb3'
    cppflags='-DDEBUGGING -fno-strict-aliasing -pipe
-fstack-protector-strong -I/usr/local/include'
    ccversion=''
    gccversion='4.2.1 Compatible Clang 3.9.1 (tags/RELEASE_391/rc2)'
    gccosandvers=''
    intsize=4
    longsize=8
    ptrsize=8
    doublesize=8
    byteorder=12345678
    doublekind=3
    d_longlong=define
    longlongsize=8
    d_longdbl=define
    longdblsize=16
    longdblkind=3
    ivtype='long'
    ivsize=8
    nvtype='double'
    nvsize=8
    Off_t='off_t'
    lseeksize=8
    alignbytes=8
    prototype=define
  Linker and Libraries:
    ld='afl-clang-fast'
    ldflags =' -fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib/llvm-3.9/bin/../lib/clang/3.9.1/lib
/usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu
/lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib
    libs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    libc=libc-2.24.so
    so=so
    useshrplib=false
    libperl=libperl.a
    gnulibc_version='2.24'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs
    dlext=so
    d_dlsymun=undef
    ccdlflags='-Wl,-E'
    cccdlflags='-fPIC'
    lddlflags='-shared -O0 -g -ggdb3 -L/usr/local/lib -fstack-protector-strong'



@INC for perl 5.25.9:
    lib
    /usr/local/lib/perl5/site_perl/5.25.9/x86_64-linux
    /usr/local/lib/perl5/site_perl/5.25.9
    /usr/local/lib/perl5/5.25.9/x86_64-linux
    /usr/local/lib/perl5/5.25.9


Environment for perl 5.25.9:
    HOME=/home/afl
    LANG=en_US.UTF-8
    LANGUAGE=en_US:en
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/afl/perlbrew/bin:/home/afl/perlbrew/perls/perl-5.22.1/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
    PERLBREW_BASHRC_VERSION=0.78
    PERLBREW_HOME=/home/afl/.perlbrew
    PERLBREW_MANPATH=/home/afl/perlbrew/perls/perl-5.22.1/man
    PERLBREW_PATH=/home/afl/perlbrew/bin:/home/afl/perlbrew/perls/perl-5.22.1/bin
    PERLBREW_PERL=perl-5.22.1
    PERLBREW_ROOT=/home/afl/perlbrew
    PERLBREW_VERSION=0.78
    PERL_BADLANG (unset)
    SHELL=/usr/bin/zsh

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2017

From @tonycoz

On Sun, 04 Dec 2016 16​:58​:42 -0800, tonyc wrote​:

On Sun, 04 Dec 2016 13​:56​:12 -0800, brian.carpenter@​gmail.com wrote​:

Triggered with Perl v5.25.7-26-g7332835.

./perl -e 'map{int"";split//.0>60for"0000000000000000"}split//
for"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"'

From valgrind​:

==26813== Invalid write of size 8
==26813== at 0x64602D​: Perl_pp_split (pp.c​:6145)
==26813== by 0x556DAA​: Perl_runops_debug (dump.c​:2260)
==26813== by 0x460EB1​: S_run_body (perl.c​:2526)
==26813== by 0x460494​: perl_run (perl.c​:2449)
==26813== by 0x41EFDD​: main (perlmain.c​:123)
==26813== Address 0x5f86b88 is 0 bytes after a block of size 2,344
alloc'd
==26813== at 0x4C2AF2E​: realloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26813== by 0x5586EE​: Perl_safesysrealloc (util.c​:274)
==26813== by 0x59A2AF​: Perl_av_extend_guts (av.c​:163)
==26813== by 0x599FDB​: Perl_av_extend (av.c​:80)
==26813== by 0x64AE56​: Perl_stack_grow (scope.c​:57)
==26813== by 0x644D6E​: Perl_pp_split (pp.c​:5913)
==26813== by 0x556DAA​: Perl_runops_debug (dump.c​:2260)
==26813== by 0x460EB1​: S_run_body (perl.c​:2526)
==26813== by 0x460494​: perl_run (perl.c​:2449)
==26813== by 0x41EFDD​: main (perlmain.c​:123)

This is a stack overflow from the final​:

PUSHi(iters);

in pp_split.

An attacker has no control over the value stored, and it's always
stored
at the end of the stack. I don't believe this is a security issue.

No comments, so treating as a non-security issue, and moved to the perl5
queue.

Fixed by the attached.

Applied as 02c161e (with some noise).

Tony

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2017

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

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2017

From @tonycoz

On Sat, 14 Jan 2017 14​:02​:01 -0800, randir wrote​:

[Please describe your issue here]

While fuzzing perl v5.25.8-207-gcbe2fc5001 built with afl and run
under libdislocator, I found the following program

@​0=s//000000000000000000000000000000000000000000000000000000000000000000000000000000000\000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000000000000/;
s//$_"f0/g;
split /f/;

to perform an access outside of an allocated memory slot. ASAN
diagnostics are​:

This looks like a duplicate of #130262, and my fix from that seems to fix this issue.

As with that I don't think this is a security issue.

Tony

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2017

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

@p5pRT
Copy link
Author

p5pRT commented Feb 1, 2017

From @tonycoz

On Sun, 15 Jan 2017 21​:40​:27 -0800, tonyc wrote​:

On Sat, 14 Jan 2017 14​:02​:01 -0800, randir wrote​:

[Please describe your issue here]

While fuzzing perl v5.25.8-207-gcbe2fc5001 built with afl and run
under libdislocator, I found the following program

@​0=s//000000000000000000000000000000000000000000000000000000000000000000000000000000000\000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000000000000/;
s//$_"f0/g;
split /f/;

to perform an access outside of an allocated memory slot. ASAN
diagnostics are​:

This looks like a duplicate of #130262, and my fix from that seems to
fix this issue.

As with that I don't think this is a security issue.

No dissent, so merging into 130262.

Tony

@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