Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 Jan 2001 00:58:36 -0500 (EST)
From:      Mike Heffner <mheffner@vt.edu>
To:        FreeBSD-audit <FreeBSD-audit@freebsd.org>
Subject:   lam(1) patch
Message-ID:  <XFMail.20010126005836.mheffner@vt.edu>

next in thread | raw e-mail | index | archive | help

The following patch fixes the following:

 - sprintf() -> snprintf()
 - manual (unbounded) while() loop string copying -> strlcpy()
 - use tolower() rather than bit or'ing
 - sanity check the user specified printf() format
 - prevent walking off end of inputfile array
 - some other string bounds issues

Reviews please?


Also available from:
http://filebox.vt.edu/users/mheffner/patches/lam.patch


Index: lam.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/lam/lam.c,v
retrieving revision 1.4
diff -u -r1.4 lam.c
--- lam.c       2000/07/10 09:14:15     1.4
+++ lam.c       2001/01/26 05:48:20
@@ -50,6 +50,7 @@
  *     Author:  John Kunze, UCB
  */
 
+#include <ctype.h>
 #include <err.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -114,7 +115,8 @@
        P = S = F = T = 0;              /* capitalized options */
        while ((p = *++av) != NULL) {
                if (*p != '-' || !p[1]) {
-                       morefiles++;
+                       if (++morefiles >= MAXOFILES)
+                               errx(1, "too many input files");
                        if (*p == '-')
                                ip->fp = stdin;
                        else if ((ip->fp = fopen(p, "r")) == NULL) {
@@ -130,7 +132,7 @@
                        ip++;
                        continue;
                }
-               switch (*(c = ++p) | 040) {
+               switch (tolower(*(c = ++p))) {
                case 's':
                        if (*++p || (p = *++av))
                                ip->sepstring = p;
@@ -149,13 +151,19 @@
                case 'p':
                        ip->pad = 1;
                        P = (*c == 'P' ? 1 : 0);
+                       /* FALLTHROUGH */
                case 'f':
                        F = (*c == 'F' ? 1 : 0);
                        if (*++p || (p = *++av)) {
                                fmtp += strlen(fmtp) + 1;
-                               if (fmtp > fmtbuf + BUFSIZ)
+                               if (fmtp >= fmtbuf + sizeof(fmtbuf))
                                        errx(1, "no more format space");
-                               sprintf(fmtp, "%%%ss", p);
+                               /* restrict format string to only valid width
formatters */
+                               if (strspn(p, "-.0123456789") != strlen(p))
+                                       errx(1, "invalid format string `%s'",
p);
+                               if (snprintf(fmtp, fmtbuf + sizeof(fmtbuf) -
fmtp, "%%%ss", p)
+                                   >= fmtbuf + sizeof(fmtbuf) - fmtp)
+                                       errx(1, "no more format space");
                                ip->format = fmtp;
                        }
                        else
@@ -175,13 +183,12 @@
 pad(ip)
        struct openfile *ip;
 {
-       register char *p = ip->sepstring;
        register char *lp = linep;
 
-       while (*p)
-               *lp++ = *p++;
+       strlcpy(lp, ip->sepstring, line + sizeof(line) - lp);
+       lp += strlen(lp);
        if (ip->pad) {
-               sprintf(lp, ip->format, "");
+               snprintf(lp, line + sizeof(line) - lp, ip->format, "");
                lp += strlen(lp);
        }
        return (lp);
@@ -199,7 +206,7 @@
 
        if (ip->eof)
                return (pad(ip));
-       for (p = s; (c = fgetc(ip->fp)) != EOF && p < end; p++)
+       for (p = s; (c = fgetc(ip->fp)) != EOF && p < end - 1; p++)
                if ((*p = c) == ip->eol)
                        break;
        *p = '\0';
@@ -210,10 +217,9 @@
                morefiles--;
                return (pad(ip));
        }
-       p = ip->sepstring;
-       while (*p)
-               *lp++ = *p++;
-       sprintf(lp, ip->format, s);
+       strlcpy(lp, ip->sepstring, line + sizeof(line) - lp);
+       lp += strlen(lp);
+       snprintf(lp, line + sizeof(line) - lp, ip->format, s);
        lp += strlen(lp);
        return (lp);
 }


-- 

  Mike Heffner       <mheffner@vt.edu>
  Blacksburg, VA           ICQ# 882073
  http://filebox.vt.edu/users/mheffner



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-audit" in the body of the message




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