From: Yann Ylavic Date: Mon, 29 Jun 2015 17:52:00 +0000 (+0000) Subject: http: follow up to r1484852. X-Git-Tag: 2.5.0-alpha~3037 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dc7df095edf962ddbfbf1c2a6d3f7d85da68b5ca;p=thirdparty%2Fapache%2Fhttpd.git http: follow up to r1484852. 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 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1688274 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 657d7f22a52..22d4e00c33d 100644 --- 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 ] + *) mod_ldap: In some case, LDAP_NO_SUCH_ATTRIBUTE could be returned instead of an error during a compare operation. [Eric Covener] diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c index a4e01504236..80c8bcb6b30 100644 --- a/modules/http/http_filters.c +++ b/modules/http/http_filters.c @@ -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: {