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>