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

interpreter crash with IO::Tee #9924

Closed
p5pRT opened this issue Oct 24, 2009 · 17 comments
Closed

interpreter crash with IO::Tee #9924

p5pRT opened this issue Oct 24, 2009 · 17 comments

Comments

@p5pRT
Copy link

p5pRT commented Oct 24, 2009

Migrated from rt.perl.org#70001 (status was 'rejected')

Searchable as RT70001$

@p5pRT
Copy link
Author

p5pRT commented Oct 24, 2009

From jackyf.devel@gmail.com

Created by jackyf.devel@gmail.com

The following code that uses Perl-only IO/Tee.pm from CPAN leads to Perl
interpreter crash​:

-8<-
use IO​::Tee;

open FOO, ">foo";
my $tee = IO​::Tee->new(\*STDOUT, \*FOO);
*STDOUT = $tee;
print $tee "foo\n";
->8-

The original report is here​: http​://bugs.debian.org/cgi-bin/bugreport.cgi?bug=158539.

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl 5.10.1:

Configured by Debian Project at Thu Oct  1 08:10:39 UTC 2009.

Summary of my perl5 (revision 5 version 10 subversion 1) configuration:
   
  Platform:
    osname=linux, osvers=2.6.31-trunk-amd64, archname=x86_64-linux-gnu-thread-multi
    uname='linux madeleine 2.6.31-trunk-amd64 #1 smp tue sep 22 22:33:08 eest 2009 x86_64 gnulinux '
    config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=x86_64-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.10 -Darchlib=/usr/lib/perl/5.10 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.10.1 -Dsitearch=/usr/local/lib/perl/5.10.1 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib -Dlibperl=libperl.so.5.10.1 -Dd_dosuid -des'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2 -g',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.3.4', 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 -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib /lib64 /usr/lib64
    libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
    perllibs=-ldl -lm -lpthread -lc -lcrypt
    libc=/lib/libc-2.9.so, so=so, useshrplib=true, libperl=libperl.so.5.10.1
    gnulibc_version='2.9'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -g -L/usr/local/lib -fstack-protector'

Locally applied patches:
    


@INC for perl 5.10.1:
    /etc/perl
    /usr/local/lib/perl/5.10.1
    /usr/local/share/perl/5.10.1
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.10
    /usr/share/perl/5.10
    /usr/local/lib/site_perl
    .


Environment for perl 5.10.1:
    HOME=/home/jackyf
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/local/bin:/usr/bin:/bin:/usr/games:/home/jackyf/bin
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Nov 11, 2009

@TJC - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Nov 11, 2009

From alecclews@gmail.com

Thank you for reporting this problem

Unfortunately IO​::Tee is not a part of Perl 10.1 core and so we cannot
address this issue.

Can I urge you to please raise this with the module maintainer. You can
raise a bug at http​://rt.cpan.org/Public/Bug/Report.html?Queue=IO-Tee

Many thanks

--
Alec Clews
Personal <alec.clews@​gmail.com> Melbourne, Australia.
Jabber​: alecclews@​jabber.org.au PGPKey ID​: 0x9BBBFC7C

@p5pRT
Copy link
Author

p5pRT commented Nov 11, 2009

alecclews@gmail.com - Status changed from 'open' to 'rejected'

@p5pRT
Copy link
Author

p5pRT commented Nov 11, 2009

From jackyf.devel@gmail.com

Срд. Ноя. 11 02​:48​:32 2009, alecthegeek писал​:

Unfortunately IO​::Tee is not a part of Perl 10.1 core and so we cannot
address this issue.
Um? So the interpreter crash with _Perl-only_ code is not a core
problem? I cannot agree with it.

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2012

From @jmdh

On Wed Nov 11 03​:27​:26 2009, jackyf wrote​:

Срд. Ноя. 11 02​:48​:32 2009, alecthegeek писал​:

Unfortunately IO​::Tee is not a part of Perl 10.1 core and so we
cannot
address this issue.
Um? So the interpreter crash with _Perl-only_ code is not a core
problem? I cannot agree with it.

Sounds like a reasonable concern; re-opening.

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2012

@jmdh - Status changed from 'rejected' to 'new'

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2012

From @jkeenan

On Sat Sep 01 06​:15​:54 2012, dom wrote​:

On Wed Nov 11 03​:27​:26 2009, jackyf wrote​:

Срд. Ноя. 11 02​:48​:32 2009, alecthegeek писал​:

