Loading STATUS +4 −3 Changes for STATUS: 4 added lines, 3 removed lines. Original line number Diff line number Diff line 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. Loading src/CHANGES +3 −0 Changes for src/CHANGES: 3 added lines, 0 removed lines. Original line number Diff line number Diff line 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 Loading src/modules/standard/mod_include.c +40 −24 Changes for src/modules/standard/mod_include.c: 40 added lines, 24 removed lines. Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; } Loading Loading @@ -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. */ 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) { Loading @@ -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 */ Loading @@ -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); Loading Loading @@ -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")) { Loading Loading @@ -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")) { Loading Loading @@ -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")) { Loading Loading @@ -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)) { Loading Loading @@ -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")) { Loading Loading @@ -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")) { Loading Loading @@ -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")) { Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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")) { Loading Loading @@ -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")) { Loading Loading @@ -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")) { Loading Loading @@ -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")) { Loading Loading @@ -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; } Loading Loading
STATUS +4 −3 Changes for STATUS: 4 added lines, 3 removed lines. Original line number Diff line number Diff line 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. Loading
src/CHANGES +3 −0 Changes for src/CHANGES: 3 added lines, 0 removed lines. Original line number Diff line number Diff line 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 Loading
src/modules/standard/mod_include.c +40 −24 Changes for src/modules/standard/mod_include.c: 40 added lines, 24 removed lines. Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; } Loading Loading @@ -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. */ 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) { Loading @@ -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 */ Loading @@ -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); Loading Loading @@ -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")) { Loading Loading @@ -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")) { Loading Loading @@ -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")) { Loading Loading @@ -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)) { Loading Loading @@ -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")) { Loading Loading @@ -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")) { Loading Loading @@ -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")) { Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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")) { Loading Loading @@ -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")) { Loading Loading @@ -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")) { Loading Loading @@ -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")) { Loading Loading @@ -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; } Loading