You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by nd...@apache.org on 2003/11/24 22:34:39 UTC

cvs commit: httpd-2.0/server log.c util.c

nd          2003/11/24 13:34:39

  Modified:    .        CHANGES
               include  ap_mmn.h httpd.h
               server   log.c util.c
  Log:
  SECURITY [CAN-2003-0020]: escape arbitrary data before writing into the
  errorlog.
  
  Reviewed by: Mark J Cox
  
  Revision  Changes    Path
  1.1324    +3 -0      httpd-2.0/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/CHANGES,v
  retrieving revision 1.1323
  retrieving revision 1.1324
  diff -u -u -r1.1323 -r1.1324
  --- CHANGES	22 Nov 2003 02:10:59 -0000	1.1323
  +++ CHANGES	24 Nov 2003 21:34:37 -0000	1.1324
  @@ -2,6 +2,9 @@
   
     [Remove entries to the current 2.0 section below, when backported]
   
  +  *) SECURITY [CAN-2003-0020]: Escape arbitrary data before writing
  +     into the errorlog.  [Andr� Malo]
  +
     *) mod_expires: Initialize ExpiresDefault to NULL instead of "" to
        avoid reporting an Internal Server error if it is used without
        having been set in the httpd.conf file. PR: 23748, 24459
  
  
  
  1.61      +2 -1      httpd-2.0/include/ap_mmn.h
  
  Index: ap_mmn.h
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/include/ap_mmn.h,v
  retrieving revision 1.60
  retrieving revision 1.61
  diff -u -u -r1.60 -r1.61
  --- ap_mmn.h	2 Nov 2003 20:37:03 -0000	1.60
  +++ ap_mmn.h	24 Nov 2003 21:34:38 -0000	1.61
  @@ -117,6 +117,7 @@
    *                        handler
    * 20030821 (2.1.0-dev) bumped mod_include's entire API
    * 20030821.1 (2.1.0-dev) added XHTML doctypes
  + * 20030821.2 (2.1.0-dev) added ap_escape_errorlog_item
    */
   
   #define MODULE_MAGIC_COOKIE 0x41503230UL /* "AP20" */
  @@ -124,7 +125,7 @@
   #ifndef MODULE_MAGIC_NUMBER_MAJOR
   #define MODULE_MAGIC_NUMBER_MAJOR 20030821
   #endif
  -#define MODULE_MAGIC_NUMBER_MINOR 1                     /* 0...n */
  +#define MODULE_MAGIC_NUMBER_MINOR 2                     /* 0...n */
   
   /**
    * Determine if the server's current MODULE_MAGIC_NUMBER is at least a
  
  
  
  1.203     +11 -1     httpd-2.0/include/httpd.h
  
  Index: httpd.h
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/include/httpd.h,v
  retrieving revision 1.202
  retrieving revision 1.203
  diff -u -u -r1.202 -r1.203
  --- httpd.h	24 Nov 2003 16:08:44 -0000	1.202
  +++ httpd.h	24 Nov 2003 21:34:38 -0000	1.203
  @@ -1381,10 +1381,20 @@
   /**
    * Escape a string for logging
    * @param p The pool to allocate from
  - * @param s The string to escape
  + * @param str The string to escape
    * @return The escaped string
    */
   AP_DECLARE(char *) ap_escape_logitem(apr_pool_t *p, const char *str);
  +
  +/**
  + * Escape a string for logging into the error log (without a pool)
  + * @param dest The buffer to write to
  + * @param source The string to escape
  + * @param maxlen The buffer size for the escaped string (including \0)
  + * @return The len of the escaped string (always < maxlen)
  + */
  +AP_DECLARE(apr_size_t) ap_escape_errorlog_item(char *dest, const char *source,
  +                                               apr_size_t buflen);
   
   /**
    * Construct a full hostname
  
  
  
  1.136     +9 -4      httpd-2.0/server/log.c
  
  Index: log.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/server/log.c,v
  retrieving revision 1.135
  retrieving revision 1.136
  diff -u -u -r1.135 -r1.136
  --- log.c	14 Jul 2003 14:48:40 -0000	1.135
  +++ log.c	24 Nov 2003 21:34:38 -0000	1.136
  @@ -401,7 +401,7 @@
                              const request_rec *r, apr_pool_t *pool,
                              const char *fmt, va_list args)
   {
  -    char errstr[MAX_STRING_LEN];
  +    char errstr[MAX_STRING_LEN], scratch[MAX_STRING_LEN];
       apr_size_t len, errstrlen;
       apr_file_t *logf = NULL;
       const char *referer;
  @@ -536,12 +536,17 @@
               errstr[len] = '\0';
           }
       }
  +
       errstrlen = len;
  -    len += apr_vsnprintf(errstr + len, MAX_STRING_LEN - len, fmt, args);
  +    if (apr_vsnprintf(scratch, MAX_STRING_LEN - len, fmt, args)) {
  +        len += ap_escape_errorlog_item(errstr + len, scratch,
  +                                       MAX_STRING_LEN - len);
  +    }
   
  -    if (r && (referer = apr_table_get(r->headers_in, "Referer"))) {
  +    if (   r && (referer = apr_table_get(r->headers_in, "Referer"))
  +        && ap_escape_errorlog_item(scratch, referer, MAX_STRING_LEN - len)) {
           len += apr_snprintf(errstr + len, MAX_STRING_LEN - len,
  -                            ", referer: %s", referer);
  +                            ", referer: %s", scratch);
       }
   
       /* NULL if we are logging to syslog */
  
  
  
  1.143     +64 -0     httpd-2.0/server/util.c
  
  Index: util.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/server/util.c,v
  retrieving revision 1.142
  retrieving revision 1.143
  diff -u -u -r1.142 -r1.143
  --- util.c	3 Sep 2003 19:27:09 -0000	1.142
  +++ util.c	24 Nov 2003 21:34:38 -0000	1.143
  @@ -1838,6 +1838,70 @@
       return ret;
   }
   
  +AP_DECLARE(apr_size_t) ap_escape_errorlog_item(char *dest, const char *source,
  +                                               apr_size_t buflen)
  +{
  +    unsigned char *d, *ep;
  +    const unsigned char *s;
  +
  +    if (!source || !buflen) { /* be safe */
  +        return 0;
  +    }
  +
  +    d = (unsigned char *)dest;
  +    s = (const unsigned char *)source;
  +    ep = d + buflen - 1;
  +
  +    for (; d < ep && *s; ++s) {
  +
  +        if (TEST_CHAR(*s, T_ESCAPE_LOGITEM)) {
  +            *d++ = '\\';
  +            if (d >= ep) {
  +                --d;
  +                break;
  +            }
  +
  +            switch(*s) {
  +            case '\b':
  +                *d++ = 'b';
  +                break;
  +            case '\n':
  +                *d++ = 'n';
  +                break;
  +            case '\r':
  +                *d++ = 'r';
  +                break;
  +            case '\t':
  +                *d++ = 't';
  +                break;
  +            case '\v':
  +                *d++ = 'v';
  +                break;
  +            case '\\':
  +                *d++ = *s;
  +                break;
  +            case '"': /* no need for this in error log */
  +                d[-1] = *s;
  +                break;
  +            default:
  +                if (d >= ep - 2) {
  +                    ep = --d; /* break the for loop as well */
  +                    break;
  +                }
  +                c2x(*s, d);
  +                *d = 'x';
  +                d += 3;
  +            }
  +        }
  +        else {
  +            *d++ = *s;
  +        }
  +    }
  +    *d = '\0';
  +
  +    return (d - (unsigned char *)dest);
  +}
  +
   AP_DECLARE(int) ap_is_directory(apr_pool_t *p, const char *path)
   {
       apr_finfo_t finfo;