httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cove...@apache.org
Subject svn commit: r1758083 - in /httpd/httpd/trunk: CHANGES modules/generators/mod_cgid.c
Date Sat, 27 Aug 2016 23:15:11 GMT
Author: covener
Date: Sat Aug 27 23:15:11 2016
New Revision: 1758083

URL: http://svn.apache.org/viewvc?rev=1758083&view=rev
Log:
Stash the cgi PID earlier in mod_cgid

In some cases, a 2nd CGI using the same c->id can get into
the mod_cgid handler before cleanups have been run, causing
the new CGI pid to be used by the first CGI's cleanup function.

Instead of stashing c->id in the request processing thread,
just use it before leaving the handler to get the pid.

May indirectly fix PR57771, but it must have a slightly different
cause because stashing the conn_id slightly differently was 
supposed to be sufficient there.


Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/modules/generators/mod_cgid.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1758083&r1=1758082&r2=1758083&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Sat Aug 27 23:15:11 2016
@@ -1,6 +1,10 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) mod_cgid: Resolve a case where a short CGI response causes a subsequent
+     CGI to be killed prematurely, resulting in a truncated subsequent
+     response. [Eric Covener]
+
   *) mod_proxy_hcheck: Set health check URI and expression correctly for health
      check worker. PR 60038 [zdeno <zdeno@scnet.sk>]
 

Modified: httpd/httpd/trunk/modules/generators/mod_cgid.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/generators/mod_cgid.c?rev=1758083&r1=1758082&r2=1758083&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/generators/mod_cgid.c (original)
+++ httpd/httpd/trunk/modules/generators/mod_cgid.c Sat Aug 27 23:15:11 2016
@@ -1298,8 +1298,8 @@ static void discard_script_output(apr_bu
 
 struct cleanup_script_info {
     request_rec *r;
-    unsigned long conn_id;
     cgid_server_conf *conf;
+    pid_t pid;
 };
 
 static apr_status_t dead_yet(pid_t pid, apr_interval_time_t max_wait)
@@ -1351,25 +1351,19 @@ static apr_status_t cleanup_nonchild_pro
     return APR_EGENERAL;
 }
 
-static apr_status_t cleanup_script(void *vptr)
-{
-    struct cleanup_script_info *info = vptr;
-    int sd;
-    int rc;
+static apr_status_t get_cgi_pid(request_rec *r,  cgid_server_conf *conf, pid_t *pid) { 
     cgid_req_t req = {0};
-    pid_t pid;
     apr_status_t stat;
+    int rc, sd;
 
-    rc = connect_to_daemon(&sd, info->r, info->conf);
+    rc = connect_to_daemon(&sd, r, conf);
     if (rc != OK) {
         return APR_EGENERAL;
     }
 
-    /* we got a socket, and there is already a cleanup registered for it */
-
     req.req_type = GETPID_REQ;
     req.ppid = parent_pid;
-    req.conn_id = info->r->connection->id;
+    req.conn_id = r->connection->id;
 
     stat = sock_write(sd, &req, sizeof(req));
     if (stat != APR_SUCCESS) {
@@ -1377,18 +1371,26 @@ static apr_status_t cleanup_script(void
     }
 
     /* wait for pid of script */
-    stat = sock_read(sd, &pid, sizeof(pid));
+    stat = sock_read(sd, pid, sizeof(*pid));
     if (stat != APR_SUCCESS) {
         return stat;
     }
 
     if (pid == 0) {
-        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, info->r, APLOGNO(01261)
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01261)
                       "daemon couldn't find CGI process for connection %lu",
-                      info->conn_id);
+                      r->connection->id);
         return APR_EGENERAL;
     }
-    return cleanup_nonchild_process(info->r, pid);
+
+    return APR_SUCCESS;
+}
+
+
+static apr_status_t cleanup_script(void *vptr)
+{
+    struct cleanup_script_info *info = vptr;
+    return cleanup_nonchild_process(info->r, info->pid);
 }
 
 static int cgid_handler(request_rec *r)
@@ -1486,12 +1488,19 @@ static int cgid_handler(request_rec *r)
     }
 
     info = apr_palloc(r->pool, sizeof(struct cleanup_script_info));
-    info->r = r;
-    info->conn_id = r->connection->id;
     info->conf = conf;
-    apr_pool_cleanup_register(r->pool, info,
+    info->r = r;
+    rv = get_cgi_pid(r, conf, &(info->pid));
+
+    if (APR_SUCCESS == rv){  
+        apr_pool_cleanup_register(r->pool, info,
                               cleanup_script,
                               apr_pool_cleanup_null);
+    }
+    else { 
+        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "error determining cgi PID");
+    }
+
     /* We are putting the socket discriptor into an apr_file_t so that we can
      * use a pipe bucket to send the data to the client.  APR will create
      * a cleanup for the apr_file_t which will close the socket, so we'll
@@ -1816,6 +1825,7 @@ static int include_cmd(include_ctx_t *ct
     cgid_dirconf *dc = ap_get_module_config(r->per_dir_config, &cgid_module);
 
     struct cleanup_script_info *info;
+    apr_status_t rv;
 
     add_ssi_vars(r);
     env = ap_create_environment(r->pool, r->subprocess_env);
@@ -1827,13 +1837,22 @@ static int include_cmd(include_ctx_t *ct
     send_req(sd, r, command, env, SSI_REQ);
 
     info = apr_palloc(r->pool, sizeof(struct cleanup_script_info));
-    info->r = r;
-    info->conn_id = r->connection->id;
     info->conf = conf;
-    /* for this type of request, the script is invoked through an
-     * intermediate shell process...  cleanup_script is only able
-     * to knock out the shell process, not the actual script
-     */
+    info->r = r;
+    rv = get_cgi_pid(r, conf, &(info->pid));
+    if (APR_SUCCESS == rv) {             
+        /* for this type of request, the script is invoked through an
+         * intermediate shell process...  cleanup_script is only able
+         * to knock out the shell process, not the actual script
+         */
+        apr_pool_cleanup_register(r->pool, info,
+                                  cleanup_script,
+                                  apr_pool_cleanup_null);
+    }
+    else { 
+        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "error determining cgi PID (for SSI)");
+    }
+
     apr_pool_cleanup_register(r->pool, info,
                               cleanup_script,
                               apr_pool_cleanup_null);



Mime
View raw message