summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrad <brad@openbsd.org>2004-06-07 04:21:30 +0000
committerbrad <brad@openbsd.org>2004-06-07 04:21:30 +0000
commit91eaef1e1af3309667eb7006652953ab4d29d081 (patch)
tree1a167d674a7cf9b27324f1a47c5c1233aac5fc2d
parentcheck for NOPIC instead of using a list of arch names. (diff)
downloadwireguard-openbsd-91eaef1e1af3309667eb7006652953ab4d29d081.tar.xz
wireguard-openbsd-91eaef1e1af3309667eb7006652953ab4d29d081.zip
Apache does not filter terminal escape sequences from its error logs, which
could make it easier for attackers to insert those sequences into terminal emulators containing vulnerabilities related to escape sequences. CAN-2003-0020 ok henning@
-rw-r--r--usr.sbin/httpd/src/include/httpd.h2
-rw-r--r--usr.sbin/httpd/src/main/http_log.c12
-rw-r--r--usr.sbin/httpd/src/main/util.c63
3 files changed, 76 insertions, 1 deletions
diff --git a/usr.sbin/httpd/src/include/httpd.h b/usr.sbin/httpd/src/include/httpd.h
index 3dd3bb44c3b..3e2f6ec6bd8 100644
--- a/usr.sbin/httpd/src/include/httpd.h
+++ b/usr.sbin/httpd/src/include/httpd.h
@@ -1072,6 +1072,8 @@ API_EXPORT(char *) ap_escape_html(pool *p, const char *s);
API_EXPORT(char *) ap_construct_server(pool *p, const char *hostname,
unsigned port, const request_rec *r);
API_EXPORT(char *) ap_escape_logitem(pool *p, const char *str);
+API_EXPORT(size_t) ap_escape_errorlog_item(char *dest, const char *source,
+ size_t buflen);
API_EXPORT(char *) ap_escape_shell_cmd(pool *p, const char *s);
API_EXPORT(int) ap_count_dirs(const char *path);
diff --git a/usr.sbin/httpd/src/main/http_log.c b/usr.sbin/httpd/src/main/http_log.c
index 21d00c95d2d..fcd019d165a 100644
--- a/usr.sbin/httpd/src/main/http_log.c
+++ b/usr.sbin/httpd/src/main/http_log.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: http_log.c,v 1.14 2003/08/21 13:11:35 henning Exp $ */
+/* $OpenBSD: http_log.c,v 1.15 2004/06/07 04:21:30 brad Exp $ */
/* ====================================================================
* The Apache Software License, Version 1.1
@@ -316,6 +316,9 @@ static void log_error_core(const char *file, int line, int level,
const char *fmt, va_list args)
{
char errstr[MAX_STRING_LEN];
+#ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED
+ char scratch[MAX_STRING_LEN];
+#endif
size_t len;
int save_errno = errno;
FILE *logf;
@@ -447,7 +450,14 @@ static void log_error_core(const char *file, int line, int level,
}
#endif
+#ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED
+ if (ap_vsnprintf(scratch, sizeof(scratch) - len, fmt, args)) {
+ len += ap_escape_errorlog_item(errstr + len, scratch,
+ sizeof(errstr) - len);
+ }
+#else
len += ap_vsnprintf(errstr + len, sizeof(errstr) - len, fmt, args);
+#endif
/* NULL if we are logging to syslog */
if (logf) {
diff --git a/usr.sbin/httpd/src/main/util.c b/usr.sbin/httpd/src/main/util.c
index 9151379ea3f..f7cb18f8fdd 100644
--- a/usr.sbin/httpd/src/main/util.c
+++ b/usr.sbin/httpd/src/main/util.c
@@ -1520,6 +1520,69 @@ API_EXPORT(char *) ap_escape_logitem(pool *p, const char *str)
return ret;
}
+API_EXPORT(size_t) ap_escape_errorlog_item(char *dest, const char *source,
+ 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);
+}
API_EXPORT(char *) ap_escape_shell_cmd(pool *p, const char *str)
{