Date: Wed, 6 Sep 1995 12:49:39 -0700 From: Paul Traina <pst@Shockwave.COM> To: security@freebsd.org Subject: diffs for syslog.c Message-ID: <199509061949.MAA12949@precipice.shockwave.com>
index | next in thread | raw e-mail
--- /usr/src/lib/libc/gen/syslog.c Tue Aug 29 08:04:17 1995
+++ syslog.c Wed Sep 6 12:44:59 1995
@@ -88,6 +88,24 @@
va_end(ap);
}
+/*
+ * Some rather anal checks to make sure we don't overflow our stack.
+ * We want to make sure no one can attack either the program stack or
+ * syslogd's stack. All writes are limited by SPACELEFT, and an additional
+ * overflow check is performed to insure that the travelling pointer has
+ * not exceeded the bounds of the buffer (the return value from snprintf
+ * is the number of characters it expected to write, not the number of
+ * characters is did write if the limit was reached).
+ *
+ * The overflow check could be eliminated if we changed v/snprintf or
+ * made "safe" versions of those routines.
+ */
+
+#define SPACELEFT(buffer, current) (sizeof (buffer) - \
+ ((char *)(current) - (char *)(buffer)))
+#define OVERFLOW(buffer, current) ((current) > \
+ (char *)(buffer) + sizeof (buffer))
+
void
vsyslog(pri, fmt, ap)
int pri;
@@ -120,31 +138,46 @@
/* Build the message. */
(void)time(&now);
- p = tbuf + sprintf(tbuf, "<%d>", pri);
- p += sprintf(p, "%.15s ", ctime(&now) + 4);
+ p = tbuf + snprintf(tbuf, sizeof(tbuf), "<%d>", pri);
+ if (OVERFLOW(tbuf, p))
+ goto overflow;
+ p += snprintf(p, SPACELEFT(tbuf, p), "%.15s ", ctime(&now) + 4);
+ if (OVERFLOW(tbuf, p))
+ goto overflow;
if (LogStat & LOG_PERROR)
stdp = p;
if (LogTag == NULL)
LogTag = __progname;
if (LogTag != NULL)
- p += sprintf(p, "%s", LogTag);
+ p += snprintf(p, SPACELEFT(tbuf, p), "%s", LogTag);
+ if (OVERFLOW(tbuf, p))
+ goto overflow;
if (LogStat & LOG_PID)
- p += sprintf(p, "[%d]", getpid());
- if (LogTag != NULL) {
+ p += snprintf(p, SPACELEFT(tbuf, p), "[%d]", getpid());
+ if (OVERFLOW(tbuf, p))
+ goto overflow;
+ if (LogTag != NULL && (SPACELEFT(tbuf, p) > 2)) {
*p++ = ':';
*p++ = ' ';
}
+ if (OVERFLOW(tbuf, p))
+ goto overflow;
/* Substitute error message for %m. */
- for (t = fmt_cpy; ch = *fmt; ++fmt)
+ for (t = fmt_cpy; ch = *fmt && (SPACELEFT(fmt_cpy, t) > 0); ++fmt)
if (ch == '%' && fmt[1] == 'm') {
++fmt;
- t += sprintf(t, "%s", strerror(saved_errno));
+ t += snprintf(t, SPACELEFT(fmt_cpy, t), "%s", strerror(saved_errno));
} else
*t++ = ch;
*t = '\0';
+ if (OVERFLOW(fmt_cpy, t))
+ goto overflow;
+
+ p += vsnprintf(p, SPACELEFT(tbuf, p), fmt_cpy, ap);
+ if (OVERFLOW(tbuf, p))
+ goto overflow;
- p += vsprintf(p, fmt_cpy, ap);
cnt = p - tbuf;
/* Output to stderr if requested. */
@@ -178,6 +211,12 @@
p = index(tbuf, '>') + 1;
(void)write(fd, p, cnt - (p - tbuf));
(void)close(fd);
+ }
+
+ if (SPACELEFT(tbuf, p) < 2) {
+ overflow:
+ syslog(LOG_CRIT|LOG_AUTH|LOG_CONS|LOG_PERROR|LOG_PID,
+ "DANGER: syslog buffer overflow attempt--possible attack");
}
}
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199509061949.MAA12949>
