From 02e736ae5a7bb18b2767bbee1690fa4f0be4e6e1 Mon Sep 17 00:00:00 2001 From: Yann Ylavic Date: Wed, 12 Nov 2014 15:41:07 +0000 Subject: [PATCH] mod_proxy_fcgi: CVE-2014-3583: Fix a potential crash with response headers' size above 8K. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1638818 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 ++++ modules/proxy/mod_proxy_fcgi.c | 29 +++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 5aafa7de30..c33226fa6d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) SECURITY: CVE-2014-3583 (cve.mitre.org) + mod_proxy_fcgi: Fix a potential crash with response headers' size above 8K. + [Teguh , Yann Ylavic] + *) event: Resolve potential crashes under load after r1604350. [Eric Covener] *) mod_authnz_ldap: Resolve crashes with LDAP authz and non-LDAP authn since diff --git a/modules/proxy/mod_proxy_fcgi.c b/modules/proxy/mod_proxy_fcgi.c index ab1118238b..fb71b5074b 100644 --- a/modules/proxy/mod_proxy_fcgi.c +++ b/modules/proxy/mod_proxy_fcgi.c @@ -18,6 +18,8 @@ #include "util_fcgi.h" #include "util_script.h" +#include "apr_lib.h" /* for apr_iscntrl() */ + module AP_MODULE_DECLARE_DATA proxy_fcgi_module; /* @@ -310,13 +312,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: @@ -347,13 +348,17 @@ static int handle_headers(request_rec *r, break; } } - else { + else if (*itr == '\t' || !apr_iscntrl(*itr)) { *state = HDR_STATE_READING_HEADERS; } + else { + return -1; + } if (*state == HDR_STATE_DONE_WITH_HEADERS) break; + --readlen; ++itr; } @@ -563,7 +568,14 @@ 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) { + *err = "parsing response headers"; + rv = APR_EINVAL; + break; + } if (st == 1) { int status; @@ -684,6 +696,11 @@ recv_again: break; } + if (*err) { + /* stop on error in the above switch */ + break; + } + if (plen) { rv = get_data_full(conn, iobuf, plen); if (rv != APR_SUCCESS) { -- 2.40.0