Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/ul Fix a buffer overflow when reading from files con...



details:   https://anonhg.NetBSD.org/src/rev/8d1d0daae1f3
branches:  trunk
changeset: 345873:8d1d0daae1f3
user:      abhinav <abhinav%NetBSD.org@localhost>
date:      Sun Jun 12 13:29:29 2016 +0000

description:
Fix a buffer overflow when reading from files containing extra long lines.
Instead of using a statically allocated buffer, manage the buffer at run-time
and reallocate as needed.

It was dumping core for following two cases:
man evrpc | ul
man xdm | ul

While there, also remove __P macro from function prototypes.

Ok from Christos.

diffstat:

 usr.bin/ul/Makefile |    4 +-
 usr.bin/ul/ul.c     |  127 ++++++++++++++++++++++++++++++++-------------------
 2 files changed, 81 insertions(+), 50 deletions(-)

diffs (truncated from 310 to 300 lines):

diff -r e36919d644d0 -r 8d1d0daae1f3 usr.bin/ul/Makefile
--- a/usr.bin/ul/Makefile       Sun Jun 12 12:48:32 2016 +0000
+++ b/usr.bin/ul/Makefile       Sun Jun 12 13:29:29 2016 +0000
@@ -1,8 +1,8 @@
-#      $NetBSD: Makefile,v 1.6 2010/02/03 15:34:46 roy Exp $
+#      $NetBSD: Makefile,v 1.7 2016/06/12 13:29:29 abhinav Exp $
 #      @(#)Makefile    8.1 (Berkeley) 6/6/93
 
 PROG=  ul
 DPADD= ${LIBTERMINFO}
-LDADD= -lterminfo
+LDADD= -lterminfo -lutil
 
 .include <bsd.prog.mk>
diff -r e36919d644d0 -r 8d1d0daae1f3 usr.bin/ul/ul.c
--- a/usr.bin/ul/ul.c   Sun Jun 12 12:48:32 2016 +0000
+++ b/usr.bin/ul/ul.c   Sun Jun 12 13:29:29 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ul.c,v 1.16 2012/03/20 20:34:59 matt Exp $     */
+/*     $NetBSD: ul.c,v 1.17 2016/06/12 13:29:29 abhinav Exp $  */
 
 /*
  * Copyright (c) 1980, 1993
@@ -39,14 +39,16 @@
 #if 0
 static char sccsid[] = "@(#)ul.c       8.1 (Berkeley) 6/6/93";
 #endif
-__RCSID("$NetBSD: ul.c,v 1.16 2012/03/20 20:34:59 matt Exp $");
+__RCSID("$NetBSD: ul.c,v 1.17 2016/06/12 13:29:29 abhinav Exp $");
 #endif /* not lint */
 
+#include <err.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <term.h>
 #include <unistd.h>
+#include <util.h>
 
 #define        IESC    '\033'
 #define        SO      '\016'
@@ -74,25 +76,25 @@
        char    c_char;
 } ;
 
-struct CHAR    obuf[MAXBUF];
-int    col, maxcol;
+size_t col, maxcol;
 int    mode;
 int    halfpos;
 int    upln;
 int    iflag;
 
-int    main __P((int, char **));
-void   filter __P((FILE *));
-void   flushln __P((void));
-void   fwd __P((void));
-void   iattr __P((void));
-void   initbuf __P((void));
-void   initcap __P((void));
-void   outc __P((int));
-int    outchar __P((int));
-void   overstrike __P((void));
-void   reverse __P((void));
-void   setulmode __P((int));
+void filter(FILE *);
+void flushln(struct CHAR *, size_t);
+void fwd(struct CHAR *, size_t);
+void iattr(struct CHAR *);
+void initbuf(struct CHAR *, size_t);
+void initcap(void);
+void outc(int);
+int outchar(int);
+void overstrike(struct CHAR *);
+void reverse(struct CHAR *, size_t);
+void setulmode(int);
+static void alloc_buf(struct CHAR **, size_t *);
+static void set_mode(void);
 
 
 #define        PRINT(s)        if (s == NULL) /* void */; else tputs(s, 1, outchar)
@@ -128,19 +130,19 @@
        setupterm(termtype, 0, NULL);
        if ((over_strike && enter_bold_mode == NULL) ||
            (transparent_underline && enter_underline_mode == NULL &&
-            underline_char == NULL))
-       initbuf();
+               underline_char == NULL)) {
+               set_mode();
+       }
        if (optind == argc)
                filter(stdin);
