From: Joe Orton Date: Tue, 25 Nov 2014 09:17:19 +0000 (+0000) Subject: Merge r1640036, r1640331 from trunk: X-Git-Tag: 2.4.11~153 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f2d64096855789a51b02af4aaa8bbdfb1680bd28;p=apache Merge r1640036, r1640331 from trunk: mod_proxy_fcgi: SECURITY: CVE-2014-3583 (cve.mitre.org) Fix a potential crash with response headers' size above 8K. The code changes to mod_authnz_fcgi keep the handle_headers() function in sync between the two modules. mod_authnz_fcgi does not have this issue because it allocated a separate byte for terminating '\0'. Submitted by: ylavic, trawick Reviewed by: ylavic, trawick, mrumph git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1641551 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index a41a630f4d..a6ac6d5448 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.4.11 + + *) SECURITY: CVE-2014-3583 (cve.mitre.org) + mod_proxy_fcgi: Fix a potential crash due to buffer over-read, with + response headers' size above 8K. [Yann Ylavic, Jeff Trawick] *) SECURITY: CVE-2014-3581 (cve.mitre.org) mod_cache: Avoid a crash when Content-Type has an empty value. diff --git a/modules/aaa/mod_authnz_fcgi.c b/modules/aaa/mod_authnz_fcgi.c index 5e4a937850..401fa99507 100644 --- a/modules/aaa/mod_authnz_fcgi.c +++ b/modules/aaa/mod_authnz_fcgi.c @@ -406,13 +406,12 @@ enum { * * Returns 0 if it can't find the end of the headers, and 1 if it found the * end of the headers. */ -static int handle_headers(request_rec *r, - int *state, - char *readbuf) +static int handle_headers(request_rec *r, int *state, + const char *readbuf, apr_size_t readlen) { const char *itr = readbuf; - while (*itr) { + while (readlen--) { if (*itr == '\r') { switch (*state) { case HDR_STATE_GOT_CRLF: @@ -555,7 +554,8 @@ static apr_status_t handle_response(const fcgi_provider_conf *conf, APR_BRIGADE_INSERT_TAIL(ob, b); if (!seen_end_of_headers) { - int st = handle_headers(r, &header_state, readbuf); + int st = handle_headers(r, &header_state, + readbuf, readbuflen); if (st == 1) { int status; diff --git a/modules/proxy/mod_proxy_fcgi.c b/modules/proxy/mod_proxy_fcgi.c index 4c9bfb84dc..9f57035163 100644 --- a/modules/proxy/mod_proxy_fcgi.c +++ b/modules/proxy/mod_proxy_fcgi.c @@ -308,13 +308,12 @@ enum { * * Returns 0 if it can't find the end of the headers, and 1 if it found the * end of the headers. */ -static int handle_headers(request_rec *r, - int *state, - char *readbuf) +static int handle_headers(request_rec *r, int *state, + const char *readbuf, apr_size_t readlen) { const char *itr = readbuf; - while (*itr) { + while (readlen--) { if (*itr == '\r') { switch (*state) { case HDR_STATE_GOT_CRLF: @@ -561,7 +560,8 @@ recv_again: APR_BRIGADE_INSERT_TAIL(ob, b); if (! seen_end_of_headers) { - int st = handle_headers(r, &header_state, iobuf); + int st = handle_headers(r, &header_state, + iobuf, readbuflen); if (st == 1) { int status;