[php-maint] Bug#329822: php5: Crash related to use of stream_select

Dan Elphick dre at ecs.soton.ac.uk
Fri Sep 23 15:15:39 UTC 2005


Package: php5
Version: 5.0.5-1
Severity: important


The attached code causes php to crash:

I was trying to make something that would read stdout and stderr from a
process and if necessary kill it after a timeout. Testing this on the
process 'tail -f /tmp/testselect' (when the file doesn't exist) works
some of the time in which case it prints:

dre at carmen:~/public_html$ php index.php
Result is -1
stdout is
stderr is /usr/bin/tail: cannot open `/tmp/testselect' for reading: No
such file or directory
/usr/bin/tail: no files remaining

But sometimes it crashes and prints:

dre at carmen:~/public_html$ php index.php

Warning: fread(): supplied argument is not a valid stream resource in
/home/dre/public_html/index.php on line 38
*** glibc detected *** double free or corruption (!prev): 0x084add50 ***
Aborted

In fact the bug seems to manifest every 1/5th time I run it. (If I run
the script through apache it also crashes but it was easier to get
output from command line). 

-- System Information:
Debian Release: testing/unstable
  APT prefers unstable
  APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.11-1-k7
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)

Versions of packages php5 depends on:
ii  libapache2-mod-php5           5.0.5-1    server-side, HTML-embedded scripti
ii  php5-common                   5.0.5-1    Common files for packages built fr

php5 recommends no packages.

-- no debconf information
-------------- next part --------------
<?
$result = run_process();
echo "Result is $result[0]\n";
echo "stdout is $result[1]\n";
echo "stderr is $result[2]\n";

function run_process()
{
	$descriptorspec = array(
        0 => array("pipe", "r"),
        1 => array("pipe", "w"),
        2 => array("pipe", "w")
    );
	$command = '/usr/bin/tail -f /tmp/testselect';

    $process = proc_open($command, $descriptorspec, $pipes);

    if(is_resource($process))
    {
        fclose($pipes[0]);
		$error = '';
		$output = '';

		$starttime = microtime(true);
		$maxtime = 1;

		$sec_remaining = floor($maxtime);
		$usec_remaining = floor(($maxtime - $sec_remaining) * 1000000);

		stream_set_blocking($pipes[1], false);
		stream_set_blocking($pipes[2], false);
		$r_copy = array($pipes[1], $pipes[2]);
		while($ret = stream_select($r_copy, $writearray = NULL, $exceptarray = NULL,
								   $sec_remaining, $usec_remaining))
		{
			for($i = 0; $i < count($r_copy); $i++)
			{
				$read = fread($r_copy[$i], 8192);
				if($pipes[1] == $r_copy[$i])
				{
					$output .= $read;
				}
				else if($pipes[2] == $r_copy[$i])
				{
					$error .= $read;
				}
			}
			if(feof($pipes[1]) && feof($pipes[2]))
			{
				break;
			}
			$remaining = $maxtime - (microtime(true) - $starttime);
			$sec_remaining = floor($remaining);
			$usec_remaining = floor(($remaining - $sec_remaining) * 1000000);
			$r_copy = array($pipes[1], $pipes[2]);
		}
		fclose($pipes[1]);
		fclose($pipes[2]);
		$status = proc_get_status($process);
		if($status.running)
		{
			proc_terminate($process);
			$return_value = -1;
		}
		else
		{
			$return_value = proc_close($process);
		}

		return array($return_value, $output, $error);
    }
    else
        die("Cannot open $executable");
}
?>


More information about the pkg-php-maint mailing list