From: Eric Covener Date: Mon, 6 Aug 2007 23:15:02 +0000 (+0000) Subject: backport mod_proxy date parsing buffer over-read (CVE-2007-3847) X-Git-Tag: 2.0.60~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ad01caa16c2c809d129e6eddece67d40a50771c1;p=thirdparty%2Fapache%2Fhttpd.git backport mod_proxy date parsing buffer over-read (CVE-2007-3847) Submitted by: Davi Arnaut, Nick Kew Reviewed by: niq, rpluem, covener git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.0.x@563329 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 6162bf8ff38..6d7d024cbfc 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,11 @@ -*- coding: utf-8 -*- Changes with Apache 2.0.60 + *) SECURITY: CVE-2007-3847 (cve.mitre.org) + mod_proxy: Prevent reading past the end of a buffer when parsing + date-related headers. PR 41144. + [Davi Arnaut, Nick Kew] + *) SECURITY: CVE-2007-1863 (cve.mitre.org) mod_cache: Prevent segmentation fault if a Cache-Control header has no value. [Niklas Edmundsson ] diff --git a/STATUS b/STATUS index 0e2107f14ce..241dac14a07 100644 --- a/STATUS +++ b/STATUS @@ -114,14 +114,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - *) SECURITY: CVE-2007-3847 - mod_proxy: Prevent reading past the end of a buffer when parsing - date-related headers. PR 41144. - 2.2.x: http://svn.apache.org/viewvc?view=rev&revision=563198 - 2.0.x: http://people.apache.org/~covener/proxy-util-20x.patch - (Same as 2.2 but removed lines have hard tabs) - +1: covener, niq, rpluem - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ please place SVN revisions from trunk here, so it is easy to identify exactly what the proposed changes are! Add all new diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index eb1555e9a98..bab945f52f6 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -259,70 +259,28 @@ PROXY_DECLARE(char *) return NULL; } -static const char * const lwday[7] = -{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; - /* * If the date is a valid RFC 850 date or asctime() date, then it - * is converted to the RFC 1123 format, otherwise it is not modified. - * This routine is not very fast at doing conversions, as it uses - * sscanf and sprintf. However, if the date is already correctly - * formatted, then it exits very quickly. + * is converted to the RFC 1123 format. */ PROXY_DECLARE(const char *) - ap_proxy_date_canon(apr_pool_t *p, const char *x1) + ap_proxy_date_canon(apr_pool_t *p, const char *date) { - char *x = apr_pstrdup(p, x1); - int wk, mday, year, hour, min, sec, mon; - char *q, month[4], zone[4], week[4]; - - q = strchr(x, ','); - /* check for RFC 850 date */ - if (q != NULL && q - x > 3 && q[1] == ' ') { - *q = '\0'; - for (wk = 0; wk < 7; wk++) - if (strcmp(x, lwday[wk]) == 0) - break; - *q = ','; - if (wk == 7) - return x; /* not a valid date */ - if (q[4] != '-' || q[8] != '-' || q[11] != ' ' || q[14] != ':' || - q[17] != ':' || strcmp(&q[20], " GMT") != 0) - return x; - if (sscanf(q + 2, "%u-%3s-%u %u:%u:%u %3s", &mday, month, &year, - &hour, &min, &sec, zone) != 7) - return x; - if (year < 70) - year += 2000; - else - year += 1900; - } - else { -/* check for acstime() date */ - if (x[3] != ' ' || x[7] != ' ' || x[10] != ' ' || x[13] != ':' || - x[16] != ':' || x[19] != ' ' || x[24] != '\0') - return x; - if (sscanf(x, "%3s %3s %u %u:%u:%u %u", week, month, &mday, &hour, - &min, &sec, &year) != 7) - return x; - for (wk = 0; wk < 7; wk++) - if (strcmp(week, apr_day_snames[wk]) == 0) - break; - if (wk == 7) - return x; + apr_status_t rv; + char* ndate; + + apr_time_t time = apr_date_parse_http(date); + if (!time) { + return date; } -/* check date */ - for (mon = 0; mon < 12; mon++) - if (strcmp(month, apr_month_snames[mon]) == 0) - break; - if (mon == 12) - return x; + ndate = apr_palloc(p, APR_RFC822_DATE_LEN); + rv = apr_rfc822_date(ndate, time); + if (rv != APR_SUCCESS) { + return date; + } - q = apr_palloc(p, 30); - apr_snprintf(q, 30, "%s, %.2d %s %d %.2d:%.2d:%.2d GMT", apr_day_snames[wk], - mday, apr_month_snames[mon], year, hour, min, sec); - return q; + return ndate; } PROXY_DECLARE(request_rec *)ap_proxy_make_fake_req(conn_rec *c, request_rec *r)