Aaron Bannert wrote:

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;
     }

Reply via email to