Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 Jul 2014 20:22:09 +0000 (UTC)
From:      Olli Hauer <ohauer@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r362845 - in head/www/apache22: . files
Message-ID:  <201407242022.s6OKM9uC059154@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ohauer
Date: Thu Jul 24 20:22:08 2014
New Revision: 362845
URL: http://svnweb.freebsd.org/changeset/ports/362845
QAT: https://qat.redports.org/buildarchive/r362845/

Log:
  - backport upstream security fixes
  - fix build with SSL from ports [1]
  
  SECURITY: CVE-2014-0118 (cve.mitre.org)
  
  mod_deflate: The DEFLATE input filter (inflates request bodies) now
  limits the length and compression ratio of inflated request bodies to
  avoid denial of sevice via highly compressed bodies.  See directives
  DeflateInflateLimitRequestBody, DeflateInflateRatioLimit, and
  DeflateInflateRatioBurst.
  
  http://svn.apache.org/viewvc?view=revision&revision=1611426
  
  SECURITY: CVE-2014-0226 (cve.mitre.org)
  
  Fix a race condition in scoreboard handling,
  which could lead to a heap buffer overflow.  Thanks to Marek Kroemeke
  working with HP's Zero Day Initiative for reporting this.
  * include/scoreboard.h: Add ap_copy_scoreboard_worker.
  * server/scoreboard.c (ap_copy_scoreboard_worker): New function.
  * modules/generators/mod_status.c (status_handler): Use it.
  
  http://svn.apache.org/viewvc?view=revision&revision=1610515
  
  SECURITY: CVE-2014-0231 (cve.mitre.org)
  
  mod_cgid: Fix a denial of service against CGI scripts that do not consume
  stdin that could lead to lingering HTTPD child processes filling up the
  scoreboard and eventually hanging the server.
  
  http://svn.apache.org/viewvc?view=revision&revision=1611185
  
  [1] noted and testd by mat@
  
  MFH:		2014Q3
  Security:	f927e06c-1109-11e4-b090-20cf30e32f6d
  		CVE-2014-0118
  		CVE-2014-0231
  		CVE-2014-0226

Added:
  head/www/apache22/files/patch-CVE-2014-0118__mod_deflate.c   (contents, props changed)
  head/www/apache22/files/patch-CVE-2014-0226__scoreboard.c   (contents, props changed)
  head/www/apache22/files/patch-CVE-2014-0231__mod_cgid.c   (contents, props changed)
Modified:
  head/www/apache22/Makefile

Modified: head/www/apache22/Makefile
==============================================================================
--- head/www/apache22/Makefile	Thu Jul 24 20:12:51 2014	(r362844)
+++ head/www/apache22/Makefile	Thu Jul 24 20:22:08 2014	(r362845)
@@ -2,7 +2,7 @@
 
 PORTNAME=	apache22
 PORTVERSION=	2.2.27
-PORTREVISION?=	5
+PORTREVISION?=	6
 CATEGORIES=	www ipv6
 MASTER_SITES=	${MASTER_SITE_APACHE_HTTPD}
 DISTNAME=	httpd-${PORTVERSION}
@@ -153,9 +153,9 @@ pre-configure::
 	@${ECHO_MSG}	"  You can check your modules configuration by using make show-modules"
 	@${ECHO_MSG}	""
 
-# Fix build on FreeBSD-10+ with OpenSSL from ports
+# Fix build with OpenSSL from ports
 .if ${PORT_OPTIONS:MSSL}
-. if ${OPSYS} == FreeBSD && ${OSVERSION} > 1000000
+. if ${OPSYS} == FreeBSD
 .  if defined(OPENSSL_INSTALLED) && ${OPENSSL_INSTALLED} != ""
 	@${ECHO_MSG}	"===>  apply fix for FreeBSD-${OSREL} (${OSVERSION}) for usage with ${OPENSSL_INSTALLED}"
 	@${ECHO_MSG}	""
