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