]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Merge r1710095, r1727544 from trunk:
authorYann Ylavic <ylavic@apache.org>
Wed, 31 Aug 2016 19:52:28 +0000 (19:52 +0000)
committerYann Ylavic <ylavic@apache.org>
Wed, 31 Aug 2016 19:52:28 +0000 (19:52 +0000)
core: Limit to ten the number of tolerated empty lines between request,
and consume them before the pipelining check to avoid possible response
delay when reading the next request without flushing.

Before this commit, the maximum number of empty lines was the same as
configured LimitRequestFields, defaulting to 100, which was way too much.
We now use a fixed/hard limit of 10 (DEFAULT_LIMIT_BLANK_LINES).

check_pipeline() is changed to check for (up to the limit) and comsume the
trailing [CR]LFs so that they won't be interpreted as pipelined requests,
otherwise we would block on the next read without flushing data, and hence
possibly delay pending response(s) until the next/real request comes in or
the keepalive timeout expires.

Finally, when the maximum number of empty line is reached in
read_request_line(), or that request line does not contains at least a method
and an (valid) URI, we can fail early and avoid some failure detected in
further processing.

* Ensure that proto_num and protocol is set in another "error out early" edge
  case. This can happen with invalid CONNECT requests as described in the PR.

PR: 58929

Submitted by: ylavic, rpluem
Reviewed  by: wrowe, covener, ylavic

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@1758672 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
include/httpd.h
server/protocol.c

diff --git a/CHANGES b/CHANGES
index 07c02d03d601eaea427790757927166896ed06c0..3f81842f044f5ddf8c548d717a5b4da9f0312758 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,9 @@ Changes with Apache 2.2.32
   *) core: CVE-2016-5387: Mitigate [f]cgi "httpoxy" issues.
      [Dominic Scheirlinck <dominic vendhq.com>, Yann Ylavic]
 
+  *) core: Limit to ten the number of tolerated empty lines between request.
+     [Yann Ylavic]
+
   *) Core: reject NULLs in request line or request headers.
      PR 43039 [Nick Kew]
 
index 2682247ec86e518ef388989acbc3e23154566232..6f4c3d4538ea1b23e526d42417fe0e473a51cbbb 100644 (file)
@@ -205,6 +205,10 @@ extern "C" {
 #ifndef DEFAULT_LIMIT_REQUEST_FIELDS
 #define DEFAULT_LIMIT_REQUEST_FIELDS 100
 #endif 
+/** default/hard limit on number of leading/trailing empty lines */
+#ifndef DEFAULT_LIMIT_BLANK_LINES
+#define DEFAULT_LIMIT_BLANK_LINES 10
+#endif
 
 /**
  * The default default character set name to add if AddDefaultCharset is
index c3a034e504d73c2728f4dde7fc131206cf3161b1..a05ece13143a1ea150c51a2f572937720047542b 100644 (file)
@@ -563,12 +563,7 @@ static int read_request_line(request_rec *r, apr_bucket_brigade *bb)
     unsigned int major = 1, minor = 0;   /* Assume HTTP/1.0 if non-"HTTP" protocol */
     char http[5];
     apr_size_t len;
-    int num_blank_lines = 0;
-    int max_blank_lines = r->server->limit_req_fields;
-
-    if (max_blank_lines <= 0) {
-        max_blank_lines = DEFAULT_LIMIT_REQUEST_FIELDS;
-    }
+    int num_blank_lines = DEFAULT_LIMIT_BLANK_LINES;
 
     /* Read past empty lines until we get a real request line,
      * a read error, the connection closes (EOF), or we timeout.
@@ -615,7 +610,7 @@ static int read_request_line(request_rec *r, apr_bucket_brigade *bb)
             r->protocol  = apr_pstrdup(r->pool, "HTTP/1.0");
             return 0;
         }
-    } while ((len <= 0) && (++num_blank_lines < max_blank_lines));
+    } while ((len <= 0) && (--num_blank_lines >= 0));
 
     r->request_time = apr_time_now();
     ll = r->the_request;
@@ -623,6 +618,13 @@ static int read_request_line(request_rec *r, apr_bucket_brigade *bb)
 
     uri = ap_getword_white(r->pool, &ll);
 
+    if (!*r->method || !*uri) {
+        r->status    = HTTP_BAD_REQUEST;
+        r->proto_num = HTTP_VERSION(1,0);
+        r->protocol  = apr_pstrdup(r->pool, "HTTP/1.0");
+        return 0;
+    }
+
     /* Provide quick information about the request method as soon as known */
 
     r->method_number = ap_method_number_of(r->method);
@@ -631,6 +633,11 @@ static int read_request_line(request_rec *r, apr_bucket_brigade *bb)
     }
 
     ap_parse_uri(r, uri);
+    if (r->status != HTTP_OK) {
+        r->proto_num = HTTP_VERSION(1,0);
+        r->protocol  = apr_pstrdup(r->pool, "HTTP/1.0");
+        return 0;
+    }
 
     if (ll[0]) {
         r->assbackwards = 0;