-       else for (; optind<argc; optind++) {
-               f = fopen(argv[optind],"r");
-               if (f == NULL) {
-                       perror(argv[optind]);
-                       exit(1);
+       else {
+               for (; optind < argc; optind++) {
+                       f = fopen(argv[optind], "r");
+                       if (f == NULL)
+                               err(EXIT_FAILURE, "Failed to open `%s'", argv[optind]);
+                       filter(f);
+                       fclose(f);
                }
-
-               filter(f);
-               fclose(f);
        }
        exit(0);
 }
@@ -149,6 +151,9 @@
 filter(FILE *f)
 {
        int c;
+       struct  CHAR *obuf = NULL;
+       size_t obuf_size = 0;
+       alloc_buf(&obuf, &obuf_size);
 
        while ((c = getc(f)) != EOF) switch(c) {
 
@@ -161,6 +166,8 @@
                col = (col+8) & ~07;
                if (col > maxcol)
                        maxcol = col;
+               if (col >= obuf_size)
+                       alloc_buf(&obuf, &obuf_size);
                continue;
 
        case '\r':
@@ -187,7 +194,7 @@
                                halfpos--;
                        } else {
                                halfpos = 0;
-                               reverse();
+                               reverse(obuf, obuf_size);
                        }
                        continue;
 
@@ -200,12 +207,12 @@
                                halfpos++;
                        } else {
                                halfpos = 0;
-                               fwd();
+                               fwd(obuf, obuf_size);
                        }
                        continue;
 
                case FREV:
-                       reverse();
+                       reverse(obuf, obuf_size);
                        continue;
 
                default:
@@ -214,7 +221,6 @@
                                IESC, c);
                        exit(1);
                }
-               continue;
 
        case '_':
                if (obuf[col].c_char)
@@ -225,14 +231,16 @@
                col++;
                if (col > maxcol)
                        maxcol = col;
+               if (col >= obuf_size)
+                       alloc_buf(&obuf, &obuf_size);
                continue;
 
        case '\n':
-               flushln();
+               flushln(obuf, obuf_size);
                continue;
 
        case '\f':
-               flushln();
+               flushln(obuf, obuf_size);
                putchar('\f');
                continue;
 
@@ -252,17 +260,21 @@
                col++;
                if (col > maxcol)
                        maxcol = col;
+               if (col >= obuf_size)
+                       alloc_buf(&obuf, &obuf_size);
                continue;
        }
        if (maxcol)
-               flushln();
+               flushln(obuf, obuf_size);
+
+       free(obuf);
 }
 
 void
-flushln(void)
+flushln(struct CHAR *obuf, size_t obuf_size)
 {
        int lastmode;
-       int i;
+       size_t i;
        int hadmodes = 0;
 
        lastmode = NORMAL;
@@ -286,14 +298,14 @@
                setulmode(0);
        }
        if (must_overstrike && hadmodes)
-               overstrike();
+               overstrike(obuf);
        putchar('\n');
        if (iflag && hadmodes)
-               iattr();
+               iattr(obuf);
        (void)fflush(stdout);
        if (upln)
                upln--;
-       initbuf();
+       initbuf(obuf, obuf_size);
 }
 
 /*
@@ -301,9 +313,9 @@
  * We don't do anything with halfline ups and downs, or Greek.
  */
 void
-overstrike(void)
+overstrike(struct CHAR *obuf)
 {
-       int i;
+       size_t i;
        char lbuf[256];
        char *cp = lbuf;
        int hadbold=0;
@@ -339,9 +351,9 @@
 }
 
 void
-iattr(void)
+iattr(struct CHAR *obuf)
 {
-       int i;
+       size_t i;
        char lbuf[256];
        char *cp = lbuf;
 
@@ -363,32 +375,38 @@
 }
 
 void
-initbuf(void)
+initbuf(struct CHAR *obuf, size_t obuf_size)
 {
 
-       memset((char *)obuf, 0, sizeof (obuf)); /* depends on NORMAL == 0 */
+       memset(obuf, 0, obuf_size * sizeof(*obuf));     /* depends on NORMAL == 0 */
        col = 0;
        maxcol = 0;
+       set_mode();
+}
+
+static void
+set_mode(void)
+{
        mode &= ALTSET;
 }
 
 void
-fwd(void)
+fwd(struct CHAR *obuf, size_t obuf_size)
 {
        int oldcol, oldmax;
 
        oldcol = col;
        oldmax = maxcol;
-       flushln();
+       flushln(obuf, obuf_size);
        col = oldcol;
        maxcol = oldmax;
 }
 
 void
-reverse(void)
+reverse(struct CHAR *obuf, size_t obuf_size)
 {
        upln++;
-       fwd();
+       fwd(obuf, obuf_size);
        PRINT(cursor_up);
        PRINT(cursor_up);
        upln++;
@@ -484,3 +502,16 @@
        }
        curmode = newmode;
 }
+
+/*
+ * Reallocates the buffer pointed to by *buf and sets



Home | Main Index | Thread Index | Old Index