From:             anton dot php at titov dot net
Operating system: Gentoo Linux
PHP version:      4.4.2
PHP Bug Type:     Apache related
Bug description:  shell_exec not freeing memory/pipe file descriptor on timeout

Description:
------------
shell_exec/backticks operator use popen to fork process, but do not
register this pipe with php_stream_fopen_from_pipe so in case of apache
timeout /I guess other APIs also have the same problem/. 

I've fixed this problem by lookind at how other exec functions work, so
this fix should be fine.

patch follows:

--- php-4.4.2-orig/ext/standard/exec.c  2006-01-01 15:46:57.000000000
+0200
+++ php-4.4.2/ext/standard/exec.c       2006-01-14 20:53:18.059967960
+0200
@@ -552,6 +552,7 @@
        int readbytes, total_readbytes=0, allocated_space;
        pval **cmd;
        char *ret;
+        php_stream *stream;

        if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1,
&cmd)==FAILURE) {
                WRONG_PARAM_COUNT;
@@ -571,10 +572,11 @@
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to
execute '%s'", Z_STRVAL_PP(cmd));
                RETURN_FALSE;
        }
+        stream = php_stream_fopen_from_pipe(in, "rb");
        allocated_space = EXEC_INPUT_BUF;
        ret = (char *) emalloc(allocated_space);
        while (1) {
-               readbytes = fread(ret+total_readbytes, 1, EXEC_INPUT_BUF,
in);
+               readbytes = php_stream_read(stream, ret+total_readbytes,
EXEC_INPUT_BUF);
                if (readbytes<=0) {
                        break;
                }
@@ -582,7 +584,7 @@
                allocated_space = total_readbytes+EXEC_INPUT_BUF;
                ret = (char *) erealloc(ret, allocated_space);
        }
-       pclose(in);
+       php_stream_close(stream);

        RETVAL_STRINGL(ret, total_readbytes, 0);
        Z_STRVAL_P(return_value)[total_readbytes] = '\0';


Reproduce code:
---------------
<?php

/* execute this with apache timeout of 60, or change sleep value to 700
*/

echo `sleep 100`;

exit(0);

Expected result:
----------------
The program works as expected and do nothing, but if apache timeout
happens you end up with zombie process and an open file descriptor inside
the apache process.


-- 
Edit bug report at http://bugs.php.net/?id=36012&edit=1
-- 
Try a CVS snapshot (PHP 4.4): 
http://bugs.php.net/fix.php?id=36012&r=trysnapshot44
Try a CVS snapshot (PHP 5.1): 
http://bugs.php.net/fix.php?id=36012&r=trysnapshot51
Try a CVS snapshot (PHP 6.0): 
http://bugs.php.net/fix.php?id=36012&r=trysnapshot60
Fixed in CVS:                 http://bugs.php.net/fix.php?id=36012&r=fixedcvs
Fixed in release:             
http://bugs.php.net/fix.php?id=36012&r=alreadyfixed
Need backtrace:               http://bugs.php.net/fix.php?id=36012&r=needtrace
Need Reproduce Script:        http://bugs.php.net/fix.php?id=36012&r=needscript
Try newer version:            http://bugs.php.net/fix.php?id=36012&r=oldversion
Not developer issue:          http://bugs.php.net/fix.php?id=36012&r=support
Expected behavior:            http://bugs.php.net/fix.php?id=36012&r=notwrong
Not enough info:              
http://bugs.php.net/fix.php?id=36012&r=notenoughinfo
Submitted twice:              
http://bugs.php.net/fix.php?id=36012&r=submittedtwice
register_globals:             http://bugs.php.net/fix.php?id=36012&r=globals
PHP 3 support discontinued:   http://bugs.php.net/fix.php?id=36012&r=php3
Daylight Savings:             http://bugs.php.net/fix.php?id=36012&r=dst
IIS Stability:                http://bugs.php.net/fix.php?id=36012&r=isapi
Install GNU Sed:              http://bugs.php.net/fix.php?id=36012&r=gnused
Floating point limitations:   http://bugs.php.net/fix.php?id=36012&r=float
No Zend Extensions:           http://bugs.php.net/fix.php?id=36012&r=nozend
MySQL Configuration Error:    http://bugs.php.net/fix.php?id=36012&r=mysqlcfg

Reply via email to