Bug#905603: libapache2-mod-perl2: crash when using EV::signal 'CHLD' and backtick operator at the same time

2018-08-12 Thread Niko Tyni
On Tue, Aug 07, 2018 at 01:03:55AM +0200, Benoit Bolsee wrote:
> Package: libapache2-mod-perl2
> Version: 2.0.10-2
> Severity: important
> Tags: patch upstream

>   I came to the conclusion that unloading the XS modules when mod_perl is 
> unloaded is very harsh; the perl interpretor is clearly not designed for 
> that. I tested a patch where the unloading of XS modules is simply skipped. 
> It's working and it also fixes another bug that I will report separately:

Hi, thanks for your reports. May I suggest that you bring these issues
up on the mod_perl development mailing list? See

 https://perl.apache.org/maillist/dev.html

-- 
Niko Tyni   nt...@debian.org



Bug#905603: libapache2-mod-perl2: crash when using EV::signal 'CHLD' and backtick operator at the same time

2018-08-06 Thread Benoit Bolsee
Package: libapache2-mod-perl2
Version: 2.0.10-2
Severity: important
Tags: patch upstream



-- Package-specific info:
-8<-- Start Bug Report 8<--
1. Problem Description:

  To reproduce the problem, start from a vanilla Debian server (I used 9.5).
  Install apache2, libapache2-mod-perl2, libev-perl
  Create 2 perl files with following content:
  handler1.pl:
#!/usr/bin/perl
my $pwd = `/bin/pwd`;
1;
  handler2.pl:
#!/usr/bin/perl
use EV;
my $w = EV::signal 'CHLD', sub {
print "SIGCHLD received\n";
};
1;
  Reference them in two PerlRequire directive, either in 
/etc/apache2/apache2.conf or in a separate conf file in 
/etc/apache2/conf-enabled:
   # order is important
   PerlRequire "/path/to/handler1.pl"
   PerlRequire "/path/to/handler2.pl"

  Apache will crash on startup.
  ===
  I did an in-depth analysis of this bug. What happens is the following:

  The backtick operator in handler1.pl internally calls waitpid, which  
internally waits for the SIGCHLD signal.
  EV::signal 'CHLD' installs a signal handler using sigaction (see 
libev-perl-4.22: libev/ev.c::ev_signal_start). There is no provision to remove 
this signal handler. The handler is located in EV.so, loaded by the XS loader.
  
  apache2 goes through 3 stages on startup: pre-config, destroy-config, 
create-config
  In the pre-config stage, the 2 PerlRequire commands are executed and the 
signal handler is installed at process level.
  In the destroy-config stage, all modules are removed, including mod_perl, 
which consists in removing all XS modules (see libapache2-mod-perl2-2.0.10: 
src/modules/perl/modperl_interp.c::modperl_interp_destroy())
  At this point the signal handler is still registered at process level but 
points to invalid memory!
  In the create-config stage, the config is recreated, handler1.pl is reloaded 
and the backtick operator triggers a SIGCHLD, which causes a SIGEV because the 
signal handler is not in memory (the EV.so library will only be loaded when the 
second PerlRequire is executed).
  
  I came to the conclusion that unloading the XS modules when mod_perl is 
unloaded is very harsh; the perl interpretor is clearly not designed for that. 
I tested a patch where the unloading of XS modules is simply skipped. It's 
working and it also fixes another bug that I will report separately:

--- a/src/modules/perl/modperl_interp.c 2018-08-03 20:49:54.0 +0200
+++ b/src/modules/perl/modperl_interp.c 2018-08-03 20:49:54.0 +0200
@@ -122,11 +122,11 @@
 MP_TRACE_i(MP_FUNC, "*error - still in use!*");
 }
 
-handles = modperl_xs_dl_handles_get(aTHX);
+/*handles = modperl_xs_dl_handles_get(aTHX);*/
 
 modperl_perl_destruct(interp->perl);
 
-modperl_xs_dl_handles_close(handles);
+/*modperl_xs_dl_handles_close(handles);*/
 
 free(interp);
 }

  

2. Used Components and their Configuration:

*** mod_perl version 2.10

*** using /usr/lib/x86_64-linux-gnu/perl5/5.24/Apache2/BuildConfig.pm

*** Makefile.PL options:
  MP_APR_CONFIG  => /usr/bin/apr-config
  MP_APR_LIB => aprext
  MP_APXS=> /usr/bin/apxs
  MP_CCOPTS  => -g -O2 
-fdebug-prefix-map=/build/libapache2-mod-perl2-go9ZTa/libapache2-mod-perl2-2.0.10=.
 -fstack-protector-strong -Wformat -Werror=format-security -Wall -fgnu89-inline
  MP_COMPAT_1X   => 1
  MP_GENERATE_XS => 1
  MP_LIBNAME => mod_perl
  MP_TRACE   => 0
  MP_USE_DSO => 1
  MP_USE_STATIC  => 0


*** The httpd binary was not found


*** (apr|apu)-config linking info

 -L/usr/lib/x86_64-linux-gnu -laprutil-1
 -L/usr/lib/x86_64-linux-gnu -lapr-1  



*** /usr/bin/perl -V
Summary of my perl5 (revision 5 version 24 subversion 1) configuration:
   
  Platform:
osname=linux, osvers=3.16.0, archname=x86_64-linux-gnu-thread-multi
uname='linux localhost 3.16.0 #1 smp debian 3.16.0 x86_64 gnulinux '
config_args='-Dusethreads -Duselargefiles -Dcc=x86_64-linux-gnu-gcc 
-Dcpp=x86_64-linux-gnu-cpp -Dld=x86_64-linux-gnu-gcc -Dccflags=-DDEBIAN 
-Wdate-time -D_FORTIFY_SOURCE=2 -g -O2 
-fdebug-prefix-map=/build/perl-N8J5tr/perl-5.24.1=. -fstack-protector-strong 
-Wformat -Werror=format-security -Dldflags= -Wl,-z,relro -Dlddlflags=-shared 
-Wl,-z,relro -Dcccdlflags=-fPIC -Darchname=x86_64-linux-gnu -Dprefix=/usr 
-Dprivlib=/usr/share/perl/5.24 -Darchlib=/usr/lib/x86_64-linux-gnu/perl/5.24 
-Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 
-Dvendorarch=/usr/lib/x86_64-linux-gnu/perl5/5.24 -Dsiteprefix=/usr/local 
-Dsitelib=/usr/local/share/perl/5.24.1 
-Dsitearch=/usr/local/lib/x86_64-linux-gnu/perl/5.24.1 
-Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 
-Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 
-Dusesitecustomize -Duse64bitint -Dman1ext=1 -Dman3ext=3perl 
-Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm 
-Ui