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;