]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
backport mod_proxy date parsing buffer over-read (CVE-2007-3847)
authorEric Covener <covener@apache.org>
Mon, 6 Aug 2007 23:15:02 +0000 (23:15 +0000)
committerEric Covener <covener@apache.org>
Mon, 6 Aug 2007 23:15:02 +0000 (23:15 +0000)
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

CHANGES
STATUS
modules/proxy/proxy_util.c

diff --git a/CHANGES b/CHANGES
index 6162bf8ff380069ba897533e558221fbd5c79e75..6d7d024cbfce42b62d2a35000648cbb8e07c4260 100644 (file)
--- 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 <nikke acc.umu.se>]
diff --git a/STATUS b/STATUS
index 0e2107f14ce7c09c53b19e5043b1a9a0acbff926..241dac14a077fc01633ab67acc1fbc8a7733f134 100644 (file)
--- 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
index eb1555e9a9879e06f954ad2c100e77f6fc6d3544..bab945f52f6bc5e2b226e263065308e809a01a83 100644 (file)
@@ -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)