Unfortunately IO​::Tee is not a part of Perl 10.1 core and so we
cannot
address this issue.
Um? So the interpreter crash with _Perl-only_ code is not a core
problem? I cannot agree with it.

Sounds like a reasonable concern; re-opening.

When you read both the original Debian bug ticket and try to debug the
OP's code sample, closing the ticket does not seem so unreasonable after
all.

The title of the original Debian ticket was, "segfault while doing odd
things with glob refs".
(http​://bugs.debian.org/cgi-bin/bugreport.cgi?bug=158539) So the person
who filed that ticket himself recognized that he was doing something
weird -- stunt programming, in effect, -- which was likely to produce
strange results. The stunt, of course, is to provide \*STDOUT as one of
the arguments to IO​::Tee​::new(), then to assign the resulting object
back into STDOUT's slot in the symbol table.

The original Debian poster went on to say, "I have no idea how
wide-ranging or serious this is, nor do I really understand what is
going on here."

Well, I myself don't claim to fully understand what is going on here.
But I can say that the problem is most likely in IO​::Tee, a module which
is not included in the Perl 5 core distribution and which hasn't been
updated in eleven years. Here is IO​::Tee's constructor​:

#####
sub new
{
  my $class = shift;
  my $self = gensym;
  @​{*$self} = map {
  ! ref($_) ? IO​::File->new($_)
  : ref($_) eq 'ARRAY' ? IO​::File->new(@​$_)
  : ref($_) eq 'GLOB' ? bless $_, 'IO​::Handle'
  : $_ or return undef } @​_;
  bless $self, $class;
  tie *$self, $class, $self;
  return $self;
}
#####

Are there tie/symbol-table experts who can say exactly what is going on
in the 'bless' and 'tie' lines there? (I tried to step through this
with the debugger and found it difficult to determine what $self and/or
*$self were at any given moment.)

Would this constructor and the subsequent PRINT method be reasonably
able to support the original poster's stunt?

#####
sub PRINT
{
  my $self = shift;
  my $ret = 1;
  foreach my $fh (@​$self) { undef $ret unless print $fh @​_ }
  return $ret;
}
#####

If someone has quick answers to this, we can keep this open. But if it
is not actually a problem with Perl, then I suggest we move it to
IO​::Tee's bug queue on CPAN and close it here.

Thank you very much.
Jim Keenan

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2012

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

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2012

From @iabyn

Well, I myself don't claim to fully understand what is going on here.
But I can say that the problem is most likely in IO​::Tee, a module which
is not included in the Perl 5 core distribution and which hasn't been
updated in eleven years. Here is IO​::Tee's constructor​:

Perl is crashing due to infinite recursion within the tie PRINT method.
ie PRINT keeps calling PRINT.

This is because within the PRINT method, when it prints to one of the
unldelying file handles, one of them happens to be STDOUT, which is now
also tied.

a tie method recursively triggering a tie method is one of the few areas
in perl that needs to use the C stack rather then the perl stack, so
crashaes with an unceremonious SEGV rather than the slighly more
ceremonious 'out of memory' error you;'d get if the perl stack gets
exhaused.

Not a lot we can really do to make it more graceful.

--
A power surge on the Bridge is rapidly and correctly diagnosed as a faulty
capacitor by the highly-trained and competent engineering staff.
  -- Things That Never Happen in "Star Trek" #9

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2012

From @cpansprout

On Sat Sep 01 13​:30​:15 2012, davem wrote​:

Well, I myself don't claim to fully understand what is going on here.
But I can say that the problem is most likely in IO​::Tee, a module which
is not included in the Perl 5 core distribution and which hasn't been
updated in eleven years. Here is IO​::Tee's constructor​:

Perl is crashing due to infinite recursion within the tie PRINT method.
ie PRINT keeps calling PRINT.

This is because within the PRINT method, when it prints to one of the
unldelying file handles, one of them happens to be STDOUT, which is now
also tied.

a tie method recursively triggering a tie method is one of the few areas
in perl that needs to use the C stack rather then the perl stack, so
crashaes with an unceremonious SEGV rather than the slighly more
ceremonious 'out of memory' error you;'d get if the perl stack gets
exhaused.

Not a lot we can really do to make it more graceful.

This is basically the same as #8861. The thing is, this actually worked
at one point, when the gv itself held the tie.

I think it might be possible to make this work again by disabling the
magic during the magic call.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2012

From @jkeenan

On Sat Sep 01 14​:45​:06 2012, sprout wrote​:

This is basically the same as #8861. The thing is, this actually worked
at one point, when the gv itself held the tie.

I think it might be possible to make this work again by disabling the
magic during the magic call.

Yes, but is it the sort of thing we would *want* to make work "again"?
Or would that just encourage stunt programming?

Thank you very much.
Jim Keenan

@p5pRT
Copy link
Author

p5pRT commented Sep 2, 2012

From @cpansprout

On Sat Sep 01 16​:04​:39 2012, jkeenan wrote​:

On Sat Sep 01 14​:45​:06 2012, sprout wrote​:

This is basically the same as #8861. The thing is, this actually worked
at one point, when the gv itself held the tie.

I think it might be possible to make this work again by disabling the
magic during the magic call.

Yes, but is it the sort of thing we would *want* to make work "again"?

In this particular example, I think I was wrong, and that it could never
have worked. This is merely similar to #8861, not the same, and not a
bug. (I’m closing it.) It cannot but result in infinite recursion.

Or would that just encourage stunt programming?

This particular example of stunt programming looks perfectly reasonable
to me (except that it doesn’t work). It feels a lot like​:

*foo = create_wrapper(\&foo);

But the fact that the whole glob is passed stops it from working.
*STDOUT{IO} probably works with IO​::Tee, but I haven’t tested it.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Sep 2, 2012

@cpansprout - Status changed from 'open' to 'rejected'

@p5pRT p5pRT closed this as completed Sep 2, 2012
@p5pRT
Copy link
Author

p5pRT commented Sep 2, 2012

From @jmdh

On Sat Sep 01 17​:22​:38 2012, sprout wrote​:

On Sat Sep 01 16​:04​:39 2012, jkeenan wrote​:

On Sat Sep 01 14​:45​:06 2012, sprout wrote​:

This is basically the same as #8861. The thing is, this actually
worked
at one point, when the gv itself held the tie.

I think it might be possible to make this work again by disabling
the
magic during the magic call.

Yes, but is it the sort of thing we would *want* to make work
"again"?

In this particular example, I think I was wrong, and that it could
never
have worked. This is merely similar to #8861, not the same, and not a
bug. (I’m closing it.) It cannot but result in infinite recursion.

Or would that just encourage stunt programming?

This particular example of stunt programming looks perfectly
reasonable
to me (except that it doesn’t work). It feels a lot like​:

*foo = create_wrapper(\&foo);

But the fact that the whole glob is passed stops it from working.
*STDOUT{IO} probably works with IO​::Tee, but I haven’t tested it.

Thanks for the analysis, all. I'll propagate this to the Debian bug
report.

Cheers,
Dominic.

@p5pRT
Copy link
Author

p5pRT commented Sep 3, 2012

From perl-diddler@tlinx.org

James E Keenan via RT wrote​:

Yes, but is it the sort of thing we would *want* to make work "again"?
Or would that just encourage stunt programming?


  If perl issued an error and exited gracefully, that would be one thing,
but perl is a programming 'environment'. Bad programs should be handled
by the interpreter and terminated with a reason -- they should not terminate
perl with a core dump, which it sounds like what is happening here.

  Would you consider it acceptable if running a user program on linux
would
cause the kernel to dump core or hang? If the user isn't using 'C' /
'XS' code, but pure perl (i.e. -- isn't running "privileged code"), I
wouldn't feel right knowing how easy it is to crash perl given all the
code that is out there that relies on it. Aren't there programs out
there that allow perl-sandboxed code? Would those sandboxes die?

@p5pRT
Copy link
Author

p5pRT commented Sep 3, 2012

From @Leont

On Sat, Sep 1, 2012 at 10​:28 PM, Dave Mitchell <davem@​iabyn.com> wrote​:

Perl is crashing due to infinite recursion within the tie PRINT method.
ie PRINT keeps calling PRINT.

This is because within the PRINT method, when it prints to one of the
unldelying file handles, one of them happens to be STDOUT, which is now
also tied.

a tie method recursively triggering a tie method is one of the few areas
in perl that needs to use the C stack rather then the perl stack, so
crashaes with an unceremonious SEGV rather than the slighly more
ceremonious 'out of memory' error you;'d get if the perl stack gets
exhaused.

Not a lot we can really do to make it more graceful.

I think we could maintain some kind of counter in the tie magic while
doing the print, and refusing to go deeper than a certain level.

Leon

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

1 participant