From: Joe Orton Date: Fri, 3 Jul 2009 13:48:25 +0000 (+0000) Subject: Merge r790587 from trunk: X-Git-Tag: 2.2.12~61 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7c86cedd3b117aaba17ea62a8c91b87c7d8bcfea;p=thirdparty%2Fapache%2Fhttpd.git Merge r790587 from trunk: Security fix for CVE-2009-1890: * modules/proxy/mod_proxy_http.c (stream_reqbody_cl): Specify the base passed to apr_strtoff, and validate the Content-Length in the same way the HTTP_IN filter does. If the number of bytes streamed exceeds the expected body length, bail out of the loop. Thanks to: Toadie for reporting and diagnosis of this issue. Submitted by: niq, jorton Reviewed by: rpluem, jim, jorton git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@790914 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 4729b64490c..b0b4d41488f 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,11 @@ Changes with Apache 2.2.12 [Jonathan Peatfield , Joe Orton, Ruediger Pluem, Jeff Trawick] + *) SECURITY: CVE-2009-1890 (cve.mitre.org) + Fix a potential Denial-of-Service attack against mod_proxy in a + reverse proxy configuration, where a remote attacker can force a + proxy process to consume CPU time indefinitely. [Nick Kew, Joe Orton] + *) SECURITY: CVE-2009-1191 (cve.mitre.org) mod_proxy_ajp: Avoid delivering content from a previous request which failed to send a request body. PR 46949 [Ruediger Pluem] diff --git a/STATUS b/STATUS index 495e5b5f5ff..3a6469cf8d1 100644 --- a/STATUS +++ b/STATUS @@ -82,14 +82,6 @@ CURRENT RELEASE NOTES: RELEASE SHOWSTOPPERS: - * SECURITY: CVE-2009-1890 (cve.mitre.org) - Fix a potential Denial-of-Service attack against mod_proxy in a - reverse proxy configuration, where a remote attacker can force a - proxy process to consume CPU time indefinitely. [Nick Kew, Joe Orton] - Trunk version of patch works: - http://svn.apache.org/viewvc?view=rev&revision=790587 - +1: rpluem, jim - * SECURITY: CVE-2009-1891 (cve.mitre.org) Fix a potential Denial-of-Service attack against mod_deflate or other modules, by forcing the server to consume CPU time in diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c index 846504f1af8..ae7fd08ba0b 100644 --- a/modules/proxy/mod_proxy_http.c +++ b/modules/proxy/mod_proxy_http.c @@ -422,10 +422,16 @@ static int stream_reqbody_cl(apr_pool_t *p, apr_off_t bytes_streamed = 0; if (old_cl_val) { + char *endstr; + add_cl(p, bucket_alloc, header_brigade, old_cl_val); - if (APR_SUCCESS != (status = apr_strtoff(&cl_val, old_cl_val, NULL, - 0))) { - return HTTP_INTERNAL_SERVER_ERROR; + status = apr_strtoff(&cl_val, old_cl_val, &endstr, 10); + + if (status || *endstr || endstr == old_cl_val || cl_val < 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, + "proxy: could not parse request Content-Length (%s)", + old_cl_val); + return HTTP_BAD_REQUEST; } } terminate_headers(bucket_alloc, header_brigade); @@ -453,8 +459,13 @@ static int stream_reqbody_cl(apr_pool_t *p, * * Prevents HTTP Response Splitting. */ - if (bytes_streamed > cl_val) - continue; + if (bytes_streamed > cl_val) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "proxy: read more bytes of request body than expected " + "(got %" APR_OFF_T_FMT ", expected %" APR_OFF_T_FMT ")", + bytes_streamed, cl_val); + return HTTP_INTERNAL_SERVER_ERROR; + } if (header_brigade) { /* we never sent the header brigade, so go ahead and