ID:               38915
 Updated by:       ras...@php.net
 Reported By:      dimmoborgir at gmail dot com
-Status:           Open
+Status:           Analyzed
 Bug Type:         Feature/Change Request
 Operating System: UNIX
 PHP Version:      5.2.2, 4.4.7
 New Comment:

This is finally fixed in Apache now.

https://issues.apache.org/bugzilla/show_bug.cgi?id=46425

It really is the responsibility of initiator of an fd to set the
O_CLOEXEC flag on it.  Going back and trying to do it after the fact is
really messy because we don't have direct access to these fds.  Since I
can't think of a portable way to get a list of all open fds, we would
have to pick some arbitrary number and loop through and set FD_CLOEXEC
on the first N fds.

Something like this:

Index: ext/standard/exec.c
===================================================================
RCS file: /repository/php-src/ext/standard/exec.c,v
retrieving revision 1.113.2.3.2.13
diff -u -r1.113.2.3.2.13 exec.c
--- ext/standard/exec.c 30 Apr 2009 15:25:05 -0000      1.113.2.3.2.13
+++ ext/standard/exec.c 3 Jul 2009 00:35:25 -0000
@@ -101,6 +101,17 @@
        sig_handler = signal (SIGCHLD, SIG_DFL);
 #endif
 
+#if defined(F_SETFD) && defined(FD_CLOEXEC)
+       {
+               int i, oldflags;
+               for(i=0; i<10; i++) {
+                       oldflags = fcntl(i, F_GETFD, 0);
+                       oldflags |= FD_CLOEXEC;
+                       fcntl(i, F_SETFD, oldflags);
+               }
+       }
+#endif
+
 #ifdef PHP_WIN32
        fp = VCWD_POPEN(cmd_p, "rb");
 #else

and something similar would have to be done in the other places we
fork, like in mail().  This is extremely ugly, as far as I am concerned,
and likely doesn't catch everything anyway.

If someone sees a clean way of fixing this that I have missed, please
let us know.  Otherwise I would encourage you to upgrade your Apache or
lean on whatever web server you are using that is passing dirty fds to
us.



Previous Comments:
------------------------------------------------------------------------

[2009-06-25 16:07:50] virus at tgu dot ru

OMG...
It's still didn't fixed... :(

------------------------------------------------------------------------

[2008-08-26 13:08:53] anomie at users dot sf dot net

It seems that it could easily be fixed by having mod_php use the
Apache-provided functions which are intended to solve exactly this
problem, but the PHP developers seem to have decided to ignore this bug
instead.

Rather than a cron script, use a trampoline program like the one posted
by jeroen at unfix dot org; we have something similar here, although
ours doesn't impose an arbitrary run time limit.

------------------------------------------------------------------------

[2008-08-20 13:28:45] peterspoon at abv dot bg

SO, can this problem be fixed within PHP/Apache or it cannot?
Do you think using funny scripts started by cron is a solution?

------------------------------------------------------------------------

[2008-05-27 15:12:09] jeroen at unfix dot org

My solution to this very annoying issue (especially when Apache is
reloaded and the from PHP spawned app is still running and your
webserver thus simply dies off as the apache processes are gone, but the
spawned app keeps port 80 etc open for you, thus making Apache never
start again...

http://unfix.org/~jeroen/archive/closedexec.c

Compile: cc -o /usr/bin/closedexec closedexec.c

Just call it like: system("/usr/bin/closedexec /path/to/exe arg arg
arg") or whatever call you where using in PHP.

It first closes all sockets !1|!2 (stdout/stderr), setsid()'s, forks,
and then execv's the args given, doing a waitpid() in the other thread
and killing the process when it runs longer than 5 minutes.

------------------------------------------------------------------------

[2008-04-30 00:06:18] support at ppnhosting dot com

5.2.3
also experiencing this 'bug' to the point of having to manually kill
Exim to just Apache restarted.. the mail() function is suffering from
the same problem. It is very annoying to see Apache failing to 
restart, because the MTA (exim via sendmail in our case) is already 
listening on port *:80

------------------------------------------------------------------------

The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
    http://bugs.php.net/38915

-- 
Edit this bug report at http://bugs.php.net/?id=38915&edit=1

Reply via email to