Bug#905603: Tested on Buster : bug still present

2018-08-15 Thread Benoit Bolsee
Hi,

Following your advice, I tested with Debian buster and the development
version of perl and mod_perl and this bug is still present. 
I filed a report on the mod_perl development mailing list.

Benoit



Bug#905650: Tested on Debian buster : bug fixed

2018-08-14 Thread Benoit Bolsee
Hi,

Following your advise I first tested if the bug is still there on Debian
testing and it's not : the sequence of event is still the same as I
described except that the relocation dependency of libm towards libperl
is gone and now libperl unloads properly when mod_perl is unloaded =>
the PL_check array is fresh clean on the second reload and there is no
invalid pointer.

So there is a fix that could perhaps be backported in Debian stretch
about removing this relocation dependency. I didn't investigate what it
could be.










Bug#905650: update

2018-08-08 Thread Benoit Bolsee

After thinking about it, my proposed patch will not work in this
situation:

1. use $[ but don't bring libstdc++ 
  => libperl.so will be removed but not arybase.so
2. on create-config stage, libperl.so is reloaded, PL_check is
initialized and points to local checks only
3. the boot section is arybase is executed, but wrap_op_checker will be
a no-op because the static ab_old_ck_.. pointer is not null 
  => the op checker is not installed in libperl...

It's a tough one. 
To bring the patch further, libperl should also be forced to stay in
memory

The correct fix is that all XS modules that register things outside
themselves should unregister properly on unload. I have identified 3 XS
modules that don't do that: arybase, EV, Params::Classify
To their defense, Perl is making it difficult (no API to unset an op
checker)
To Perl's defense, apache is making it difficult by by doing a config
load-unload-reload.







Bug#905679: libparams-classify-perl: XS version causing infinite loop when loaded twice

2018-08-07 Thread Benoit Bolsee
Package: libparams-classify-perl
Version: 0.013-6+b1
Severity: important
Tags: patch upstream

The XS version of this package registers an op checker by writing directly into 
PL_check array
(see libparams-classify-perl-0.013: lib/Params/Classify.xs line 741)
This is not the canonic way of registering a op checker, it should use 
wrap_op_checker instead.
This bug is only causing problem if the BOOT section is executed twice : on the 
second
execution, the infinite loop will form when nxck_entersub will point to 
myck_entersub (as PL_check[OP_ENTERSUB] already points to myck_entersub).

Note: the bug is fixed in version 0.015 (buster).

Here is the suggested patch for version 0.013 :

--- a/lib/Params/Classify.xs2018-08-03 22:55:45.0 +0200
+++ b/lib/Params/Classify.xs2018-08-03 22:55:45.0 +0200
@@ -738,6 +738,5 @@
newSVpvn_share(rtypemeta->keyword_pv,
strlen(rtypemeta->keyword_pv), 0);
}
-   nxck_entersub = PL_check[OP_ENTERSUB];
-   PL_check[OP_ENTERSUB] = myck_entersub;
+   wrap_op_checker(OP_ENTERSUB, myck_entersub, _entersub);
 }




-- System Information:
Debian Release: 9.5
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 4.9.0-7-amd64 (SMP w/1 CPU core)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), 
LANGUAGE=en_US:en (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages libparams-classify-perl depends on:
ii  libc6   2.24-11+deb9u3
ii  perl5.24.1-3+deb9u4
ii  perl-base [perlapi-5.24.1]  5.24.1-3+deb9u4

libparams-classify-perl recommends no packages.

Versions of packages libparams-classify-perl suggests:
pn  libscalar-number-perl  

-- no debconf information



Bug#905650: libapache2-mod-perl2: crash when $[ and XML::LibXML used at the same time

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



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

   To reproduce the bug, start from a vanilla Debian server, install apache2, 
libapache2-mod-perl2 and libxml-libxml-perl.
   Create a perl file handler.pl with following content :
  #!/usr/bin/perl
  use XML::LibXML;
  $[;
  1;

   Add a directive to /etc/apache2/apache2.conf (or add a file in 
/etc/apache2/conf-enabled with the same directive) :
   PerlRequire "/path/to/handler.pl"

   Apache will crash on startup.

   ===

   I did an in-depth investigation of this problem. Here is what happens:

   apache goes through 3 stages on startup : pre-config, destroy-config, 
create-config

   In the pre-config stage, all modules are loaded
   loading mod_perl.so also brings libperl.so and libm.so in the program map
   XML::LibXML is a XS package that has a dependency on libstc++.so => 
LibXML.so and libstdc++.so.6 are brought in the program map
   libstdc++.so has a dependency on libm.so
   libm.so has a relocation dependency on libperl.so (this is strange but true).
   => a 'dependency cluster' is created between libstdc++, libm and libperl.

   The special $[ variable is implemented in the XS library arybase.so, it 
installs an op checker via wrap_op_checker() in the perl interpreter (see 
perl-5.24.1: ext/arybase/arybase.xs BOOT section)
   The address of the op checker is saved in the static PL_check array that 
resides in libperl.so
   The op checker itself resides in arybase.so
   Installing an op checker is a one-way operation, Perl provides no API to 
remove it.
   At the end of pre-config stage we have an informal dependency 
libperl.so(PL_check) -> arybase.so

   During the destroy-config stage, apache unloads all the modules.
   For mod_perl this implies removing all XS modules (see 
libapache2-mod-perl2-2.0.10: 
src/modules/perl/modperl_interp.c:modperl_interp_destroy())
   At this stage the op checker in PL_check points to invalid memory as 
arybase.so was unloaded!
   Then apache removes mod_perl itself (see apr-1.5.2: 
dso/unix/dso.c:dso_cleanup())
   Normally, this would also remove libperl.so and libm.so but with the 
dependency cluster that was created with libstc++, libperl is not removed!

   During create-config stage, mod_perl is reloaded but not libperl of course.
   loading arybase.so is differed until the PerlRequire directive is executed
   => PL_check points to invalid memory.
   The first thing mod_perl does is load /etc/perl/sitecustomize.pl => it 
crashes on the first op involving the corrupted op checked.
   
   This bug is similar to bug #905603 : a pointer to invalid memory is kept in 
memory after config-destroy.

   ==

   The fix that I proposed for bug #905603 will work here too: the crash is 
avoided by skipping the unloading the XS modules:

--- 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);
 }


   An ideal solution would be that the faulty XS modules do proper cleanup on 
unloading but Perl does not make it simpler (no API to remove a op checker).

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 

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