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

PerlIO::via modules exhibit buffer leakage when READ doesn't touch $buffer #13304

Open
p5pRT opened this issue Sep 23, 2013 · 7 comments
Open

Comments

@p5pRT
Copy link

p5pRT commented Sep 23, 2013

Migrated from rt.perl.org#119961 (status was 'open')

Searchable as RT119961$

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2013

From @kentfredric

Created by @kentfredric

I discovered accidentally, that if you're writing a PerlIO layer with
PerlIO​::via, that you can
accidentally leak the contents of the previously loaded file to calling
code.

In the given example on my machine, the contents of XSLoader.pm are spewed
to my terminal with arbitrary binary data around it, suggesting to me some
kind of memory leakage/buffer overflow.

----
use strict;
use warnings;
use utf8;

{
  package PerlIO​::via​::Bug;

  sub PUSHED {
  return bless {}, $_[0];
  }
  sub READ {
  return $_[2];
  }
}

open my $fh, '<​:raw​:via(Bug)', '/dev/null' or die "Cannot open, $! $?";

read $fh, ( my $buf ), 1024;

print $buf;

---

The failure still occurs without any of the aforementioned "use" statements,
  just 'use utf8' is convenient for me, because it somehow causes the
contents of "XSLoader.pm"
  to be dumped, which is a clear indication of error.

different values of "use" will result in different output.

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl 5.19.3:

Configured by kent at Thu Sep  5 10:45:54 NZST 2013.

Summary of my perl5 (revision 5 version 19 subversion 3) configuration:

  Platform:
    osname=linux, osvers=3.10.9-gentoo, archname=x86_64-linux
    uname='linux katipo2 3.10.9-gentoo #40 smp tue aug 27 01:15:13 nzst
2013 x86_64 intel(r) core(tm) i5-2410m cpu @ 2.30ghz genuineintel gnulinux '
    config_args='-de -Dprefix=/home/kent/perl5/perlbrew/perls/perl-5.19.3
-Dusedevel -Aeval:scriptdir=/home/kent/perl5/perlbrew/perls/perl-5.19.3/bin'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2',
    cppflags='-fno-strict-aliasing -pipe -fstack-protector'
    ccversion='', gccversion='4.7.2', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -fstack-protector'
    libpth=/lib/../lib64 /usr/lib/../lib64 /lib /usr/lib /lib64 /usr/lib64
    libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
    libc=/lib/libc-2.15.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.15'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -fstack-protector'



@INC for perl 5.19.3:

/home/kent/perl5/perlbrew/perls/perl-5.19.3/lib/site_perl/5.19.3/x86_64-linux
    /home/kent/perl5/perlbrew/perls/perl-5.19.3/lib/site_perl/5.19.3
    /home/kent/perl5/perlbrew/perls/perl-5.19.3/lib/5.19.3/x86_64-linux
    /home/kent/perl5/perlbrew/perls/perl-5.19.3/lib/5.19.3
    .


Environment for perl 5.19.3:
    HOME=/home/kent
    LANG (unset)
    LANGUAGE (unset)
    LC_CTYPE=en_NZ.UTF8
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)

PATH=/home/kent/perl5/perlbrew/bin:/home/kent/perl5/perlbrew/perls/perl-5.19.3/bin:/home/kent/.perl6/2013.04/bin:/home/kent/.gem/ruby/1.8/bin/:/usr/local/bin:/usr/bin:/bin:/opt/bin:/usr/x86_64-pc-linux-gnu/gcc-bin/4.7.2:/usr/games/bin
    PERLBREW_BASHRC_VERSION=0.61
    PERLBREW_HOME=/home/kent/.perlbrew
    PERLBREW_MANPATH=/home/kent/perl5/perlbrew/perls/perl-5.19.3/man

PERLBREW_PATH=/home/kent/perl5/perlbrew/bin:/home/kent/perl5/perlbrew/perls/perl-5.19.3/bin
    PERLBREW_PERL=perl-5.19.3
    PERLBREW_ROOT=/home/kent/perl5/perlbrew
    PERLBREW_VERSION=0.61
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2013

From @kentfredric

I should also note, even assigning to $buffer doesn't help you.

It just assumes you're not lying when you return $length

So as long as $length > length($buffer), corruption will be seen.

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2013

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

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2013

From @kentfredric

More, if you change the return to a fixed number such as 1024, and then
invoke the read as simply 'read $fh, ( my $buf ), 1', it invokes a
GLIBC corruption​:

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2013

From @kentfredric

via_io_stack.pl

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2013

From @kentfredric

stackdump

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2013

From @Leont

On Mon Sep 23 08​:54​:16 2013, kentfredric@​gmail.com wrote​:

I discovered accidentally, that if you're writing a PerlIO layer with
PerlIO​::via, that you can
accidentally leak the contents of the previously loaded file to
calling
code.

In the given example on my machine, the contents of XSLoader.pm are
spewed
to my terminal with arbitrary binary data around it, suggesting to me
some
kind of memory leakage/buffer overflow.

----
use strict;
use warnings;
use utf8;

{
package PerlIO​::via​::Bug;

sub PUSHED {
return bless {}, $_[0];
}
sub READ {
return $_[2];
}
}

open my $fh, '<​:raw​:via(Bug)', '/dev/null' or die "Cannot open, $!
$?";

read $fh, ( my $buf ), 1024;

print $buf;

---

The failure still occurs without any of the aforementioned "use"
statements,
just 'use utf8' is convenient for me, because it somehow causes
the
contents of "XSLoader.pm"
to be dumped, which is a clear indication of error.

different values of "use" will result in different output.

The bug is in PerlIOVia_read. It's doing a two things wrong​:
1) It does not ensure the buffer is in fact a string before using SvPVX.
2) It does not check if the length is in any way sane.

Leon

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

2 participants