php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #37726 proc_open let fd opened in the child process
Submitted: 2006-06-07 10:56 UTC Modified: 2006-09-09 13:43 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:2 (100.0%)
From: n dot escuder at intra-links dot com Assigned:
Status: Not a bug Package: Program Execution
PHP Version: 5.1.4 OS: 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: n dot escuder at intra-links dot com
New email:
PHP Version: OS:

 

 [2006-06-07 10:56 UTC] n dot escuder at intra-links dot com
Description:
------------
When executing a program with proc_open the child process that is started by proc_open have all fd's that was opened in the master script ex: file, database connection ....

The child process must don't have any fd open expect the fd specified by $descriptorspec.

Reproduce code:
---------------
<?
$fd = fopen("/tmp/test.log", "w");

$descriptorspec = array(
   0 => array("pipe", "r"),
   1 => array("pipe", "w"),
   2 => array("pipe", "w")
);

$pipes = null;

$process = proc_open("ls /proc/self/fd -l", $descriptorspec, $pipes);

while ( ( $line = fgets($pipes[1]) ) ) {
  echo $line;
}
proc_close( $process );
fclose($fd );
?>


Expected result:
----------------
total 5
lr-x------ 1 root root 64 2006-06-07 12:44 0 -> pipe:[22573]
l-wx------ 1 root root 64 2006-06-07 12:44 1 -> pipe:[22574]
l-wx------ 1 root root 64 2006-06-07 12:44 2 -> pipe:[22575]
lr-x------ 1 root root 64 2006-06-07 12:44 3 -> /proc/19964/fd


Actual result:
--------------
total 5
lr-x------ 1 root root 64 2006-06-07 12:44 0 -> pipe:[22573]
l-wx------ 1 root root 64 2006-06-07 12:44 1 -> pipe:[22574]
l-wx------ 1 root root 64 2006-06-07 12:44 2 -> pipe:[22575]
l-wx------ 1 root root 64 2006-06-07 12:44 3 -> /tmp/test.log
lr-x------ 1 root root 64 2006-06-07 12:44 4 -> /proc/19964/fd


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-06-07 15:16 UTC] nlopess@php.net
IMHO, I think this is expected. When you fork under unix the open file descriptors will be copied to the child process. proc_open just enforces what the specified fd should look like.
 [2006-06-07 17:08 UTC] n dot escuder at intra-links dot com
Yes when we do a pcntl_fork or a fork in C the FD must stay open but here it's a complety new program that is started.
Proc_open use fork for starting the new process but don't cleanup open descriptor after the fork.
 [2006-06-25 17:51 UTC] jdolecek at NetBSD dot org
This may be the same problem as Bug #34794, which includes the fix.
 [2006-06-26 07:55 UTC] n dot escuder at intra-links dot com
This is not the same in the bug #34794 the patch i see is only for new opened descriptor and not all opened descriptor ( databases connections ... ).
In proc_open you use fork for creating a new child and change de descriptor of STDIN STDOUT STDERR and after you do an exec.
Just before doing the exec you must close all open descriptor greater than STDERR.
 [2006-09-08 20:57 UTC] tony2001@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php


 [2006-09-09 13:30 UTC] n dot escuder at intra-links dot com
Hello,

When we create a child process on unix with fork and execl as php does in proc_open we must cleanup all open fd execpt 0 1 2 before call execl to have a clean child.

I think this is a bug because if in a script you open an sqlite query ex: update ... and you start a proc_open the proc_open will have the fd to the db dans the parent process will have a lock on the database.

Any childs process must not herit the parent fd's !

I use php cli version and start a lot of process system from an php script parent and all child get all fd's from the parent ( connection to database, files opened ... ). 
This is not clean because all process are new process started by proc_open and not pcntl_fork.

See You.

Escuder Nicolas

PS: I'm french so sorry for the traduction ;)
 [2006-09-09 13:43 UTC] tony2001@php.net
Please read what nlopess@php.net said.
No bug here.
 [2011-05-02 14:51 UTC] bogdan at moongate dot ro
This *is* a bug. When you use fork(), the child process can still use (and more importantly, close) whatever sockets and handlers you had opened in the parent process. But when you use pcntl_open(), you start a new process from scratch, and the parent's sockets and handlers are not accessible. So you're basically inheriting useless garbage; if my assumptions above are correct then I don't see how this could not be a bug.

However, if there are any scenarios where you would genuinely need/want to inherit those resources from the parent process then a PoC on how to access those resources in the child process would be very helpful. And even if that's the case, proc_open() should accept an additional parameter specifying whether they are needed or not.

Finally, at the very least, the documentation should make it very clear that this is happening. I will have to rewrite a significant portion of a project I'm working on because I had no idea this was happening, and my child processes (which are not PHP) are inheriting the parent's listening sockets (which they will never need, never access, and cause trouble all around)...
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 21:01:27 2024 UTC