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

Segmentation fault with deep recursion in regex engine #7770

Closed
p5pRT opened this issue Jan 26, 2005 · 8 comments
Closed

Segmentation fault with deep recursion in regex engine #7770

p5pRT opened this issue Jan 26, 2005 · 8 comments

Comments

@p5pRT
Copy link

p5pRT commented Jan 26, 2005

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

Searchable as RT33945$

@p5pRT
Copy link
Author

p5pRT commented Jan 26, 2005

From @ap

This is a bug report for perl from pagaltzis@​gmx.de,
generated with the help of perlbug 1.35 running under perl v5.8.6.


Deep recursion the regex engine causes a segfault. While there's
nothing that can really be done other than aborting the program
in that case, that should at least be done in orderly fashion.

The condition can easily be reproduced thusly​:

  perl -le'my $rx; $rx=qr/(??{ $rx })/; ""=~$rx'



Flags​:
  category=core
  severity=low


Site configuration information for perl v5.8.6​:

Configured by root at Sat Jan 1 19​:32​:19 PST 2005.

Summary of my perl5 (revision 5 version 8 subversion 6) configuration​:
  Platform​:
  osname=linux, osvers=2.4.28, archname=i486-linux
  uname='linux midas 2.4.28 #6 tue dec 14 14​:41​:15 pst 2004 i686 unknown unknown gnulinux '
  config_args='-de -Dprefix=/usr -Dcccdlflags=-fPIC -Dinstallprefix=/usr -Doptimize=-O2 -march=i486 -mcpu=i686 -Dinc_version_list=5.8.5 5.8.4 5.8.3 5.8.2 5.8.1 5.8.0 -Darchname=i486-linux'
  hint=recommended, useposix=true, d_sigaction=define
  usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
  useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
  use64bitint=undef use64bitall=undef uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cc', ccflags ='-fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
  optimize='-O2 -march=i486 -mcpu=i686',
  cppflags='-fno-strict-aliasing -pipe -I/usr/local/include'
  ccversion='', gccversion='3.3.4', gccosandvers=''
  intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
  ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
  alignbytes=4, prototype=define
  Linker and Libraries​:
  ld='cc', ldflags =' -L/usr/local/lib'
  libpth=/usr/local/lib /lib /usr/lib
  libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc
  perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
  libc=/lib/libc-2.3.3.so, so=so, useshrplib=false, libperl=libperl.a
  gnulibc_version='2.3.3'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
  cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib'

Locally applied patches​:
 


@​INC for perl v5.8.6​:
  /home/ap/perl/lib/
  /home/ap/lib/i386-linux
  /home/ap/lib
  /home/ap/lib/site_perl/i386-linux
  /home/ap/lib/site_perl
  /home/ap/lib/site_perl
  /usr/lib/perl5/5.8.6/i486-linux
  /usr/lib/perl5/5.8.6
  /usr/lib/perl5/site_perl/5.8.6/i486-linux
  /usr/lib/perl5/site_perl/5.8.6
  /usr/lib/perl5/site_perl/5.8.4
  /usr/lib/perl5/site_perl/5.8.3
  /usr/lib/perl5/site_perl/5.8.0
  /usr/lib/perl5/site_perl
  .


Environment for perl v5.8.6​:
  HOME=/home/ap
  LANG=C
  LANGUAGE (unset)
  LC_ALL=C
  LD_LIBRARY_PATH=/home/ap/lib/​:/opt/firefox/
  LOGDIR (unset)
  PATH=/home/ap/bin​:/opt/firefox​:/home/ap/bin​:/opt/firefox​:/usr/local/bin​:/usr/bin​:/bin​:/usr/X11R6/bin​:/usr/games​:/opt/www/htdig/bin​:/usr/lib/java/bin​:/usr/lib/java/jre/bin​:/usr/lib/qt/bin​:/usr/share/texmf/bin​:.​:/sbin​:/usr/local/sbin​:/usr/sbin​:/sbin​:/usr/local/sbin​:/usr/sbin
  PERL5LIB=/home/ap/perl/lib/​:/home/ap/lib/i386-linux​:/home/ap/lib​:/home/ap/lib/site_perl/i386-linux​:/home/ap/lib/site_perl​:/home/ap/lib/site_perl
  PERL_BADLANG (unset)
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jan 29, 2005

