Return-Path: Delivered-To: apmail-httpd-cvs-archive@www.apache.org Received: (qmail 52995 invoked from network); 22 Oct 2004 19:31:45 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 22 Oct 2004 19:31:45 -0000 Received: (qmail 97849 invoked by uid 500); 22 Oct 2004 19:31:25 -0000 Delivered-To: apmail-httpd-cvs-archive@httpd.apache.org Received: (qmail 97754 invoked by uid 500); 22 Oct 2004 19:31:20 -0000 Mailing-List: contact cvs-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@httpd.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list cvs@httpd.apache.org Received: (qmail 97718 invoked by uid 500); 22 Oct 2004 19:31:18 -0000 Delivered-To: apmail-apache-1.3-cvs@apache.org Received: (qmail 97702 invoked by uid 99); 22 Oct 2004 19:31:15 -0000 X-ASF-Spam-Status: No, hits=-10.0 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.28) with SMTP; Fri, 22 Oct 2004 12:31:13 -0700 Received: (qmail 52740 invoked by uid 1078); 22 Oct 2004 19:31:09 -0000 Date: 22 Oct 2004 19:31:09 -0000 Message-ID: <20041022193109.52739.qmail@minotaur.apache.org> From: jim@apache.org To: apache-1.3-cvs@apache.org Subject: cvs commit: apache-1.3/src/modules/standard mod_include.c X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N jim 2004/10/22 12:31:08 Modified: . STATUS src CHANGES src/modules/standard mod_include.c Log: Apply the CAN-2004-0940 patch. Revision Changes Path 1.1110 +4 -3 apache-1.3/STATUS Index: STATUS =================================================================== RCS file: /home/cvs/apache-1.3/STATUS,v retrieving revision 1.1109 retrieving revision 1.1110 diff -u -r1.1109 -r1.1110 --- STATUS 18 Oct 2004 16:40:39 -0000 1.1109 +++ STATUS 22 Oct 2004 19:31:06 -0000 1.1110 @@ -3,8 +3,9 @@ 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. 1.1960 +3 -0 apache-1.3/src/CHANGES Index: CHANGES =================================================================== RCS file: /home/cvs/apache-1.3/src/CHANGES,v retrieving revision 1.1959 retrieving revision 1.1960 diff -u -r1.1959 -r1.1960 --- CHANGES 18 Oct 2004 16:39:37 -0000 1.1959 +++ CHANGES 22 Oct 2004 19:31:07 -0000 1.1960 @@ -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 1.141 +41 -25 apache-1.3/src/modules/standard/mod_include.c Index: mod_include.c =================================================================== RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_include.c,v retrieving revision 1.140 retrieving revision 1.141 diff -u -r1.140 -r1.141 --- mod_include.c 28 Feb 2004 22:19:04 -0000 1.140 +++ mod_include.c 22 Oct 2004 19:31:08 -0000 1.141 @@ -309,9 +309,10 @@ * 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 @@ /* 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 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ { 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 @@ { 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 @@ 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 @@ 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 @@ 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; }