From: Jeff Trawick Date: Thu, 11 Mar 2010 15:54:18 +0000 (+0000) Subject: merge from trunk and 2.2.x, using existing published patch for 2.0.63: X-Git-Tag: 2.0.64~61 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=99ddf96a3deb45f3cc5af06290941aadc29bc512;p=thirdparty%2Fapache%2Fhttpd.git merge from trunk and 2.2.x, using existing published patch for 2.0.63: *) SECURITY: CVE-2008-2364 (cve.mitre.org) mod_proxy_http: Better handling of excessive interim responses from origin server to prevent potential denial of service and high memory usage. Reported by Ryujiro Shibuya. [Ruediger Pluem, Joe Orton, Jim Jagielski] Reviewed by: trawick, wrowe, rpluem git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.0.x@921908 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 0dfbae62d37..25ba0d81d6c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,12 @@ -*- coding: utf-8 -*- Changes with Apache 2.0.64 + *) SECURITY: CVE-2008-2364 (cve.mitre.org) + mod_proxy_http: Better handling of excessive interim responses + from origin server to prevent potential denial of service and high + memory usage. Reported by Ryujiro Shibuya. [Ruediger Pluem, + Joe Orton, Jim Jagielski] + *) SECURITY: CVE-2010-0425 (cve.mitre.org) mod_isapi: Do not unload an isapi .dll module until the request processing is completed, avoiding orphaned callback pointers. diff --git a/STATUS b/STATUS index 9d5e7b630dc..fc12932d1b4 100644 --- a/STATUS +++ b/STATUS @@ -114,13 +114,6 @@ CURRENT RELEASE NOTES: RELEASE SHOWSTOPPERS: - * Commit /dist/httpd/patches/apply_to_2.0.63/CVE-2008-2364-patch-2.0.txt: - SECURITY: CVE-2008-2364 (cve.mitre.org) - mod_proxy_http: Better handling of excessive interim responses - from origin server to prevent potential denial of service and high - memory usage. - +1: trawick, wrowe, rpluem - * Commit http://people.apache.org/~wrowe/CVE-2010-0434.patch SECURITY: CVE-2010-0434 (cve.mitre.org) note; simpler because we had not yet cleaned up input headers for subreq diff --git a/modules/proxy/proxy_http.c b/modules/proxy/proxy_http.c index 6cc187dbcd3..ca5f038b5ff 100644 --- a/modules/proxy/proxy_http.c +++ b/modules/proxy/proxy_http.c @@ -1290,6 +1290,16 @@ static int addit_dammit(void *v, const char *key, const char *val) return 1; } +/* + * Limit the number of interim respones we sent back to the client. Otherwise + * we suffer from a memory build up. Besides there is NO sense in sending back + * an unlimited number of interim responses to the client. Thus if we cross + * this limit send back a 502 (Bad Gateway). + */ +#ifndef AP_MAX_INTERIM_RESPONSES +#define AP_MAX_INTERIM_RESPONSES 10 +#endif + static apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, proxy_http_conn_t *p_conn, @@ -1322,7 +1332,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, */ rp->proxyreq = PROXYREQ_RESPONSE; - while (received_continue) { + while (received_continue && (received_continue <= AP_MAX_INTERIM_RESPONSES)) { apr_brigade_cleanup(bb); len = ap_getline(buffer, sizeof(buffer), rp, 0); @@ -1440,7 +1450,9 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, if ((buf = apr_table_get(r->headers_out, "Content-Type"))) { ap_set_content_type(r, apr_pstrdup(p, buf)); } - ap_proxy_pre_http_request(origin,rp); + if (!ap_is_HTTP_INFO(r->status)) { + ap_proxy_pre_http_request(origin, rp); + } /* handle Via header in response */ if (conf->viaopt != via_off && conf->viaopt != via_block) { @@ -1486,6 +1498,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, if ( r->status != HTTP_CONTINUE ) { received_continue = 0; } else { + received_continue++; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, "proxy: HTTP: received 100 CONTINUE"); } @@ -1622,6 +1635,14 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, } } + /* See define of AP_MAX_INTERIM_RESPONSES for why */ + if (received_continue > AP_MAX_INTERIM_RESPONSES) { + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + apr_psprintf(p, + "Too many (%d) interim responses from origin server", + received_continue)); + } + if ( conf->error_override ) { /* the code above this checks for 'OK' which is what the hook expects */ if ( r->status == HTTP_OK )