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 18:14:03
On Aug 30,  2:27am, Don Lewis wrote:
} Subject: Re: Patch for 8lgm syslog/sendmail vulnerability, 4.4lite machine
} On Aug 29, 10:09pm, Don Lewis wrote:
} 
} Anyway, my submission is attached.  It hasn't broken in the modest amount
} of testing I've done on it.

Well, I've run a across a few minor bugs, the %m stuff still looks like
a wart.  Here's the NetBSD specific version of my latest patch:

*** ORIGsyslog.c	Wed Aug 30 18:10:18 1995
--- syslog.c	Wed Aug 30 18:09:49 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,207 ----
  
  	/* 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)) > 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);
! 	*f._p = '\0';
! 	cnt = f._p - f._bf._base;
  
  	/* 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);
  	}
  }
--- 231,237 ----
  	    (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