hello

i have tested the bug on:
FreeBSD rtfm.*.ro 4.9-PRERELEASE FreeBSD 4.9-PRERELEASE #1: Thu Sep 18
23:17:45 EEST 2003     [EMAIL PROTECTED]:/usr/src/sys/compile/RTFM  i386
Server: Apache/1.3.28 (Unix) PHP/4.3.3 mod_perl/1.28 mod_gzip/1.3.26.1a

and nothing happened:
---------------------------------------------------
-bash-2.05b$ ./build
gcc -g -o envtest envtest.c -Wall -Wl,-E -L/usr/local/lib
/usr/local/lib/perl5/5.8.0/mach/auto/DynaLoader/DynaLoader.a -L/usr/local/li
b/perl5/5.8.0/mach/CORE -lperl -lm -lc -lcrypt -lutil -DAPPLLIB_EXP="/usr/lo
cal/lib/perl5/5.8.0/BSDPAN" -DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-stric
t-aliasing -I/usr/local/include -I/usr/local/lib/perl5/5.8.0/mach/CORE
-bash-2.05b$ ./envtest
print "1\n"
1D
print "2\n"
2D
-bash-2.05b$
---------------------------------------------------
and i dont have -DPERL_USE_SAFE_PUTENV flag activated

-bash-2.05b$ perl -V:cppflags
cppflags='';
-bash-2.05b$


Ghita Serban
www.fastweb.ro


