Dmitry Karasik wrote:
Hello,

In mixed environment of mod_perl and cgi, cgi scripts may choose to not use
mod_perl request interface, and read content of POST requests directly from
STDIN.  mod_perl during the initialization process closes file descriptor 0,
and frees it for further reuse in other processes.  Therefore, any cgi script
executing after mod_perl is initialized, and in the same process tree, will
have file descriptor 0 closed. The concrete example where this behavior leads
to impossibility of processing POST requests is reported earlier and is located
at

  http://marc.info/?l=apache-modperl&m=119062450730646&w=2

The proposed patch fixes the issue, however, not being a perl guts expert, I
would urge someone with a deeper knowledge of perl to look at it first. Chances
are that there exists a mechanism in perl that allows non-destructive
duplication and overloading of perl IO handles.

I am not a perl guts expert either (gozer??), but looking through the perl source it looks like this idiom is used in a few places. But we really need a reproducible test case to verify that this is indeed a problem.

I took a quick swing at putting one together but my mod_perl environment is a bit screwed up right now. Can you see if it runs on your setup? And hopefully passes with your change, and fails without? This test may not work at all :) but if it does and this problem is reproducible then that improves our chances of getting the fix accepted in some form.

Index: ModPerl-Registry/t/conf/extra.conf.in
===================================================================
--- ModPerl-Registry/t/conf/extra.conf.in       (revision 543707)
+++ ModPerl-Registry/t/conf/extra.conf.in       (working copy)
@@ -182,6 +182,17 @@
     PerlResponseHandler ModPerl::Registry
 </Location>

+### test for mixed mod_perl/cgi environment ###
+<Location /stdin_override/mod_perl>
+    SetHandler perl-script
+    PerlResponseHandler ModPerl::Registry
+    PerlOptions +ParseHeaders
+</Location>
+
+<Location /stdin_override/cgi>
+    SetHandler cgi-script
+</Location>
+
 ### deflate tests ###
 <IfModule mod_alias.c>
     Alias /registry_bb_deflate/ @ServerRoot@/cgi-bin/

Index: ModPerl-Registry/t/cgi-bin/stdin.pl
===================================================================
--- ModPerl-Registry/t/cgi-bin/stdin.pl (revision 0)
+++ ModPerl-Registry/t/cgi-bin/stdin.pl (revision 0)
@@ -0,0 +1,29 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use CGI qw/:standard/;
+
+print <<END;
+Content-type: text/html
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+   <body>
+     <form method="post"><input type="submit" name="submit" value="Submit">
+    </form>
+END
+
+if (param()) {
+    my $submit = param('submit');
+    if ($submit) {
+        print "<p>submitted</p>";
+    }
+}
+
+print <<END;
+    </body>
+</html>
+END
+

Index: ModPerl-Registry/t/stdin.t
===================================================================
--- ModPerl-Registry/t/stdin.t  (revision 0)
+++ ModPerl-Registry/t/stdin.t  (revision 0)
@@ -0,0 +1,24 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest qw(POST);
+
+plan tests => 2, need [qw(CGI)],
+    need_min_module_version CGI => 3.08;
+
+{
+    my $url = "/stdin_override/mod_perl";
+    my $res = POST $url;
+
+    ok t_cmp($res->content,
+             qr{submitted},
+             "form submission ok under mod_perl");
+
+    $url = "/stdin_override/cgi";
+    $res = POST $url;
+    ok t_cmp($res->content,
+             qr{submitted},
+             "stdin reset, form submission ok under cgi");
+}


Cheers,
        Dmitry Karasik

--- modperl_io.c.orig   2007-09-25 15:36:02.000000000 +0200
+++ modperl_io.c        2007-09-25 15:35:51.000000000 +0200
@@ -129,6 +129,15 @@
             Perl_croak(aTHX_ "Failed to dup STDIN: %" SVf, get_sv("!", TRUE));
         }
+ /* In mixed environment of mod_perl and cgi scripts, cgi scripts may read content of + * POST requests off STDIN. do_close() calls actual close(0), freeing the descriptor 0
+        * for reuse, and creating havoc for anyone reading from file 
descriptor 0.
+        * This hack changes the IO type to IoTYPE_STD, because do_close() does 
not call
+        * underlying close() on IO handles of these types, but does free the 
associated
+        * resources. */
+       if ( IoIFP(io) && PerlIO_fileno(IoIFP(io)) == 0)
+           IoTYPE(io) = IoTYPE_STD;
+
         /* similar to PerlIO::scalar, the PerlIO::Apache layer doesn't
          * have file descriptors, so STDIN must be closed before it can
          * be reopened */

