On Thursday, March 20, 2003, at 01:50 PM, [EMAIL PROTECTED] wrote:
wrowe 2003/03/20 13:50:41
Modified: . CHANGES modules/loggers mod_log_config.c modules/mappers mod_rewrite.c server log.c mpm_common.c server/mpm/worker pod.c Log: SECURITY: Eliminated leaks of several file descriptors to child processes, such as CGI scripts.
[...]
apr_sockaddr_info_get(&(*pod)->sa, ap_listeners->bind_addr->hostname,
APR_UNSPEC, ap_listeners->bind_addr->port, 0, p);
+ /* close these before exec. */ + apr_file_unset_inherit((*pod)->pod_in); + apr_file_unset_inherit((*pod)->pod_out); + return APR_SUCCESS;
The PODs in the worker MPM are getting closed and the parent is then unable to kill its children when it needs to (don't you love how morbid that sounds?). I see one of these every second in the error log:
[Thu Mar 20 18:09:25 2003] [warn] (32)Broken pipe: write pipe_of_death
lots of theories :)
what I see with HEAD is that the pipe gets file descriptor 2 (stderr), and we later make sure that the error log is file descriptor 2, resulting in one side of the pipe getting closed
I would guess that some other changes with closing descriptors let us get fd 2 for one of the pipe handles, and that this conceivably could have happened with all sorts of code changes.
Attached is a patch which certainly is not a fix, but which makes it work for me by clumsily ensuring that neither pipe descriptor is stdin/out/err; no more problems writing to the pipe at this point.
Index: server/mpm/worker/pod.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/mpm/worker/pod.c,v
retrieving revision 1.8
diff -u -r1.8 pod.c
--- server/mpm/worker/pod.c 20 Mar 2003 21:50:40 -0000 1.8
+++ server/mpm/worker/pod.c 21 Mar 2003 16:09:11 -0000
@@ -65,9 +65,18 @@
AP_DECLARE(apr_status_t) ap_mpm_pod_open(apr_pool_t *p, ap_pod_t **pod)
{
apr_status_t rv;
+ int fd1, fd2, fd3;
+
+ /* make darn sure that the pod doesn't collide with stdin/out/err */
+ fd1 = socket(AF_INET, SOCK_STREAM, 0);
+ fd2 = socket(AF_INET, SOCK_STREAM, 0);
+ fd3 = socket(AF_INET, SOCK_STREAM, 0);
*pod = apr_palloc(p, sizeof(**pod));
rv = apr_file_pipe_create(&((*pod)->pod_in), &((*pod)->pod_out), p);
+
+ close(fd1); close(fd2); close(fd3);
+
if (rv != APR_SUCCESS) {
return rv;
}
