]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Apply the CAN-2004-0940 patch.
authorJim Jagielski <jim@apache.org>
Fri, 22 Oct 2004 19:31:08 +0000 (19:31 +0000)
committerJim Jagielski <jim@apache.org>
Fri, 22 Oct 2004 19:31:08 +0000 (19:31 +0000)
PR:
Obtained from:
Submitted by:
Reviewed by:

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x@105547 13f79535-47bb-0310-9956-ffa450edef68

STATUS
src/CHANGES
src/modules/standard/mod_include.c

diff --git a/STATUS b/STATUS
index e7fb4145c772df603d1beb200f8d17b78161a9d4..2105a3d67674887422e0df314d83d0235eeac5fa 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -1,10 +1,11 @@
 APACHE 1.3 STATUS:                                             -*-text-*-
-  Last modified at [$Date: 2004/10/18 16:40:39 $]
+  Last modified at [$Date: 2004/10/22 19:31:06 $]
 
 Release:
 
-   1.3.33-dev: In development
-   1.3.32: Tagged October 18, 2004.
+   1.3.33-dev: Jim proposes a tag-n-roll around Oct 24
+               with a release on the 27th.
+   1.3.32: Tagged October 18, 2004. Not released.
    1.3.31: Tagged May 7, 2004. Announced May 11, 2004.
    1.3.30: Tagged April 9, 2004. Not released.
    1.3.29: Tagged October 24, 2003. Announced Oct 29, 2003.
index 14bb6e74a73739ae78f55a7ba7f0151823521db2..a928e160bd421e89c9ab74bf2400f20ba3796c12 100644 (file)
@@ -1,5 +1,8 @@
 Changes with Apache 1.3.33
 
+  *) SECURITY: CAN-2004-0940 (cve.mitre.org)
+     mod_include: Fix potential buffer overflow with escaped characters
+     in SSI tag string. [Martin Kraemer, Jim Jagielski]
 
 Changes with Apache 1.3.32
 
index ee5905b7ae67d56e0c93a35678e65b3588d1af9f..f3f8c3e3af651fd1d682815c15acbbaf9ee9a099 100644 (file)
@@ -309,9 +309,10 @@ otilde\365oslash\370ugrave\371uacute\372yacute\375"     /* 6 */
  * the tag value is html decoded if dodecode is non-zero
  */
 
