]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Fix CVE-2010-1623 in mod_reqtimeout, too. It includes a non-blocking variant
authorStefan Fritsch <sf@apache.org>
Fri, 1 Oct 2010 19:33:39 +0000 (19:33 +0000)
committerStefan Fritsch <sf@apache.org>
Fri, 1 Oct 2010 19:33:39 +0000 (19:33 +0000)
of apr_brigade_split_line().

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1003626 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/filters/mod_reqtimeout.c

diff --git a/CHANGES b/CHANGES
index 3c743cfb20635b2ae8c2a75065800c7a9a16069c..c6b02a24f989628a6d5e37800bcc97c61b582cd4 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -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
index b0de997b8e7548bd0d7164399ce536ad6e36f306..adc4defc2c5de68f6cef6664275e7109566f02c4 100644 (file)
@@ -115,6 +115,41 @@ static apr_status_t have_lf_or_eos(apr_bucket_brigade *bb)
     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_filter_t *f,
                 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 */