2. Used Components and their Configuration:

*** mod_perl version 2.000003

*** using 
/usr/ports/www/mod_perl2/work/mod_perl-2.0.3/lib/Apache2/BuildConfig.pm

*** Makefile.PL options:
  MP_APR_LIB     => aprext
  MP_APXS        => /usr/local/sbin/apxs
  MP_COMPAT_1X   => 1
  MP_GENERATE_XS => 1
  MP_LIBNAME     => mod_perl
  MP_USE_DSO     => 1


*** The httpd binary was not found


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

 -L/usr/local/lib -laprutil-1 -lexpat -liconv -L/usr/local/lib
-L/usr/local/lib -lapr-1 -lcrypt -lpthread

*** /usr/local/bin/perl -V
Summary of my perl5 (revision 5 version 8 subversion 8) configuration:
  Platform:
    osname=freebsd, osvers=6.2-release, archname=i386-freebsd-64int
    uname='freebsd freebsd.org 6.2-release freebsd 6.2-release #0: sat oct 14 
21:57:31 pdt 2006 [EMAIL PROTECTED]:usrsrcsysmagickernelpath i386 '
    config_args='-sde -Dprefix=/usr/local -Darchlib=/usr/local/lib/perl5/5.8.8/mach 
-Dprivlib=/usr/local/lib/perl5/5.8.8 -Dman3dir=/usr/local/lib/perl5/5.8.8/perl/man/man3 
-Dman1dir=/usr/local/man/man1 -Dsitearch=/usr/local/lib/perl5/site_perl/5.8.8/mach 
-Dsitelib=/usr/local/lib/perl5/site_perl/5.8.8 -Dscriptdir=/usr/local/bin 
-Dsiteman3dir=/usr/local/lib/perl5/5.8.8/man/man3 -Dsiteman1dir=/usr/local/man/man1 
-Ui_malloc -Ui_iconv -Uinstallusrbinperl -Dcc=cc -Duseshrplib 
-Dccflags=-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.8/BSDPAN" -Doptimize=-O2 
-fno-strict-aliasing -pipe  -Ud_dosuid -Ui_gdbm -Dusethreads=n -Dusemymalloc=y 
-Duse64bitint'
    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=define use64bitall=undef uselongdouble=undef
    usemymalloc=y, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.8/BSDPAN" 
-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe 
-Wdeclaration-after-statement -I/usr/local/include',
    optimize='-O2 -fno-strict-aliasing -pipe ',
    cppflags='-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.8/BSDPAN" -DHAS_FPSETMASK 
-DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -Wdeclaration-after-statement 
-I/usr/local/include'
    ccversion='', gccversion='3.4.6 [FreeBSD] 20060305', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', 
lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -Wl,-E -L/usr/local/lib'
    libpth=/usr/lib /usr/local/lib
    libs=-lm -lcrypt -lutil
    perllibs=-lm -lcrypt -lutil
    libc=, so=so, useshrplib=true, libperl=libperl.so
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='  
-Wl,-R/usr/local/lib/perl5/5.8.8/mach/CORE'
    cccdlflags='-DPIC -fPIC', lddlflags='-shared  -L/usr/local/lib'


Characteristics of this binary (from libperl): Compile-time options: MYMALLOC PERL_MALLOC_WRAP USE_64_BIT_INT
                        USE_LARGE_FILES USE_PERLIO
  Locally applied patches:
        defined-or
  Built under freebsd
  Compiled at Oct 15 2006 05:04:59
  %ENV:
    PERL_LWP_USE_HTTP_10="1"
  @INC:
    /usr/local/lib/perl5/5.8.8/BSDPAN
    /usr/local/lib/perl5/site_perl/5.8.8/mach
    /usr/local/lib/perl5/site_perl/5.8.8
    /usr/local/lib/perl5/site_perl
    /usr/local/lib/perl5/5.8.8/mach
    /usr/local/lib/perl5/5.8.8
    .

*** Packages of interest status:

Apache2            : -
Apache2::Request   : -
CGI                : 3.15
ExtUtils::MakeMaker: 6.30, undef
LWP                : 5.805
mod_perl           : -
mod_perl2          : 2.000003


This report was generated by t/REPORT on Tue Sep 25 13:39:09 2007 GMT.

-------------8<---------- End Bug Report --------------8<----------

Note: Complete the rest of the details and post this bug report to
modperl <at> perl.apache.org. To subscribe to the list send an empty
email to [EMAIL PROTECTED]





Reply via email to