-static char *get_tag(pool *p, FILE *in, char *tag, int tagbuf_len, int dodecode)
+static char *get_tag(request_rec *r, FILE *in, char *tag, int tagbuf_len, int dodecode)
 {
     char *t = tag, *tag_val, c, term;
+    pool *p = r->pool;
 
     /* makes code below a little less cluttered */
     --tagbuf_len;
@@ -337,7 +338,7 @@ static char *get_tag(pool *p, FILE *in, char *tag, int tagbuf_len, int dodecode)
 
     /* find end of tag name */
     while (1) {
-        if (t - tag == tagbuf_len) {
+        if (t == tag + tagbuf_len) {
             *t = '\0';
             return NULL;
         }
@@ -371,16 +372,30 @@ static char *get_tag(pool *p, FILE *in, char *tag, int tagbuf_len, int dodecode)
     term = c;
     while (1) {
         GET_CHAR(in, c, NULL, p);
-        if (t - tag == tagbuf_len) {
+        if (t == tag + tagbuf_len) {
             *t = '\0';
+            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
+                          "mod_include: value length exceeds limit"
+                          " (%d) in %s", tagbuf_len, r->filename);
             return NULL;
         }
-/* Want to accept \" as a valid character within a string. */
+        /* Want to accept \" as a valid character within a string. */
         if (c == '\\') {
-            *(t++) = c;         /* Add backslash */
             GET_CHAR(in, c, NULL, p);
-            if (c == term) {    /* Only if */
-                *(--t) = c;     /* Replace backslash ONLY for terminator */
+            /* Insert backslash only if not escaping a terminator char */
+            if (c != term) {
+                *(t++) = '\\';
+                /*
+                 * check to make sure that adding in the backslash won't cause
+                 * an overflow, since we're now 1 character ahead.
+                 */
+                if (t == tag + tagbuf_len) {
+                    *t = '\0';
+                    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
+                                  "mod_include: value length exceeds limit"
+                                  " (%d) in %s", tagbuf_len, r->filename);
+                    return NULL;
+                }
             }
         }
         else if (c == term) {
@@ -395,9 +410,10 @@ static char *get_tag(pool *p, FILE *in, char *tag, int tagbuf_len, int dodecode)
     return ap_pstrdup(p, tag_val);
 }
 
-static int get_directive(FILE *in, char *dest, size_t len, pool *p)
+static int get_directive(FILE *in, char *dest, size_t len, request_rec *r)
 {
     char *d = dest;
+    pool *p = r->pool;
     char c;
 
     /* make room for nul terminator */
@@ -413,6 +429,9 @@ static int get_directive(FILE *in, char *dest, size_t len, pool *p)
     /* now get directive */
     while (1) {
        if (d == len + dest) {
+            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
+                          "mod_include: directive length exceeds limit"
+                          " (%d) in %s", len+1, r->filename);
            return 1;
        }
         *d++ = ap_tolower(c);
@@ -616,7 +635,7 @@ static int handle_include(FILE *in, request_rec *r, const char *error, int noexe
     char *tag_val;
 
     while (1) {
-        if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
+        if (!(tag_val = get_tag(r, in, tag, sizeof(tag), 1))) {
             return 1;
         }
         if (!strcmp(tag, "file") || !strcmp(tag, "virtual")) {
@@ -839,7 +858,7 @@ static int handle_exec(FILE *in, request_rec *r, const char *error)
     char parsed_string[MAX_STRING_LEN];
 
     while (1) {
-        if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
+        if (!(tag_val = get_tag(r, in, tag, sizeof(tag), 1))) {
             return 1;
         }
         if (!strcmp(tag, "cmd")) {
@@ -890,7 +909,7 @@ static int handle_echo(FILE *in, request_rec *r, const char *error)
     encode = E_ENTITY;
 
     while (1) {
-        if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
+        if (!(tag_val = get_tag(r, in, tag, sizeof(tag), 1))) {
             return 1;
         }
         if (!strcmp(tag, "var")) {
@@ -952,7 +971,7 @@ static int handle_perl(FILE *in, request_rec *r, const char *error)
         return DECLINED;
     }
     while (1) {
-        if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
+        if (!(tag_val = get_tag(r, in, tag, sizeof(tag), 1))) {
             break;
         }
         if (strnEQ(tag, "sub", 3)) {
@@ -985,7 +1004,7 @@ static int handle_config(FILE *in, request_rec *r, char *error, char *tf,
     table *env = r->subprocess_env;
 
     while (1) {
-        if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 0))) {
+        if (!(tag_val = get_tag(r, in, tag, sizeof(tag), 0))) {
             return 1;
         }
         if (!strcmp(tag, "errmsg")) {
@@ -1101,7 +1120,7 @@ static int handle_fsize(FILE *in, request_rec *r, const char *error, int sizefmt
     char parsed_string[MAX_STRING_LEN];
 
     while (1) {
-        if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
+        if (!(tag_val = get_tag(r, in, tag, sizeof(tag), 1))) {
             return 1;
         }
         else if (!strcmp(tag, "done")) {
@@ -1141,7 +1160,7 @@ static int handle_flastmod(FILE *in, request_rec *r, const char *error, const ch
     char parsed_string[MAX_STRING_LEN];
 
     while (1) {
-        if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
+        if (!(tag_val = get_tag(r, in, tag, sizeof(tag), 1))) {
             return 1;
         }
         else if (!strcmp(tag, "done")) {
@@ -1917,7 +1936,7 @@ static int handle_if(FILE *in, request_rec *r, const char *error,
 
     expr = NULL;
     while (1) {
-        tag_val = get_tag(r->pool, in, tag, sizeof(tag), 0);
+        tag_val = get_tag(r, in, tag, sizeof(tag), 0);
         if (!tag_val || *tag == '\0') {
             return 1;
         }
@@ -1960,7 +1979,7 @@ static int handle_elif(FILE *in, request_rec *r, const char *error,
 
     expr = NULL;
     while (1) {
-        tag_val = get_tag(r->pool, in, tag, sizeof(tag), 0);
+        tag_val = get_tag(r, in, tag, sizeof(tag), 0);
         if (!tag_val || *tag == '\0') {
             return 1;
         }
@@ -2007,7 +2026,7 @@ static int handle_else(FILE *in, request_rec *r, const char *error,
 {
     char tag[MAX_STRING_LEN];
 
-    if (!get_tag(r->pool, in, tag, sizeof(tag), 1)) {
+    if (!get_tag(r, in, tag, sizeof(tag), 1)) {
         return 1;
     }
     else if (!strcmp(tag, "done")) {
@@ -2035,7 +2054,7 @@ static int handle_endif(FILE *in, request_rec *r, const char *error,
 {
     char tag[MAX_STRING_LEN];
 
-    if (!get_tag(r->pool, in, tag, sizeof(tag), 1)) {
+    if (!get_tag(r, in, tag, sizeof(tag), 1)) {
         return 1;
     }
     else if (!strcmp(tag, "done")) {
@@ -2065,7 +2084,7 @@ static int handle_set(FILE *in, request_rec *r, const char *error)
 
     var = (char *) NULL;
     while (1) {
-        if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
+        if (!(tag_val = get_tag(r, in, tag, sizeof(tag), 1))) {
             return 1;
         }
         else if (!strcmp(tag, "done")) {
@@ -2102,7 +2121,7 @@ static int handle_printenv(FILE *in, request_rec *r, const char *error)
     table_entry *elts = (table_entry *) arr->elts;
     int i;
 
-    if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
+    if (!(tag_val = get_tag(r, in, tag, sizeof(tag), 1))) {
         return 1;
     }
     else if (!strcmp(tag, "done")) {
@@ -2173,10 +2192,7 @@ static void send_parsed_content(FILE *f, request_rec *r)
 
     while (1) {
         if (!find_string(f, STARTING_SEQUENCE, r, printing)) {
-            if (get_directive(f, directive, sizeof(directive), r->pool)) {
-               ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
-                           "mod_include: error reading directive in %s",
-                           r->filename);
+            if (get_directive(f, directive, sizeof(directive), r)) {
                ap_rputs(error, r);
                 return;
             }