@@ -173,12 +173,12 @@ post-configure:
 post-install:
 	@${MKDIR} ${ETC_SUBDIRS:S|^|${STAGEDIR}${ETCDIR}/|}
 	${INSTALL_DATA} ${FILESDIR}/no-accf.conf ${STAGEDIR}${ETCDIR}/Includes/
-	${INSTALL_DATA} ${FILESDIR}/README_modules.d ${STAGEDIR}/${ETCDIR}/modules.d/
+	${INSTALL_DATA} ${FILESDIR}/README_modules.d ${STAGEDIR}${ETCDIR}/modules.d/
 # place for module configuration samples
 	@${MKDIR} ${STAGEDIR}/${EXAMPLESDIR}/modules.d
-	${INSTALL_DATA} ${FILESDIR}/README_modules.d ${STAGEDIR}/${EXAMPLESDIR}/modules.d
+	${INSTALL_DATA} ${FILESDIR}/README_modules.d ${STAGEDIR}${EXAMPLESDIR}/modules.d
 
-# supress warnings about all the non binary files
+# suppress warning for non binary files
 	-@${STRIP_CMD} ${STAGEDIR}${PREFIX}/sbin/* \
 		${STAGEDIR}${PREFIX}/libexec/apache22/*.so 2>/dev/null
 .if ${PORT_OPTIONS:MLOG_FORENSIC}

Added: head/www/apache22/files/patch-CVE-2014-0118__mod_deflate.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/apache22/files/patch-CVE-2014-0118__mod_deflate.c	Thu Jul 24 20:22:08 2014	(r362845)
@@ -0,0 +1,284 @@
+SECURITY: CVE-2014-0118 (cve.mitre.org)
+
+mod_deflate: The DEFLATE input filter (inflates request bodies) now
+limits the length and compression ratio of inflated request bodies to
+avoid denial of sevice via highly compressed bodies.  See directives
+DeflateInflateLimitRequestBody, DeflateInflateRatioLimit, and
+DeflateInflateRatioBurst.
+
+http://svn.apache.org/viewvc?view=revision&revision=1611426
+
+
+--- ./modules/filters/mod_deflate.c.orig	2011-08-29 17:22:22.000000000 +0200
++++ ./modules/filters/mod_deflate.c	2014-07-24 21:07:40.000000000 +0200
+@@ -37,6 +37,7 @@
+ #include "httpd.h"
+ #include "http_config.h"
+ #include "http_log.h"
++#include "http_core.h"
+ #include "apr_lib.h"
+ #include "apr_strings.h"
+ #include "apr_general.h"
+@@ -51,6 +52,9 @@
+ static const char deflateFilterName[] = "DEFLATE";
+ module AP_MODULE_DECLARE_DATA deflate_module;
+ 
++#define AP_INFLATE_RATIO_LIMIT 200
++#define AP_INFLATE_RATIO_BURST 3
++
+ typedef struct deflate_filter_config_t
+ {
+     int windowSize;
+@@ -62,6 +66,12 @@
+     char *note_output_name;
+ } deflate_filter_config;
+ 
++typedef struct deflate_dirconf_t {
++    apr_off_t inflate_limit;
++    int ratio_limit,
++        ratio_burst;
++} deflate_dirconf_t;
++
+ /* RFC 1952 Section 2.3 defines the gzip header:
+  *
+  * +---+---+---+---+---+---+---+---+---+---+
+@@ -193,6 +203,14 @@
+     return c;
+ }
+ 
++static void *create_deflate_dirconf(apr_pool_t *p, char *dummy)
++{
++    deflate_dirconf_t *dc = apr_pcalloc(p, sizeof(*dc));
++    dc->ratio_limit = AP_INFLATE_RATIO_LIMIT;
++    dc->ratio_burst = AP_INFLATE_RATIO_BURST;
++    return dc;
++}
++
+ static const char *deflate_set_window_size(cmd_parms *cmd, void *dummy,
+                                            const char *arg)
+ {
+@@ -284,6 +302,55 @@
+     return NULL;
+ }
+ 
++
++static const char *deflate_set_inflate_limit(cmd_parms *cmd, void *dirconf,
++                                      const char *arg)
++{
++    deflate_dirconf_t *dc = (deflate_dirconf_t*) dirconf;
++    char *errp;
++
++    if (APR_SUCCESS != apr_strtoff(&dc->inflate_limit, arg, &errp, 10)) {
++        return "DeflateInflateLimitRequestBody is not parsable.";
++    }
++    if (*errp || dc->inflate_limit < 0) {
++        return "DeflateInflateLimitRequestBody requires a non-negative integer.";
++    }
++
++    return NULL;
++}
++
++static const char *deflate_set_inflate_ratio_limit(cmd_parms *cmd,
++                                                   void *dirconf,
++                                                   const char *arg)
++{
++    deflate_dirconf_t *dc = (deflate_dirconf_t*) dirconf;
++    int i;
++
++    i = atoi(arg);
++    if (i <= 0)
++        return "DeflateInflateRatioLimit must be positive";
++
++    dc->ratio_limit = i;
++
++    return NULL;
++}
++
++static const char *deflate_set_inflate_ratio_burst(cmd_parms *cmd,
++                                                   void *dirconf,
++                                                   const char *arg)
++{
++    deflate_dirconf_t *dc = (deflate_dirconf_t*) dirconf;
++    int i;
++
++    i = atoi(arg);
++    if (i <= 0)
++        return "DeflateInflateRatioBurst must be positive";
++
++    dc->ratio_burst = i;
++
++    return NULL;
++}
++
+ typedef struct deflate_ctx_t
+ {
+     z_stream stream;
+@@ -294,8 +361,26 @@
+     unsigned char *validation_buffer;
+     apr_size_t validation_buffer_length;
+     int inflate_init;
++    int ratio_hits;
++    apr_off_t inflate_total;
+ } deflate_ctx;
+ 
++/* Check whether the (inflate) ratio exceeds the configured limit/burst. */
++static int check_ratio(request_rec *r, deflate_ctx *ctx,
++                       const deflate_dirconf_t *dc)
++{
++    if (ctx->stream.total_in) {
++        int ratio = ctx->stream.total_out / ctx->stream.total_in;
++        if (ratio < dc->ratio_limit) {
++            ctx->ratio_hits = 0;
++        }
++        else if (++ctx->ratio_hits > dc->ratio_burst) {
++            return 0;
++        }
++    }
++    return 1;
++}
++
+ /* Number of validation bytes (CRC and length) after the compressed data */
+ #define VALIDATION_SIZE 8
+ /* Do not update ctx->crc, see comment in flush_libz_buffer */
+@@ -744,6 +829,8 @@
+     int zRC;
+     apr_status_t rv;
+     deflate_filter_config *c;
++    deflate_dirconf_t *dc;
++    apr_off_t inflate_limit;
+ 
+     /* just get out of the way of things we don't want. */
+     if (mode != AP_MODE_READBYTES) {
+@@ -751,6 +838,7 @@
+     }
+ 
+     c = ap_get_module_config(r->server->module_config, &deflate_module);
++    dc = ap_get_module_config(r->per_dir_config, &deflate_module);
+ 
+     if (!ctx) {
+         char deflate_hdr[10];
+@@ -803,11 +891,13 @@
+         if (len != 10 ||
+             deflate_hdr[0] != deflate_magic[0] ||
+             deflate_hdr[1] != deflate_magic[1]) {
++            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Failed to inflate input: wrong/partial magic bytes");
+             return APR_EGENERAL;
+         }
+ 
+         /* We can't handle flags for now. */
+         if (deflate_hdr[3] != 0) {
++            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Failed to inflate input: cannot handle deflate flags");
+             return APR_EGENERAL;
+         }
+ 
+@@ -831,6 +921,12 @@
+         apr_brigade_cleanup(ctx->bb);
+     }
+ 
++    inflate_limit = dc->inflate_limit; 
++    if (inflate_limit == 0) { 
++        /* The core is checking the deflated body, we'll check the inflated */
++        inflate_limit = ap_get_limit_req_body(f->r);
++    }
++
+     if (APR_BRIGADE_EMPTY(ctx->proc_bb)) {
+         rv = ap_get_brigade(f->next, ctx->bb, mode, block, readbytes);
+ 
+@@ -863,6 +959,17 @@
+ 
+                 ctx->stream.next_out = ctx->buffer;
+                 len = c->bufferSize - ctx->stream.avail_out;
++ 
++                ctx->inflate_total += len;
++                if (inflate_limit && ctx->inflate_total > inflate_limit) { 
++                    inflateEnd(&ctx->stream);
++                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, 
++                            "Inflated content length of %" APR_OFF_T_FMT
++                            " is larger than the configured limit"
++                            " of %" APR_OFF_T_FMT, 
++                            ctx->inflate_total, inflate_limit);
++                    return APR_ENOSPC;
++                }
+ 
+                 ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
+                 tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len,
+@@ -891,6 +998,26 @@
+                     ctx->stream.next_out = ctx->buffer;
+                     len = c->bufferSize - ctx->stream.avail_out;
+ 
++                      ctx->inflate_total += len;
++                      if (inflate_limit && ctx->inflate_total > inflate_limit) { 
++                          inflateEnd(&ctx->stream);
++                          ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
++                                  "Inflated content length of %" APR_OFF_T_FMT
++                                  " is larger than the configured limit"
++                                  " of %" APR_OFF_T_FMT, 
++                                  ctx->inflate_total, inflate_limit);
++                          return APR_ENOSPC;
++                      }
++
++                      if (!check_ratio(r, ctx, dc)) {
++                          inflateEnd(&ctx->stream);
++                          ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, 
++                                  "Inflated content ratio is larger than the "
++                                  "configured limit %i by %i time(s)",
++                                  dc->ratio_limit, dc->ratio_burst);
++                          return APR_EINVAL;
++                      }
++
+                     ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
+                     tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len,
+                                                       NULL, f->c->bucket_alloc);
+@@ -1003,6 +1130,7 @@
+     int zRC;
+     apr_status_t rv;
+     deflate_filter_config *c;
++    deflate_dirconf_t *dc;
+ 
+     /* Do nothing if asked to filter nothing. */
+     if (APR_BRIGADE_EMPTY(bb)) {
+@@ -1010,6 +1138,7 @@
+     }
+ 
+     c = ap_get_module_config(r->server->module_config, &deflate_module);
++    dc = ap_get_module_config(r->per_dir_config, &deflate_module);
+ 
+     if (!ctx) {
+ 
+@@ -1272,6 +1401,14 @@
+         while (ctx->stream.avail_in != 0) {
+             if (ctx->stream.avail_out == 0) {
+ 
++                if (!check_ratio(r, ctx, dc)) {
++                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, 
++                            "Inflated content ratio is larger than the "
++                            "configured limit %i by %i time(s)",
++                            dc->ratio_limit, dc->ratio_burst);
++                    return APR_EINVAL;
++                }
++
+                 ctx->stream.next_out = ctx->buffer;
+                 len = c->bufferSize - ctx->stream.avail_out;
+ 
+@@ -1346,12 +1483,20 @@
+                   "Set the Deflate Memory Level (1-9)"),
+     AP_INIT_TAKE1("DeflateCompressionLevel", deflate_set_compressionlevel, NULL, RSRC_CONF,
+                   "Set the Deflate Compression Level (1-9)"),
++    AP_INIT_TAKE1("DeflateInflateLimitRequestBody", deflate_set_inflate_limit, NULL, OR_ALL,
++                  "Set a limit on size of inflated input"),
++    AP_INIT_TAKE1("DeflateInflateRatioLimit", deflate_set_inflate_ratio_limit, NULL, OR_ALL,
++                  "Set the inflate ratio limit above which inflation is "
++                  "aborted (default: " APR_STRINGIFY(AP_INFLATE_RATIO_LIMIT) ")"),
++    AP_INIT_TAKE1("DeflateInflateRatioBurst", deflate_set_inflate_ratio_burst, NULL, OR_ALL,
++                  "Set the maximum number of following inflate ratios above limit "
++                  "(default: " APR_STRINGIFY(AP_INFLATE_RATIO_BURST) ")"),
+     {NULL}
+ };
+ 
+ module AP_MODULE_DECLARE_DATA deflate_module = {
+     STANDARD20_MODULE_STUFF,
+-    NULL,                         /* dir config creater */
++    create_deflate_dirconf,       /* dir config creater */
+     NULL,                         /* dir merger --- default is to override */
+     create_deflate_server_config, /* server config */
+     NULL,                         /* merge server config */

Added: head/www/apache22/files/patch-CVE-2014-0226__scoreboard.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/apache22/files/patch-CVE-2014-0226__scoreboard.c	Thu Jul 24 20:22:08 2014	(r362845)
@@ -0,0 +1,82 @@
+SECURITY: CVE-2014-0226 (cve.mitre.org)
+
+Fix a race condition in scoreboard handling,
+which could lead to a heap buffer overflow.  Thanks to Marek Kroemeke
+working with HP's Zero Day Initiative for reporting this.
+* include/scoreboard.h: Add ap_copy_scoreboard_worker.
+* server/scoreboard.c (ap_copy_scoreboard_worker): New function.
+* modules/generators/mod_status.c (status_handler): Use it.
+
+http://svn.apache.org/viewvc?view=revision&revision=1610515
+
+--- ./include/scoreboard.h.orig	2007-12-08 17:59:08.000000000 +0100
++++ ./include/scoreboard.h	2014-07-24 21:07:40.000000000 +0200
+@@ -189,7 +189,24 @@
+                                                     int status, request_rec *r);
+ void ap_time_process_request(ap_sb_handle_t *sbh, int status);
+ 
++/** Return a pointer to the worker_score for a given child, thread pair.
++ * @param child_num The child number.
++ * @param thread_num The thread number.
++ * @return A pointer to the worker_score structure.
++ * @deprecated This function is deprecated, use ap_copy_scoreboard_worker instead. 
++ */
+ AP_DECLARE(worker_score *) ap_get_scoreboard_worker(int x, int y);
++
++/** Copy the contents of a worker's scoreboard entry.  The contents of
++ * the worker_score structure are copied verbatim into the dest
++ * structure.
++ * @param dest Output parameter.
++ * @param child_num The child number.
++ * @param thread_num The thread number.
++ */
++AP_DECLARE(void) ap_copy_scoreboard_worker(worker_score *dest,
++                                           int child_num, int thread_num);
++
+ AP_DECLARE(process_score *) ap_get_scoreboard_process(int x);
+ AP_DECLARE(global_score *) ap_get_scoreboard_global(void);
+ AP_DECLARE(lb_score *) ap_get_scoreboard_lb(int lb_num);
+--- ./server/scoreboard.c.orig	2012-07-24 15:46:40.000000000 +0200
++++ ./server/scoreboard.c	2014-07-24 21:07:40.000000000 +0200
+@@ -510,6 +510,21 @@
+     return &ap_scoreboard_image->servers[x][y];
+ }
+ 
++AP_DECLARE(void) ap_copy_scoreboard_worker(worker_score *dest, 
++                                           int child_num,
++                                           int thread_num)
++{
++    worker_score *ws = ap_get_scoreboard_worker(child_num, thread_num);
++
++    memcpy(dest, ws, sizeof *ws);
++
++    /* For extra safety, NUL-terminate the strings returned, though it
++     * should be true those last bytes are always zero anyway. */
++    dest->client[sizeof(dest->client) - 1] = '\0';
++    dest->request[sizeof(dest->request) - 1] = '\0';
++    dest->vhost[sizeof(dest->vhost) - 1] = '\0';
++}
++
+ AP_DECLARE(process_score *) ap_get_scoreboard_process(int x)
+ {
+     if ((x < 0) || (server_limit < x)) {
+--- ./modules/generators/mod_status.c.orig	2013-02-18 17:52:21.000000000 +0100
++++ ./modules/generators/mod_status.c	2014-07-24 21:07:40.000000000 +0200
+@@ -241,7 +241,7 @@
+ #endif
+     int short_report;
+     int no_table_report;
+-    worker_score *ws_record;
++    worker_score *ws_record = apr_palloc(r->pool, sizeof *ws_record);
+     process_score *ps_record;
+     char *stat_buffer;
+     pid_t *pid_buffer, worker_pid;
+@@ -333,7 +333,7 @@
+         for (j = 0; j < thread_limit; ++j) {
+             int indx = (i * thread_limit) + j;
+ 
+-            ws_record = ap_get_scoreboard_worker(i, j);
++            ap_copy_scoreboard_worker(ws_record, i, j);
+             res = ws_record->status;
+             stat_buffer[indx] = status_flags[res];
+ 

Added: head/www/apache22/files/patch-CVE-2014-0231__mod_cgid.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/apache22/files/patch-CVE-2014-0231__mod_cgid.c	Thu Jul 24 20:22:08 2014	(r362845)
@@ -0,0 +1,152 @@
+SECURITY: CVE-2014-0231 (cve.mitre.org)
+
+mod_cgid: Fix a denial of service against CGI scripts that do not consume
+stdin that could lead to lingering HTTPD child processes filling up the
+scoreboard and eventually hanging the server.
+
+http://svn.apache.org/viewvc?view=revision&revision=1611185
+
+
+--- ./modules/generators/mod_cgid.c.orig	2009-08-03 16:38:53.000000000 +0200
++++ ./modules/generators/mod_cgid.c	2014-07-24 21:07:40.000000000 +0200
+@@ -93,6 +93,10 @@
+ static pid_t parent_pid;
+ static ap_unix_identity_t empty_ugid = { (uid_t)-1, (gid_t)-1, -1 };
+ 
++typedef struct { 
++    apr_interval_time_t timeout;
++} cgid_dirconf;
++
+ /* The APR other-child API doesn't tell us how the daemon exited
+  * (SIGSEGV vs. exit(1)).  The other-child maintenance function
+  * needs to decide whether to restart the daemon after a failure
+@@ -934,7 +938,14 @@
+     return overrides->logname ? overrides : base;
+ }
+ 
++static void *create_cgid_dirconf(apr_pool_t *p, char *dummy)
++{
++    cgid_dirconf *c = (cgid_dirconf *) apr_pcalloc(p, sizeof(cgid_dirconf));
++    return c;
++}
++
+ static const char *set_scriptlog(cmd_parms *cmd, void *dummy, const char *arg)
++
+ {
+     server_rec *s = cmd->server;
+     cgid_server_conf *conf = ap_get_module_config(s->module_config,
+@@ -987,7 +998,16 @@
+ 
+     return NULL;
+ }
++static const char *set_script_timeout(cmd_parms *cmd, void *dummy, const char *arg)
++{
++    cgid_dirconf *dc = dummy;
+ 
++    if (ap_timeout_parameter_parse(arg, &dc->timeout, "s") != APR_SUCCESS) { 
++        return "CGIDScriptTimeout has wrong format";
++    }
++ 
++    return NULL;
++}
+ static const command_rec cgid_cmds[] =
+ {
+     AP_INIT_TAKE1("ScriptLog", set_scriptlog, NULL, RSRC_CONF,
+@@ -999,6 +1019,10 @@
+     AP_INIT_TAKE1("ScriptSock", set_script_socket, NULL, RSRC_CONF,
+                   "the name of the socket to use for communication with "
+                   "the cgi daemon."),
++    AP_INIT_TAKE1("CGIDScriptTimeout", set_script_timeout, NULL, RSRC_CONF | ACCESS_CONF,
++                  "The amount of time to wait between successful reads from "
++                  "the CGI script, in seconds."),
++                  
+     {NULL}
+ };
+ 
+@@ -1335,11 +1359,15 @@
+     apr_file_t *tempsock;
+     struct cleanup_script_info *info;
+     apr_status_t rv;
++    cgid_dirconf *dc;
+ 
+     if (strcmp(r->handler,CGI_MAGIC_TYPE) && strcmp(r->handler,"cgi-script"))
+         return DECLINED;
+ 
+     conf = ap_get_module_config(r->server->module_config, &cgid_module);
++    dc = ap_get_module_config(r->per_dir_config, &cgid_module);
++
++    
+     is_included = !strcmp(r->protocol, "INCLUDED");
+ 
+     if ((argv0 = strrchr(r->filename, '/')) != NULL)
+@@ -1412,6 +1440,12 @@
+      */
+ 
+     apr_os_pipe_put_ex(&tempsock, &sd, 1, r->pool);
++    if (dc->timeout > 0) { 
++        apr_file_pipe_timeout_set(tempsock, dc->timeout);
++    }
++    else { 
++        apr_file_pipe_timeout_set(tempsock, r->server->timeout);
++    }
+     apr_pool_cleanup_kill(r->pool, (void *)((long)sd), close_unix_socket);
+ 
+     if ((argv0 = strrchr(r->filename, '/')) != NULL)
+@@ -1487,6 +1521,10 @@
+             if (rv != APR_SUCCESS) {
+                 /* silly script stopped reading, soak up remaining message */
+                 child_stopped_reading = 1;
++                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, 
++                              "Error writing request body to script %s", 
++                              r->filename);
++
+             }
+         }
+         apr_brigade_cleanup(bb);
+@@ -1577,7 +1615,13 @@
+             return HTTP_MOVED_TEMPORARILY;
+         }
+ 
+-        ap_pass_brigade(r->output_filters, bb);
++        rv = ap_pass_brigade(r->output_filters, bb);
++        if (rv != APR_SUCCESS) { 
++            /* APLOG_ERR because the core output filter message is at error,
++             * but doesn't know it's passing CGI output 
++             */
++            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "Failed to flush CGI output to client");
++        }
+     }
+ 
+     if (nph) {
+@@ -1707,6 +1751,8 @@
+     request_rec *r = f->r;
+     cgid_server_conf *conf = ap_get_module_config(r->server->module_config,
+                                                   &cgid_module);
++    cgid_dirconf *dc = ap_get_module_config(r->per_dir_config, &cgid_module);
++
+     struct cleanup_script_info *info;
+ 
+     add_ssi_vars(r);
+@@ -1736,6 +1782,13 @@
+      * get rid of the cleanup we registered when we created the socket.
+      */
+     apr_os_pipe_put_ex(&tempsock, &sd, 1, r->pool);
++    if (dc->timeout > 0) {
++        apr_file_pipe_timeout_set(tempsock, dc->timeout);
++    }
++    else {
++        apr_file_pipe_timeout_set(tempsock, r->server->timeout);
++    }
++
+     apr_pool_cleanup_kill(r->pool, (void *)((long)sd), close_unix_socket);
+ 
+     APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_pipe_create(tempsock,
+@@ -1841,7 +1894,7 @@
+ 
+ module AP_MODULE_DECLARE_DATA cgid_module = {
+     STANDARD20_MODULE_STUFF,
+-    NULL, /* dir config creater */
++    create_cgid_dirconf, /* dir config creater */
+     NULL, /* dir merger --- default is to override */
+     create_cgid_config, /* server config */
+     merge_cgid_config, /* merge server config */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201407242022.s6OKM9uC059154>