httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jor...@apache.org
Subject cvs commit: httpd-2.0/server protocol.c
Date Wed, 10 Nov 2004 11:32:40 GMT
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);
  
  
  

Mime
View raw message