Return-Path: Delivered-To: apmail-httpd-cvs-archive@www.apache.org Received: (qmail 58481 invoked from network); 10 Nov 2004 11:32:45 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 10 Nov 2004 11:32:45 -0000 Received: (qmail 63828 invoked by uid 500); 10 Nov 2004 11:32:43 -0000 Delivered-To: apmail-httpd-cvs-archive@httpd.apache.org Received: (qmail 63764 invoked by uid 500); 10 Nov 2004 11:32:42 -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 63750 invoked by uid 500); 10 Nov 2004 11:32:42 -0000 Delivered-To: apmail-httpd-2.0-cvs@apache.org Received: (qmail 63746 invoked by uid 99); 10 Nov 2004 11:32:42 -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; Wed, 10 Nov 2004 03:32:42 -0800 Received: (qmail 58460 invoked by uid 1582); 10 Nov 2004 11:32:40 -0000 Date: 10 Nov 2004 11:32:40 -0000 Message-ID: <20041110113240.58459.qmail@minotaur.apache.org> From: jorton@apache.org To: httpd-2.0-cvs@apache.org Subject: cvs commit: httpd-2.0/server protocol.c X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N jorton 2004/11/10 03:32:40 Modified: server Tag: APACHE_2_0_BRANCH protocol.c Log: Backport fix for memory consumption DoS, CVE CAN-2004-0942: * server/protocol.c (ap_rgetline_core): Don't trim trailing whitespace from the buffer here. (ap_get_mime_headers_core): Trim trailing whitespace here, after reading a complete field including continuation lines. Also simplify code to remove whitespace between field-name and colon. Reviewed by: stoddard, jorton, nd Revision Changes Path No revision No revision 1.121.2.22 +22 -47 httpd-2.0/server/protocol.c Index: protocol.c =================================================================== RCS file: /home/cvs/httpd-2.0/server/protocol.c,v retrieving revision 1.121.2.21 retrieving revision 1.121.2.22 diff -d -w -u -r1.121.2.21 -r1.121.2.22 --- protocol.c 23 Sep 2004 18:18:36 -0000 1.121.2.21 +++ protocol.c 10 Nov 2004 11:32:40 -0000 1.121.2.22 @@ -305,35 +305,13 @@ } } - /* We now go backwards over any CR (if present) or white spaces. - * - * Trim any extra trailing spaces or tabs except for the first - * space or tab at the beginning of a blank string. This makes - * it much easier to check field values for exact matches, and - * saves memory as well. Terminate string at end of line. - */ - pos = last_char; - if (pos > *s && *(pos - 1) == APR_ASCII_CR) { - --pos; - } - - /* Trim any extra trailing spaces or tabs except for the first - * space or tab at the beginning of a blank string. This makes - * it much easier to check field values for exact matches, and - * saves memory as well. - */ - while (pos > ((*s) + 1) - && (*(pos - 1) == APR_ASCII_BLANK || *(pos - 1) == APR_ASCII_TAB)) { - --pos; + /* Now NUL-terminate the string at the end of the line; + * if the last-but-one character is a CR, terminate there */ + if (last_char > *s && last_char[-1] == APR_ASCII_CR) { + last_char--; } - - /* Since we want to remove the LF from the line, we'll go ahead - * and set this last character to be the term NULL and reset - * bytes_handled accordingly. - */ - *pos = '\0'; - last_char = pos; - bytes_handled = pos - *s; + *last_char = '\0'; + bytes_handled = last_char - *s; /* If we're folding, we have more work to do. * @@ -750,7 +728,7 @@ last_len += len; folded = 1; } - else { + else /* not a continuation line */ { if (r->server->limit_req_fields && (++fields_read > r->server->limit_req_fields)) { @@ -774,28 +752,25 @@ return; } - *value = '\0'; - tmp_field = value; /* used to trim the whitespace between key - * token and separator - */ - ++value; + tmp_field = value - 1; /* last character of field-name */ + + *value++ = '\0'; /* NUL-terminate at colon */ + while (*value == ' ' || *value == '\t') { ++value; /* Skip to start of value */ } - /* This check is to avoid any invalid memory reference while - * traversing backwards in the key. To avoid a case where - * the header starts with ':' (or with just some white - * space and the ':') followed by the value - */ - if (tmp_field > last_field) { - --tmp_field; - while ((tmp_field > last_field) && - (*tmp_field == ' ' || *tmp_field == '\t')) { - --tmp_field; /* Removing LWS between key and ':' */ + /* Strip LWS after field-name: */ + while (tmp_field > last_field + && (*tmp_field == ' ' || *tmp_field == '\t')) { + *tmp_field-- = '\0'; } - ++tmp_field; - *tmp_field = '\0'; + + /* Strip LWS after field-value: */ + tmp_field = last_field + last_len - 1; + while (tmp_field > value + && (*tmp_field == ' ' || *tmp_field == '\t')) { + *tmp_field-- = '\0'; } apr_table_addn(r->headers_in, last_field, value);