http: follow up to r1484852.
authorYann Ylavic <ylavic@apache.org>
Mon, 29 Jun 2015 17:52:00 +0000 (17:52 +0000)
committerYann Ylavic <ylavic@apache.org>
Mon, 29 Jun 2015 17:52:00 +0000 (17:52 +0000)
Don't check LimitRequestBody when there is no (more) body.

This fixes an uninitialized use of 'totalread' in ap_http_filter() when either
the remaining or requested number of body bytes is zero, leading to an invalid
computation of bytes received.

Reported by: Michael Kaufmann <mail michael-kaufmann.ch>

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

CHANGES
modules/http/http_filters.c

diff --git a/CHANGES b/CHANGES
index 657d7f22a528b609a1d0ad16f8aa2a8fe8faf72a..22d4e00c33d862bae2c14f035c5326bb04f0088f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) http: Fix LimitRequestBody checks when there is no more bytes to read.
+     [Michael Kaufmann <mail michael-kaufmann.ch>]
+
   *) mod_ldap: In some case, LDAP_NO_SUCH_ATTRIBUTE could be returned instead of
      an error during a compare operation. [Eric Covener]
 
index a4e0150423669e7d45c60044b33f758c4e152257..80c8bcb6b3061817269d568a20dee5ce39bf6988 100644 (file)
@@ -279,7 +279,6 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
     apr_bucket *e;
     http_ctx_t *ctx = f->ctx;
     apr_status_t rv;
-    apr_off_t totalread;
     int again;
 
     conf = (core_server_config *)
@@ -503,6 +502,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
                 readbytes = ctx->remaining;
             }
             if (readbytes > 0) {
+                apr_off_t totalread;
 
                 rv = ap_get_brigade(f->next, b, mode, block, readbytes);
 
@@ -545,6 +545,23 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
                     }
                 }
 
+                /* We have a limit in effect. */
+                if (ctx->limit) {
+                    /* FIXME: Note that we might get slightly confused on
+                     * chunked inputs as we'd need to compensate for the chunk
+                     * lengths which may not really count.  This seems to be up
+                     * for interpretation.
+                     */
+                    ctx->limit_used += totalread;
+                    if (ctx->limit < ctx->limit_used) {
+                        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r,
+                                      APLOGNO(01591) "Read content length of "
+                                      "%" APR_OFF_T_FMT " is larger than the "
+                                      "configured limit of %" APR_OFF_T_FMT,
+                                      ctx->limit_used, ctx->limit);
+                        return APR_ENOSPC;
+                    }
+                }
             }
 
             /* If we have no more bytes remaining on a C-L request,
@@ -556,21 +573,6 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
                 ctx->eos_sent = 1;
             }
 
-            /* We have a limit in effect. */
-            if (ctx->limit) {
-                /* FIXME: Note that we might get slightly confused on chunked inputs
-                 * as we'd need to compensate for the chunk lengths which may not
-                 * really count.  This seems to be up for interpretation.  */
-                ctx->limit_used += totalread;
-                if (ctx->limit < ctx->limit_used) {
-                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(01591)
-                                  "Read content-length of %" APR_OFF_T_FMT
-                                  " is larger than the configured limit"
-                                  " of %" APR_OFF_T_FMT, ctx->limit_used, ctx->limit);
-                    return APR_ENOSPC;
-                }
-            }
-
             break;
         }
         case BODY_CHUNK_TRAILER: {