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
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
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

Add a Patch

Pull Requests

Add a Pull Request

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-2021 The PHP Group
All rights reserved.
Last updated: Thu Sep 23 03:03:37 2021 UTC