From @iabyn

On Wed, Jan 26, 2005 at 10​:07​:17PM -0000, A. Pagaltzis wrote​:

Deep recursion the regex engine causes a segfault. While there's
nothing that can really be done other than aborting the program
in that case, that should at least be done in orderly fashion.

The condition can easily be reproduced thusly​:

perl \-le'my $rx; $rx=qr/\(??\{ $rx \}\)/; ""=~$rx'

I can't really see what else Perl can do. The segfault happens when Perl
extends the stack too far. This can't be avoided. The SIGSEGV could be
caught, but then there's nothing sensible that perl could then do to
retrieve the situation.

--
My get-up-and-go just got up and went.

@p5pRT
Copy link
Author

p5pRT commented Jan 29, 2005

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

@p5pRT
Copy link
Author

p5pRT commented Jan 29, 2005

From @ap

* Dave Mitchell via RT <perlbug-followup@​perl.org> [2005-01-29 16​:40]​:

I can't really see what else Perl can do. The segfault happens
when Perl extends the stack too far. This can't be avoided.

Isn't it possible to check before extending the stack whether
there's room for the planned extension?

The SIGSEGV could be caught, but then there's nothing sensible
that perl could then do to retrieve the situation.

As I said I don't think there is much that perl could do to
salvage the running program; but if possible it should at least
throw an error along the lines of "Deep recursion in regex in
file foo.pl line 42" and, ideally, proceed to die in an orderly
manner (global destruction and all that).

@p5pRT
Copy link
Author

p5pRT commented Jan 29, 2005

From @iabyn

On Sat, Jan 29, 2005 at 05​:18​:59PM +0100, A. Pagaltzis wrote​:

* Dave Mitchell via RT <perlbug-followup@​perl.org> [2005-01-29 16​:40]​:

I can't really see what else Perl can do. The segfault happens
when Perl extends the stack too far. This can't be avoided.

Isn't it possible to check before extending the stack whether
there's room for the planned extension?

No. we're talking about the processor stack here, not the Perl stack. That
would imply that every function call that perl ever makes (and in any
libraries that is uses) must check first, which would grind things to a
halt. Also, I don't believe there is a portable way of determining the
current stack allocation.

The SIGSEGV could be caught, but then there's nothing sensible
that perl could then do to retrieve the situation.

As I said I don't think there is much that perl could do to
salvage the running program; but if possible it should at least
throw an error along the lines of "Deep recursion in regex in
file foo.pl line 42" and, ideally, proceed to die in an orderly
manner (global destruction and all that).

No, because by the time of a SIGSEGV, perl can't execute any code that
might call a function, because it hasn't got a stack.

--
Thank God I'm an atheist.....

@p5pRT
Copy link
Author

p5pRT commented Jan 30, 2005

From @ap

* Dave Mitchell via RT <perlbug-followup@​perl.org> [2005-01-29 19​:14]​:

No. we're talking about the processor stack here, not the Perl
stack. That would imply that every function call that perl ever
makes (and in any libraries that is uses) must check first,
which would grind things to a halt.

Sure, but we're not talking about every conceivable scenario.
This is a specific case, namely the evaluation of a postponed
regular expression. Isn't it possible to insert a guard that is
checked before the engine evaluates a postponed expression?

Or to put this in another way​: could I write a straight regular
expression *without* postponed expressions that is so large as to
cause perl to segfault just as it does here?

No, because by the time of a SIGSEGV, perl can't execute any
code that might call a function, because it hasn't got a stack.

I am well aware of that. The goal would of course be to recognise
the situation before the segfault happens in the first place.

@p5pRT
Copy link
Author

p5pRT commented Jan 30, 2005

From @iabyn

On Sat, Jan 29, 2005 at 08​:33​:48PM +0100, A. Pagaltzis wrote​:

Or to put this in another way​: could I write a straight regular
expression *without* postponed expressions that is so large as to
cause perl to segfault just as it does here?

$ perl -e '$s = 'x' x 10000; $s =~ /(a?x)*/'
Segmentation fault
$

--
Wesley Crusher gets beaten up by his classmates for being a smarmy git,
and consequently has a go at making some friends of his own age for a
change.
  -- Things That Never Happen in "Star Trek" #18

@p5pRT
Copy link
Author

p5pRT commented Sep 26, 2010

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

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