|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #67383 exec() leaks file and socket descriptors to called program
Submitted: 2014-06-05 11:25 UTC Modified: 2014-08-04 19:35 UTC
Avg. Score:4.5 ± 0.8
Reproduced:15 of 15 (100.0%)
Same Version:10 (66.7%)
Same OS:12 (80.0%)
From: Assigned:
Status: Open Package: *General Issues
PHP Version: Irrelevant OS: linux
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2014-06-05 11:25 UTC]
PHP doesn't sanitize opened file descriptors opened by PHP itself before executing a program.

This should be fixed by opening all sockets with SOCK_CLOEXEC and all run a fcntl(file, F_SETFD, FD_CLOEXEC); on all newly opened filedescriptors

SOCK_CLOEXEC and FD_CLOEXEC cause exec() to close the descriptors in the fork()ed child process.

Note that this is similar, but not identical to bug #38915, bug #15529 and  bug #20302 which are about file descriptors and sockets opened by Apache.

Note that my patch also sets SOCK_CLOEXEC on the fastcgi listening socket and other similar usages of sockets.

The patch was generated on php-src master branch. I'm happy to do some more work on it if any of you feel this is required.


SOCK_CLOEXEC-and-FD_CLOEXEC (last revision 2014-06-05 11:26 UTC by casper at langemeijer dot eu)

Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2014-07-21 11:54 UTC]
-Status: Open +Status: Duplicate
 [2014-07-21 11:54 UTC]
This is a duplicate of bug #67383 (Which contains a patch that should be merged by someone!)
 [2014-08-04 19:35 UTC]
-Status: Duplicate +Status: Open
 [2014-08-04 19:35 UTC]
Obviously, this bug is not a duplicate of itself. Previous comment was a clerical error.
 [2016-01-26 16:41 UTC] brak at gameservers dot com
This issue can cause you to be unable to restart PHP-FPM.  Specifically, this leaks the webserver -> php-fpm socket to any process you execute.  This prevents PHP-FPM from cleanly restarting until the process exits, because the socket will already be in use.

Quick example:
        $p = popen('/bin/bash -c "sleep 60"','w');

Now find the child process (ps aux | grep sleep) and lsof -p XXX -n:

sleep   13443 nobody    0r  FIFO      0,8      0t0 10237775 pipe
sleep   13443 nobody    1u   CHR      1,3      0t0     3920 /dev/null
sleep   13443 nobody    2u   CHR      1,3      0t0     3920 /dev/null
sleep   13443 nobody    4u  IPv4 10236693      0t0      TCP> (ESTABLISHED)
sleep   13443 nobody    9u   REG      0,9        0     3918 [eventpoll]

FD 4 there is the TCP connection from the PHP worker process to the web server.
 [2017-10-11 08:29 UTC]
It is, in my opinion, not desirable to do this blindly for all fds.

It should be possible to specify this on a per-fd basis. For streams this can be done with a context option (or multiple context options for sockets vs files), but for e.g. mysqlnd it's trickier - most likely these should default to not being inheritable, but this will need to be taken care of by the extension.

A stream context option would cover 99% of cases where it's relevant, though. I would be fine with having the context option default to setting the flag, and needing to explicitly make an fd heritable, but this would be a BC break.
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Mar 04 03:01:30 2024 UTC