Req #38915 [Com]: Apache: system() (and similar) don't cleanup opened handles of Apache

[email protected] ("crrodriguez at opensuse dot org")
Newsgroups php.bugs
Message-ID <[email protected]>
Edit report at http://bugs.php.net/bug.php?id=38915&edit=1

 ID:               38915
 Comment by:       crrodriguez at opensuse dot org
 Reported by:      dimmoborgir at gmail dot com
 Summary:          Apache: system() (and similar) don't cleanup opened
                   handles of Apache
 Status:           Analyzed
 Type:             Feature/Change Request
 Package:          Feature/Change Request
 Operating System: UNIX
 PHP Version:      5.2.2, 4.4.7

 New Comment:

In linux, this should fix the issue for mail()

diff --git a/ext/standard/mail.c b/ext/standard/mail.c
index ab65f16..a8b3bf5 100644
--- a/ext/standard/mail.c
+++ b/ext/standard/mail.c
@@ -288,8 +288,12 @@ PHPAPI int php_mail(char *to, char *subject, char
*message, 
char *headers, char
         * (e.g. the shell can't be executed) we explicitely set it to 0
to be
         * sure we don't catch any older errno value. */
        errno = 0;
+#if defined(__linux__) && defined(__GLIBC__) &&  __GLIBC_PREREQ(2, 9)
+       sendmail = popen(sendmail_cmd, "we");
+#else 
        sendmail = popen(sendmail_cmd, "w");
 #endif
+#endif
        if (extra_cmd != NULL) {
                efree (sendmail_cmd);
        }


Note that you need glibc 2.9 though.


Previous Comments:
------------------------------------------------------------------------
[2010-02-22 19:16:37] ionut dot dumitru at webland dot ro

the problem is still there in 5.2 just with php not involving apache.
so i write a cli daemon A which uses a listener socket , at some point
it starts another daemon B with any of exec/system/popen etc. 'A' works
as a sort of supervisor for B so i can't shut it down. but at some point
i need to restart A, well I can't cause it won't bind to the same
listener address anymore because B is keeping the handles open. spent a
lot of time but i guess i have to go the file/cron way since php can't
clean itself.

------------------------------------------------------------------------
[2009-12-23 18:45:09] devrim at kodingen dot com

Apparently Jeroen's closedexec.c code is not available from his
website,

here is my copy: http://pastie.org/754717

It is very useful to us, and that fix is still not there.

------------------------------------------------------------------------
[2009-07-03 00:38:14] [email protected]

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.


------------------------------------------------------------------------
[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.

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


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/bug.php?id=38915


-- 
Edit this bug report at http://bugs.php.net/bug.php?id=38915&edit=1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.