<[EMAIL PROTECTED]> wrote in message
news:[EMAIL PROTECTED]
> Below is the report we had created describing the resolution to a
> series of sporadic Apache child process segfaults.  It is being posted
> here so that, as the message has it, "it will be archived and
> Googlable".
>
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> Executive Summary
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> PHP and mod_perl do not share the environment nicely.  PHP's putenv()
> will cause segfaults.  Caveats should be distributed all around in
> PHP and mod_perl, at the very least, with the following two options:
>
>   * Recompile Perl itself with -DPERL_USE_SAFE_PUTENV, then
>     recompile mod_perl and Apache, in that order.
>
>   * Replace all PHP calls to putenv() with apache_setenv().
>
> I'm publishing this so that it will be archived and Googlable.
>
> Most of the following is written by, and based research from, Nick
> Dronen.
>
>
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> Background / Affected Configuration
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> We've been seeing segmentation faults in an Apache configured with
> mod_perl and PHP.  There are several posts, all to archived PHP
> mailing lists, with stack traces that match the ones we've been
> seeing, but no useful resolutions.  This document describes the
> problem and solution so other users who encounter this problem can
> acquire a clear idea what to do.
>
> At first, it looks like the problem is caused by either PHP or the
> C runtime library.  It's not.  It's caused by the use of both
> mod_perl and mod_php in Apache, if (and hopefully only if) your
> perl is not configured to use the C library's putenv(3) routine.
> Other Apaches configured to use mod_perl and any other module that
> manipulates the process's environment may also be affected.  At
> any rate, this is what we're using:
>
>   * Apache 1.3.28
>   * PHP 4.3.3
>   * Perl 5.8.0
>   * mod_perl 1.28
>
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> Symptoms - PHP
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> If PHP is configured with --enable-debug, errors containing apparantly
> corrupt memory will appear in the log files.  (Reformatted here to
> make it less unreadable.)
>
>   [Thu Aug 28 13:11:47 2003]  Script:  '/path/to/file.html'
>   /usr/src/php-4.3.3/Zend/zend_opcode.c(159) :
>       Block 0x08D77C58 status:
>   /usr/src/php-4.3.3/Zend/zend_variables.c(44):
>       Actual location (location was relayed)
>
>   Beginning:      OK (allocated on Zend/zend_language_scanner.c:4718,
> 64 bytes)
>         End:      Overflown (magic=0x08376158 instead of 0x2A8FCC84)
>                      At least 4 bytes overflown
>   ---------------------------------------
>   [Thu Aug 28 13:11:47 2003] [error] php Warning:  String is not
> zero-terminated ([EMAIL PROTECTED]) (source:
> /usr/src/php-4.3.3/Zend/zend_opcode.c:159) in Unknown on line 0
>   [Thu Aug 28 13:11:47 2003]  Script:  '/path/to/file.html'
>   ---------------------------------------
>   /usr/src/php-4.3.3/Zend/zend_opcode.c(159):
>       Block 0x08D77D00 status:
>   /usr/src/php-4.3.3/Zend/zend_variables.c(44):
>       Actual location (location was relayed)
>
>   Beginning:      Overrun (magic=0x083763F0, expected=0x7312F8DC)
>
>   [Thu Aug 28 13:11:47 2003] [notice] child pid 3983 exit signal
> Segmentation fault
>
> Note that the garbage in the "String is not zero-terminated" line
> is about 80 characters long and filled with randomness.  It's been
> truncated here.
>
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> Symptoms - core dumps
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> If your apache is able to create a core file, you can examine the
> stack trace by doing:
>
>   $ gdb /path/to/httpd /path/to/core
>
> or
>
>   $ dbx /path/to/httpd /path/to/core
>
> In some cases -- specifically when httpd is running suid/sgid --
> Apache will not dump core.  There is a kernel patch for Linux that
> changes this behavior so you can get a core dump.  The patch is
> available for Linux kernel versions 2.4.x and 2.5.x at:
>
>   http://www.ussg.iu.edu/hypermail/linux/kernel/0204.2/1170.html
>
> Memory madness can cause segmentation faults at any number of places
> in a complex program, depending on how memory is accessed.  Below
> is one of the more common stack traces we've seen .  A strong sign
> that you're suffering from this problem is the presence of putenv(3)
> in the stack.
>
> If your stacks look different than this, a sample program appears
> at the end of this document, along with instructions how to run
> it.  If the program segfaults, you might be seeing the same problem.
>
> Here's a classic stack trace (also reformatted a bit):
>
>   #0  0x4207448f in _int_realloc () from /lib/i686/libc.so.6
>   #0  0x4207448f in _int_realloc () from /lib/i686/libc.so.6
>   #1  0x42073416 in realloc () from /lib/i686/libc.so.6
>   #2  0x4202ab8f in __add_to_environ () from /lib/i686/libc.so.6
>   #3  0x4202aab8 in putenv () from /lib/i686/libc.so.6
>   #4  0x080f68ba in zif_putenv (
>       ht=1, return_value=0x8c01ffc, this_ptr=0x0, return_value_used=0)
>       at /usr/src/php-4.3.3/ext/standard/basic_functions.c:1347
>
>   #5  0x080ce2e6 in execute (op_array=0x84e7044)
>       at /usr/src/php-4.3.3/Zend/zend_execute.c:1616
>
>   #6  0x080beaa4 in zend_execute_scripts (
>       type=8, retval=0x0, file_count=3
>         ) at /usr/src/php-4.3.3/Zend/zend.c:885
>
>   #7  0x08096641 in php_execute_script (primary_file=0xbfffe440)
>       at /usr/src/php-4.3.3/main/main.c:1723
>
>   #8  0x080d2e35 in apache_php_module_main (
>       r=0x8b6fa1c, display_source_mode=0
>         ) at /usr/src/php-4.3.3/sapi/apache/sapi_apache.c:54
>
>   #9  0x0808d690 in send_php (
>       r=0x8b6fa1c, display_source_mode=0,
>       filename=0x8b70924 "/home/moregan/tw/envthrash.php"
>         ) at mod_php4.c:620
>
>   #10 0x0808d6fb in send_parsed_php (r=0x8b6fa1c) at mod_php4.c:635
>   #11 0x0819bce8 in ap_invoke_handler (r=0x8b6fa1c) at
> http_config.c:518
>   #12 0x081b075b in process_request_internal (r=0x8b6fa1c)
>       at http_request.c:1324
>
>   #13 0x081b07ba in ap_process_request (r=0x8b6fa1c) at
> http_request.c:1340
>   #14 0x081a7a03 in child_main (child_num_arg=0) at http_main.c:4653
>   #15 0x081a7c64 in make_child (s=0x831fbac, slot=0, now=1063034483)
>       at http_main.c:4823
>
>   #16 0x081a7fa3 in perform_idle_server_maintenance () at
> http_main.c:5008
>   #17 0x081a85c2 in standalone_main (argc=3, argv=0xbfffe944)
>       at http_main.c:5258
>
>   #18 0x081a8bc8 in main (argc=3, argv=0xbfffe944) at http_main.c:5511
>   #19 0x420158d4 in __libc_start_main () from /lib/i686/libc.so.6
>
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> Root Cause
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> The malbehavior is caused by Perl's handling of the pointer to the
> process environment (usually accessed via the global variable
> environ).
> Some implementations of putenv(3) leak memory (or, to be fair, used to
> leak memory, but have been fixed), and perl has code that works around
> this.  To do so, perl allocates its own memory for the environment,
> copies the original environment to the new memory block, frees the
> original pointer, and assigns the new pointer to environ.
>
> A call to PHP's putenv routine results in a call to the C library,
> which will use an internal pointer, one that points to memory that
> was already freed by perl, to reallocate memory for environ.  This
> results in a segmentation fault.
>
> If you're curious about the perl code that fiddles with the
> environment,
> run:
>
>   $ egrep '\<environ\>' *.c *.h
>
> in the base directory of the perl source tree.  Enjoy.
>
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> Solutions
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> There are two ways to avoid this segmentation fault.
>
>   * Recompile perl itself with -DPERL_USE_SAFE_PUTENV, then
>     recompile mod_perl and apache, in that order.
>
>   * Replace all php calls to putenv() with apache_setenv().
>
> The first is preferable if your webby packages are built from source
> already.  If you're using a vendor's perl, and the vendor is man
> enough to stand behind the implementation of putenv(3) in its C
> library, perhaps they should rethink about the options they use to
> compile perl.  In the meantime, you can just use apache_setenv().
>
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> Recommended Action (for Apache, PHP, mod_perl maintainers)
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> In the best of all possible worlds, the mod_perl and mod_php
> documentation would be changed to include a glaringly conspicuous
> caveat to users.  In fact, because this "feature" of Perl can cause
> segfaults in any apache that uses mod_perl in concert with any
> other module that calls putenv(), it might be a good idea for the
> documentation of apache and even other modules to include this
> caveat.
>
> Something to this effect:
>
>     If you are running apache with mod_perl and at least
>     one other module, you may want to compile your perl with
>     -DPERL_USE_SAFE_PUTENV.  If your perl is not compiled with this
>     macro defined, libperl.a will contain code that plays dangerously
>     with the global variable environ, which can lead to segmentation
>     faults when other apache modules call putenv().
>
>     You can check whether your perl has been compiled with this option
>     by running the following command:
>
> $ perl -V:cppflags
>
>     If you see -DPERL_USE_SAFE_PUTENV in the output, your perl was
>     compiled with that option and your apache shouldn't exhibit the
>     bad behavior in question.  If you don't see it, and apache is
>     crashing with stack traces that contain the function putenv(),
>     reconfigure with
>
> $ ./Configure --Acppflags=-DPERL_USE_SAFE_PUTENV
>
>     along with any other Configure options you may need.  Run "make",
>     "make test", and "make install."  Then recompile mod_perl.  If
>     your mod_perl is statically linked into apache, recompile apache
>     as well.
>
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> Reproducing the problem
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> Save 'build' and 'envtest.c' to files on your machine.  Run build
> to make envtest.  Run ulimit -c to see whether your process limits
> are set to allow core dumps.  Then run envtest, using the exact
> inputs show below (print "1\n"<RETURN><CTRL>-Dprint
> "2\n"<RETURN><CTRL>-D).
>
>
#---------------------------------------------------------------------------
> # BEGIN build
>
#---------------------------------------------------------------------------
>
>     #!/bin/sh
>
>     perl=perl
>     opts=$($perl -MExtUtils::Embed -e ccopts -e ldopts)
>
>     if [[ $perl = "debugperl" ]]
>     then
> opts=$(echo $opts | sed 's/-lperl/-ldebugperl/')
>     fi
>
>     cmd="gcc -g -o envtest envtest.c -Wall $opts"
>     echo $cmd; $cmd
>
>
#---------------------------------------------------------------------------
> # END build
>
#---------------------------------------------------------------------------
>
>     /* BEGIN envtest.c */
>
>     #include <stdlib.h>
>     #include <string.h>
>     #include <assert.h>
>     #include <EXTERN.h>
>     #include <perl.h>
>
>     void run_perl(int argc, char *argv[], char **env, char
> *putenv_arg);
>
>     #define VAR1 "VAR1=value"
>     #define VAR2 "VAR2=value"
>
>     char *tmpptr = VAR2;
>
>     int main(int argc, char *argv[], char **env)
>     {
> char *envptr = malloc(strlen(VAR1) + 1);
> strcpy(envptr, VAR1);
>
> /* call putenv with malloc'ed pointer */
> run_perl(argc, argv, env, envptr);
> /* call putenv with pointer from process's data segment */
> run_perl(argc, argv, env, tmpptr);
>
> free(envptr);
>
> exit(0);
>     }
>
>     void run_perl(int argc, char *argv[], char **envptr, char
> *putenv_arg) {
> PerlInterpreter *my_perl = perl_alloc();
> perl_construct(my_perl);
> PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
> perl_parse(my_perl, NULL, argc, argv, envptr);
>
> if (putenv_arg)
>     assert(putenv(putenv_arg) == 0);
>
> perl_run(my_perl);
> perl_destruct(my_perl);
> perl_free(my_perl);
>     }
>
>     /* END envtest.c */
>
>   $ ./build
>   gcc -g -o envtest envtest.c -Wall -rdynamic -L/usr/local/lib
> /usr/lib/perl/5.8.0/auto/DynaLoader/DynaLoader.a
> -L/usr/lib/perl/5.8.0/CORE -lperl -ldl -lm -lpthread -lc -lcrypt
> -D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing
> -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/lib/perl/5.8.0/CORE
>
>   $ ./envtest
>   print "1\n" <-- press return, then ^D
>   1
>   print "2\n" <-- press return, then ^D
>   Segmentation fault (core dumped)
>
>   $ gdb -q envtest core
>   Core was generated by `./envtest'.
>   Program terminated with signal 11, Segmentation fault.
>   Reading symbols from /usr/lib/libperl.so.5.8...done.
>   Loaded symbols for /usr/lib/libperl.so.5.8
>   Reading symbols from /usr/lib/debug/libdl.so.2...done.
>   Loaded symbols for /usr/lib/debug/libdl.so.2
>   Reading symbols from /usr/lib/debug/libm.so.6...done.
>   Loaded symbols for /usr/lib/debug/libm.so.6
>   Reading symbols from /usr/lib/debug/libpthread.so.0...done.
>   Loaded symbols for /usr/lib/debug/libpthread.so.0
>   Reading symbols from /usr/lib/debug/libc.so.6...done.
>   Loaded symbols for /usr/lib/debug/libc.so.6
>   Reading symbols from /usr/lib/debug/libcrypt.so.1...done.
>   Loaded symbols for /usr/lib/debug/libcrypt.so.1
>   Reading symbols from /lib/ld-linux.so.2...done.
>   Loaded symbols for /lib/ld-linux.so.2
>   #0  0x401ffeee in __libc_realloc (oldmem=0x804e730, bytes=160) at
> malloc.c:3408
>   3408      ar_ptr = arena_for_chunk(oldp);
>   (gdb) where
>   #0  0x401ffeee in __libc_realloc (oldmem=0x804e730, bytes=160) at
> malloc.c:3408
>   #1  0x401be753 in __add_to_environ (name=0xbffff5c0 "VAR2",
> value=0x0,
>       combined=0x8048bf0 "VAR2=value", replace=1) at
> ../sysdeps/generic/setenv.c:145
>   #2  0x401be686 in putenv (string=0x8048bf0 "VAR2=value")
>       at ../sysdeps/generic/putenv.c:67
>   #3  0x08048ab7 in run_perl (argc=1, argv=0xbffff694,
> envptr=0xbffff69c,
>       putenv_arg=0x8048bf0 "VAR2=value") at envtest.c:36
>   #4  0x08048a2f in main (argc=1, argv=0xbffff694, env=0xbffff69c) at
> envtest.c:22

Reply via email to