php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #36012 [PATCH] shell_exec leaks memory/pipe file descriptor on timeout (works in 5.1)
Submitted: 2006-01-14 20:22 UTC Modified: 2008-07-11 21:13 UTC
Votes:4
Avg. Score:4.2 ± 0.8
Reproduced:3 of 3 (100.0%)
Same Version:2 (66.7%)
Same OS:0 (0.0%)
From: anton dot php at titov dot net Assigned: pollita (profile)
Status: Wont fix Package: Program Execution
PHP Version: 4.4.2 OS: Gentoo Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: anton dot php at titov dot net
New email:
PHP Version: OS:

 

 [2006-01-14 20:22 UTC] anton dot php at titov dot net
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.


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-01-14 20:49 UTC] anton dot php at titov dot net
It is a php4.x bug. It's not present in lates PHP5 snapshot, but in the latest PHP4.4 snapshot it still exists.
 [2006-04-11 17:25 UTC] sniper@php.net
Sara, this fall in your field of expertise.
 [2008-07-11 21:13 UTC] jani@php.net
We are sorry, but we can not support PHP 4 related problems anymore.
Momentum is gathering for PHP 6, and we think supporting PHP 4 will
lead to a waste of resources which we want to put into getting PHP 6
ready.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 17:01:58 2024 UTC