Skip site navigation (1)Skip section navigation (2)
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>

next in thread | raw e-mail | index | archive | help
--- /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");
 	}
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199509061949.MAA12949>