Subject: Re: Patch for 8lgm syslog/sendmail vulnerability, 4.4lite machines
To: gdonl@gv.ssi1.com (Don Lewis), Charles Hannum <Charles-Hannum@deshaw.com>
From: Don Lewis <gdonl@gv.ssi1.com>
List: current-users
Date: 08/30/1995 02:27:17
On Aug 29, 10:09pm, Don Lewis wrote:
} Subject: Re: Patch for 8lgm syslog/sendmail vulnerability, 4.4lite machine
} Also, if your using Chris Torek's stdio package, rather than calling
} snprintf() and vsnprintf() and manually keeping track of the end of
} the buffer, why don't you do call fprintf() and vfprintf() directly the
} same way as snprintf() and friends do. This cleans up the code in
} syslog() quite a bit.
I'll agree with Charles that evaluating the %m in stdio is a lot cleaner,
but I don't want the way printf("...%m...") to change. We ought to be
able to pass a flag or maybe something fancier. The original syslog()
didn't really do the right thing if the format contained %%m. Neither
the original, nor my version do the right thing if the string returned
by strerror() contains %something. Either we have to double the %, or
let stdio evaluate %m.
Anyway, my submission is attached. It hasn't broken in the modest amount
of testing I've done on it.
*** ORIGsyslog.c Tue Apr 11 09:55:01 1995
--- syslog.c Wed Aug 30 02:16:33 1995
***************
*** 51,56 ****
--- 51,57 ----
#include <fcntl.h>
#include <paths.h>
#include <stdio.h>
+ #include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
***************
*** 69,74 ****
--- 70,78 ----
static int LogMask = 0xff; /* mask of priorities to be logged */
extern char *__progname; /* Program name, from crt0. */
+ #define TBUF_LEN 2048
+ #define FMT_LEN 1024
+
/*
* syslog, vsyslog --
* print message on log file; output is intended for syslogd(8).
***************
*** 100,110 ****
register const char *fmt;
va_list ap;
{
register int cnt;
register char ch, *p, *t;
time_t now;
! int fd, saved_errno;
! char *stdp, tbuf[2048], fmt_cpy[1024];
#define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
/* Check for invalid bits. */
--- 104,117 ----
register const char *fmt;
va_list ap;
{
+ FILE f;
register int cnt;
register char ch, *p, *t;
+ register const char *cp;
time_t now;
! int fd, saved_errno, m, n, fleft;
! wchar_t wc;
! char *stdp, tbuf[TBUF_LEN], fmt_cpy[FMT_LEN], dbuf[128];
#define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
/* Check for invalid bits. */
***************
*** 120,125 ****
--- 127,137 ----
saved_errno = errno;
+ f._flags = __SWR | __SSTR;
+ f._bf._base = f._p = (unsigned char *)tbuf;
+ /* -2 to allow for trailing "\r\n" if LOG_CONS is set */
+ f._bf._size = f._w = TBUF_LEN - 2;
+
/* Set default facility if none specified. */
if ((pri & LOG_FACMASK) == 0)
pri |= LogFacility;
***************
*** 126,158 ****
/* Build the message. */
(void)time(&now);
! p = tbuf + sprintf(tbuf, "<%d>", pri);
! p += strftime(p, sizeof (tbuf) - (p - tbuf), "%h %e %T ",
! localtime(&now));
! if (LogStat & LOG_PERROR)
! stdp = p;
if (LogTag == NULL)
LogTag = __progname;
if (LogTag != NULL)
! p += sprintf(p, "%s", LogTag);
if (LogStat & LOG_PID)
! p += sprintf(p, "[%d]", getpid());
if (LogTag != NULL) {
! *p++ = ':';
! *p++ = ' ';
}
/* Substitute error message for %m. */
! for (t = fmt_cpy; ch = *fmt; ++fmt)
! if (ch == '%' && fmt[1] == 'm') {
! ++fmt;
! t += sprintf(t, "%s", strerror(saved_errno));
! } else
! *t++ = ch;
*t = '\0';
! p += vsprintf(p, fmt_cpy, ap);
! cnt = p - tbuf;
/* Output to stderr if requested. */
if (LogStat & LOG_PERROR) {
--- 138,206 ----
/* Build the message. */
(void)time(&now);
! strftime(dbuf, sizeof(dbuf) - 1, "%h %e %T ", localtime(&now));
! fprintf(&f, "<%d>%s", pri, dbuf);
! if (LogStat & (LOG_PERROR | LOG_CONS))
! stdp = strchr(tbuf, '>') + 1;
if (LogTag == NULL)
LogTag = __progname;
if (LogTag != NULL)
! fprintf(&f, "%s", LogTag);
if (LogStat & LOG_PID)
! fprintf(&f, "[%d]", getpid());
if (LogTag != NULL) {
! putc(':', &f);
! putc(' ', &f);
}
/* Substitute error message for %m. */
! for (t = fmt_cpy, fleft = FMT_LEN - 1; fleft > 0;) {
! cp = fmt;
! /* lifted from vfprintf.c */
! while ((n = mbtowc(&wc, fmt, MB_CUR_MAX), n = wc ? n : 0) > 0) {
! fmt += n;
! if (wc == '%') {
! fmt--;
! break;
! }
! }
! if ((m = fmt - cp) != 0) {
! if (m > fleft)
! m = fleft;
! memcpy(t, cp, m);
! fleft -= m;
! t += m;
! }
! if (n <= 0)
! break;
! fmt++; /* skip over '%' */
!
! ch = *fmt++;
! if (ch == 'm') {
! cp = strerror(saved_errno); /* better not contain % */
! m = strlen(cp);
! if (m > fleft)
! m = fleft;
! memcpy(t, cp, m);
! fleft -= m;
! t += m;
! } else {
! if (fleft > 0) {
! *t++ = '%';
! fleft--;
! }
! if (ch != '\0') {
! if (fleft > 0) {
! *t++ = ch;
! fleft--;
! }
! }
! }
! }
*t = '\0';
! vfprintf(&f, fmt_cpy, ap);
! cnt = strlen(tbuf);
/* Output to stderr if requested. */
if (LogStat & LOG_PERROR) {
***************
*** 182,189 ****
(fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) {
(void)strcat(tbuf, "\r\n");
cnt += 2;
! p = strchr(tbuf, '>') + 1;
! (void)write(fd, p, cnt - (p - tbuf));
(void)close(fd);
}
}
--- 230,236 ----
(fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) {
(void)strcat(tbuf, "\r\n");
cnt += 2;
! (void)write(fd, stdp, cnt - (stdp - tbuf));
(void)close(fd);
}
}
--- Truck