You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by sf...@apache.org on 2010/10/01 21:33:39 UTC
svn commit: r1003626 - in /httpd/httpd/trunk: CHANGES
modules/filters/mod_reqtimeout.c
Author: sf
Date: Fri Oct 1 19:33:39 2010
New Revision: 1003626
URL: http://svn.apache.org/viewvc?rev=1003626&view=rev
Log:
Fix CVE-2010-1623 in mod_reqtimeout, too. It includes a non-blocking variant
of apr_brigade_split_line().
Modified:
httpd/httpd/trunk/CHANGES
httpd/httpd/trunk/modules/filters/mod_reqtimeout.c
Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1003626&r1=1003625&r2=1003626&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Fri Oct 1 19:33:39 2010
@@ -2,6 +2,10 @@
Changes with Apache 2.3.9
+ *) SECURITY: CVE-2010-1623 (cve.mitre.org)
+ Fix a denial of service attack against mod_reqtimeout.
+ [Stefan Fritsch]
+
*) mod_cache: Support the caching of HEAD requests. [Graham Leggett]
*) htcacheclean: Allow the option to round up file sizes to a given
Modified: httpd/httpd/trunk/modules/filters/mod_reqtimeout.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/filters/mod_reqtimeout.c?rev=1003626&r1=1003625&r2=1003626&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/filters/mod_reqtimeout.c (original)
+++ httpd/httpd/trunk/modules/filters/mod_reqtimeout.c Fri Oct 1 19:33:39 2010
@@ -115,6 +115,41 @@ static apr_status_t have_lf_or_eos(apr_b
return APR_INCOMPLETE;
}
+/*
+ * Append bbIn to bbOut and merge small buckets, to avoid DoS by high memory
+ * usage
+ */
+static apr_status_t brigade_append(apr_bucket_brigade *bbOut, apr_bucket_brigade *bbIn)
+{
+ while (!APR_BRIGADE_EMPTY(bbIn)) {
+ apr_bucket *e = APR_BRIGADE_FIRST(bbIn);
+ const char *str;
+ apr_size_t len;
+ apr_status_t rv;
+
+ rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ);
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
+
+ APR_BUCKET_REMOVE(e);
+ if (APR_BUCKET_IS_METADATA(e) || len > APR_BUCKET_BUFF_SIZE/4) {
+ APR_BRIGADE_INSERT_TAIL(bbOut, e);
+ }
+ else {
+ if (len > 0) {
+ rv = apr_brigade_write(bbOut, NULL, NULL, str, len);
+ if (rv != APR_SUCCESS) {
+ apr_bucket_destroy(e);
+ return rv;
+ }
+ }
+ apr_bucket_destroy(e);
+ }
+ }
+ return APR_SUCCESS;
+}
+
#define MIN(x,y) ((x) < (y) ? (x) : (y))
static apr_status_t reqtimeout_filter(ap_filter_t *f,
@@ -217,7 +252,9 @@ static apr_status_t reqtimeout_filter(ap
if (!ccfg->tmpbb) {
ccfg->tmpbb = apr_brigade_create(f->c->pool, f->c->bucket_alloc);
}
- APR_BRIGADE_CONCAT(ccfg->tmpbb, bb);
+ rv = brigade_append(ccfg->tmpbb, bb);
+ if (rv != APR_SUCCESS)
+ break;
}
/* ... and wait for more */