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

multi-arg open() error leaks #16118

Open
p5pRT opened this issue Aug 19, 2017 · 4 comments
Open

multi-arg open() error leaks #16118

p5pRT opened this issue Aug 19, 2017 · 4 comments

Comments

@p5pRT
Copy link

p5pRT commented Aug 19, 2017

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

Searchable as RT131929$

@p5pRT
Copy link
Author

p5pRT commented Aug 19, 2017

From zefram@fysh.org

Created by zefram@fysh.org

If an open() operation specifies a list of layers, and has more than one
argument, and the layer handling the opening can't accept more than one
argument, then the operation leaks​:

$ perl -lwe 'for(0..2) { system("ps u $$"); for(0..9999) { eval { open($f, ">​:scalar", \$a, 2) } } }'
Name "main​::f" used only once​: possible typo at -e line 1.
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
zefram 10526 0.0 0.0 22268 3268 pts/3 S+ 03​:59 0​:00 perl -lwe for(0
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
zefram 10526 0.0 0.0 26308 6076 pts/3 S+ 03​:59 0​:00 perl -lwe for(0
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
zefram 10526 0.0 0.0 28156 7964 pts/3 S+ 03​:59 0​:00 perl -lwe for(0

The problem is that the argument count error is signalled as an exception
(unlike most opening errors) but explicit freeing of the layer list is
required (in PerlIO_openn()). I'm not sure which part of this is the
bug​: perhaps the error ought to be signalled through errno, or perhaps
the code branch that croaks should explicitly free the layer list, or
perhaps the operation should be made robust against all exceptions by
using some arrangement like mortalisation to free the layer list.

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl 5.27.2:

Configured by zefram at Thu Jul 20 23:32:33 BST 2017.

Summary of my perl5 (revision 5 version 27 subversion 2) configuration:
   
  Platform:
    osname=linux
    osvers=3.16.0-4-amd64
    archname=x86_64-linux-thread-multi
    uname='linux barba.rous.org 3.16.0-4-amd64 #1 smp debian 3.16.43-2+deb8u2 (2017-06-26) x86_64 gnulinux '
    config_args='-des -Dprefix=/home/zefram/usr/perl/perl_install/perl-5.27.2-i64-f52 -Duselargefiles -Dusethreads -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dusedevel -Uversiononly -Ui_db'
    hint=recommended
    useposix=true
    d_sigaction=define
    useithreads=define
    usemultiplicity=define
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    default_inc_excludes_dot=define
    bincompat5005=undef
  Compiler:
    cc='cc'
    ccflags ='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'
    optimize='-O2'
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
    ccversion=''
    gccversion='4.9.2'
    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='cc'
    ldflags =' -fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib/gcc/x86_64-linux-gnu/4.9/include-fixed /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 -ldb -ldl -lm -lcrypt -lutil -lc
    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    libc=libc-2.19.so
    so=so
    useshrplib=true
    libperl=libperl.so
    gnulibc_version='2.19'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs
    dlext=so
    d_dlsymun=undef
    ccdlflags='-Wl,-E -Wl,-rpath,/home/zefram/usr/perl/perl_install/perl-5.27.2-i64-f52/lib/5.27.2/x86_64-linux-thread-multi/CORE'
    cccdlflags='-fPIC'
    lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong'



@INC for perl 5.27.2:
    /home/zefram/usr/perl/perl_install/perl-5.27.2-i64-f52/lib/site_perl/5.27.2/x86_64-linux-thread-multi
    /home/zefram/usr/perl/perl_install/perl-5.27.2-i64-f52/lib/site_perl/5.27.2
    /home/zefram/usr/perl/perl_install/perl-5.27.2-i64-f52/lib/5.27.2/x86_64-linux-thread-multi
    /home/zefram/usr/perl/perl_install/perl-5.27.2-i64-f52/lib/5.27.2


Environment for perl 5.27.2:
    HOME=/home/zefram
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/zefram/usr/perl/perl_install/perl-5.27.2-i64-f52/bin:/home/zefram/usr/perl/util:/home/zefram/pub/x86_64-unknown-linux-gnu/bin:/home/zefram/pub/common/bin:/usr/bin:/bin:/usr/local/bin:/usr/games
    PERLDOC=-oman
    PERL_BADLANG (unset)
    SHELL=/usr/bin/zsh

@p5pRT
Copy link
Author

p5pRT commented Aug 23, 2017

From @jkeenan

On Sat, 19 Aug 2017 03​:07​:58 GMT, zefram@​fysh.org wrote​:

This is a bug report for perl from zefram@​fysh.org,
generated with the help of perlbug 1.40 running under perl 5.27.2.

-----------------------------------------------------------------
[Please describe your issue here]

If an open() operation specifies a list of layers, and has more than
one
argument, and the layer handling the opening can't accept more than
one
argument, then the operation leaks​:

$ perl -lwe 'for(0..2) { system("ps u $$"); for(0..9999) { eval {
open($f, ">​:scalar", \$a, 2) } } }'
Name "main​::f" used only once​: possible typo at -e line 1.
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME
COMMAND
zefram 10526 0.0 0.0 22268 3268 pts/3 S+ 03​:59 0​:00 perl
-lwe for(0
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME
COMMAND
zefram 10526 0.0 0.0 26308 6076 pts/3 S+ 03​:59 0​:00 perl
-lwe for(0
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME
COMMAND
zefram 10526 0.0 0.0 28156 7964 pts/3 S+ 03​:59 0​:00 perl
-lwe for(0

The problem is that the argument count error is signalled as an
exception
(unlike most opening errors) but explicit freeing of the layer list is
required (in PerlIO_openn()). I'm not sure which part of this is the
bug​: perhaps the error ought to be signalled through errno, or perhaps
the code branch that croaks should explicitly free the layer list, or
perhaps the operation should be made robust against all exceptions by
using some arrangement like mortalisation to free the layer list.

Bug appears to have been introduced somewhere in perl-5.8.

#####
$ perlbrew use perl-5.6.2
$ perl -v | head -2 | tail -1
This is perl, v5.6.2 built for x86_64-linux
$ perl -lwe 'for(0..2) { system("ps u $$"); for(0..9999) { eval { open($f, ">​:scalar", \$a, 2) } } }'
Name "main​::a" used only once​: possible typo at -e line 1.
Name "main​::f" used only once​: possible typo at -e line 1.
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
jkeenan 26442 0.0 0.0 17460 3088 pts/31 S+ 21​:50 0​:00 perl -lwe for(0..2) { system("ps
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
jkeenan 26442 0.0 0.0 17460 3088 pts/31 S+ 21​:50 0​:00 perl -lwe for(0..2) { system("ps
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
jkeenan 26442 0.0 0.0 17460 3088 pts/31 S+ 21​:50 0​:00 perl -lwe for(0..2) { system("ps
#####
$ perlbrew use perl-5.8.9
$ perl -v | head -2 | tail -1
This is perl, v5.8.9 built for x86_64-linux
$ perl -lwe 'for(0..2) { system("ps u $$"); for(0..9999) { eval { open($f, ">​:scalar", \$a, 2) } } }'
Name "main​::a" used only once​: possible typo at -e line 1.
Name "main​::f" used only once​: possible typo at -e line 1.
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
jkeenan 26553 0.0 0.0 17796 3008 pts/31 S+ 21​:52 0​:00 perl -lwe for(0..2) { system("ps
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
jkeenan 26553 0.0 0.1 21972 5320 pts/31 S+ 21​:52 0​:00 perl -lwe for(0..2) { system("ps
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
jkeenan 26553 0.0 0.1 23952 7412 pts/31 S+ 21​:52 0​:00 perl -lwe for(0..2) { system("ps
#####

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Aug 23, 2017

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

@p5pRT
Copy link
Author

p5pRT commented Aug 23, 2017

From zefram@fysh.org

James E Keenan via RT wrote​:

Bug appears to have been introduced somewhere in perl-5.8.

The bug was present in the earliest released version to have that error
message (5.7.3). Earlier versions of PerlIO layers, back to 5.7.1,
are vulnerable to an exception happening in that area, such as in a
layer's open method, but don't have that particular way of generating
an exception. 5.6 doesn't have PerlIO layers.

-zefram

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants