[2168] in bugtraq

home help back first fref pref prev next nref lref last post

Re: Patch for 8lgm syslog/sendmail vulnerability, 4.4lite machines

daemon@ATHENA.MIT.EDU (Charles Hannum)
Tue Aug 29 20:09:39 1995

Date:         Tue, 29 Aug 1995 13:55:38 -0400
Reply-To: Bugtraq List <BUGTRAQ@CRIMELAB.COM>
From: Charles Hannum <Charles-Hannum@deshaw.com>
X-To:         perry@piermont.com
To: Multiple recipients of list BUGTRAQ <BUGTRAQ@CRIMELAB.COM>
In-Reply-To:  <199508290909.FAA19050@frankenstein.piermont.com>
              (perry@piermont.com)

[Sigh.  I don't really have time to deal with this right now, but I
suppose it can't really wait.]

Your original patch has a couple of problems; mainly, `p' can still
overrun the end of the buffer, and thus more bytes are output than
should be.  In addition, the old special-case handling of `%m' is
annoying; it really should be done in vsnprintf().

Here's a replacement set of patches.  Please note that I have *not*
tested this.  (I'm also not happy with the static variable in
vfprintf(), but I'm not sure whether that's better or worse than
moving it outside the block and adding NL_TEXTMAX bytes of automatic
variables to vfprintf().)

I'll leave this to J.T. now...

(J.T.: Why does vfprintf() *always* call localeconv() to fetch the
decimal point string?  That seems inefficient at best.)


Index: gen/syslog.c
===================================================================
RCS file: /a/cvsroot/src/lib/libc/gen/syslog.c,v
retrieving revision 1.8
diff -c -2 -r1.8 syslog.c
*** syslog.c    1995/04/11 02:57:52     1.8
--- syslog.c    1995/08/29 17:46:59
***************
*** 70,73 ****
--- 70,75 ----
  extern char   *__progname;            /* Program name, from crt0. */

+ #define       TBUF_LEN        2048
+
  /*
   * syslog, vsyslog --
***************
*** 105,109 ****
        time_t now;
        int fd, saved_errno;
!       char *stdp, tbuf[2048], fmt_cpy[1024];

  #define       INTERNALLOG     LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
--- 107,114 ----
        time_t now;
        int fd, saved_errno;
!       size_t tbuf_left, prlen;
!       char *stdp, tbuf[TBUF_LEN];
!
!       tbuf_left = TBUF_LEN;

  #define       INTERNALLOG     LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
***************
*** 127,156 ****
        /* 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;

--- 132,187 ----
        /* Build the message. */
        (void)time(&now);
!
! #define       SYNC() \
!       p = tbuf + TBUF_LEN - tbuf_left
!
! #define       DEC() \
!       if (tbuf_left > prlen)          \
!               tbuf_left -= prlen;     \
!       else                            \
!               tbuf_left = 0;
!
!       SYNC();
!       prlen = snprintf(p, tbuf_left, "<%d>", pri);
!       DEC();
!
!       SYNC();
!       prlen = strftime(p, tbuf_left, "%h %e %T ", localtime(&now));
!       DEC();
!
!       if (LogStat & LOG_PERROR) {
!               SYNC();
                stdp = p;
+       }
+
        if (LogTag == NULL)
                LogTag = __progname;
        if (LogTag != NULL) {
+               SYNC();
+               prlen = snprintf(p, tbuf_left, "%s", LogTag);
+               DEC();
+       }
+
+       if (LogStat & LOG_PID) {
+               SYNC();
+               prlen = snprintf(p, tbuf_left, "[%d]", getpid());
+               DEC();
+       }
+
+       if (LogTag != NULL && tbuf_left > 1) {
+               SYNC();
                *p++ = ':';
!               tbuf_left--;
!               if (tbuf_left > 1) {
!                       *p++ = ' ';
!                       tbuf_left--;
!               }
        }

!       SYNC();
!       prlen = vsnprintf(p, tbuf_left, fmt, ap);
!       DEC();

!       SYNC();
        cnt = p - tbuf;

Index: stdio/vfprintf.c
===================================================================
RCS file: /a/cvsroot/src/lib/libc/stdio/vfprintf.c,v
retrieving revision 1.17
diff -c -2 -r1.17 vfprintf.c
*** vfprintf.c  1995/05/02 19:52:41     1.17
--- vfprintf.c  1995/08/29 17:46:59
***************
*** 48,51 ****
--- 48,53 ----
  #include <sys/types.h>

+ #include <errno.h>
+ #include <limits.h>
  #include <stdio.h>
  #include <stdlib.h>
***************
*** 61,64 ****
--- 63,68 ----
  #include "fvwrite.h"

+ extern char *__strerror __P((int , char *));
+
  /*
   * Flush out all the vectors defined by the given uio,
***************
*** 172,175 ****
--- 176,180 ----
        char sign;              /* sign prefix (' ', '+', '-', or \0) */
        wchar_t wc;
+       int saved_errno = errno;/* saved errno value for `%m' */
  #ifdef FLOATING_POINT
        char *decimal_point = localeconv()->decimal_point;
***************
*** 459,462 ****
--- 464,472 ----
                        break;
  #endif /* FLOATING_POINT */
+               case 'm': {
+                       static char buf[NL_TEXTMAX];
+                       cp = __strerror(saved_errno, buf);
+                       goto string;
+               }
                case 'n':
                        if (flags & QUADINT)
***************
*** 494,497 ****
--- 504,508 ----
                        if ((cp = va_arg(ap, char *)) == NULL)
                                cp = "(null)";
+               string:
                        if (prec >= 0) {
                                /*

home help back first fref pref prev next nref lref last post