bug-gnu-utils
[Top][All Lists]
Advanced

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

gawk -f buffer overflow


From: Tim J. Robbins
Subject: gawk -f buffer overflow
Date: Mon, 18 Mar 2002 19:03:20 +1100
User-agent: Mutt/1.2.5.1i

Hi,

GNU Awk 3.0.6 fails to handle filenames >BUFSIZ bytes long. For example,
on FreeBSD 4.5, where /usr/bin/awk is gawk:

$ awk -f `perl -e 'print "A"x1022;'`
awk: fatal error: internal error
Abort(coredump)

I've checked that the bug still exists in 3.1.0 and supplied a patch that
fixes the bug by avoiding the use of a static buffer, instead using
malloc (it might be more efficient to use alloca).


--- io.c.old    Mon Mar 18 18:22:01 2002
+++ io.c        Mon Mar 18 18:49:05 2002
@@ -1922,8 +1922,8 @@
 {
        static const char *savepath = NULL;
        static int first = TRUE;
-       const char *awkpath;
-       char *cp, trypath[BUFSIZ];
+       const char *awkpath, *elstart;
+       char *trypath;
        int fd;
 
        if (STREQ(file, "-"))
@@ -1946,21 +1946,26 @@
                return (devopen(file, "r"));
 
        do {
-               trypath[0] = '\0';
-               /* this should take into account limits on size of trypath */
-               for (cp = trypath; *awkpath && *awkpath != envsep; )
-                       *cp++ = *awkpath++;
-
-               if (cp != trypath) {    /* nun-null element in path */
+               elstart = awkpath;
+               while (*awkpath && *awkpath != envsep)
+                       awkpath++;
+
+               if (elstart != awkpath) { /* nun-null element in path */
+                       emalloc(trypath, char *, awkpath - elstart + 1 +
+                               strlen(file), "do_pathopen");
                        /* add directory punctuation only if needed */
-                       if (! isdirpunct(*(cp-1)))
-                               *cp++ = '/';
-                       /* append filename */
-                       strcpy(cp, file);
-               } else
-                       strcpy(trypath, file);
-               if ((fd = devopen(trypath, "r")) > INVALID_HANDLE)
-                       return (fd);
+                       sprintf(trypath, "%.*s%s%s", awkpath - elstart,
+                               elstart, isdirpunct(*(awkpath - 1)) ? "" : "/",
+                               file);
+                       if ((fd = devopen(trypath, "r")) > INVALID_HANDLE) {
+                               free(trypath);
+                               return (fd);
+                       }
+                       free(trypath);
+               } else {
+                       if ((fd = devopen(file, "r")) > INVALID_HANDLE)
+                               return (fd);
+               }
 
                /* no luck, keep going */
                if(*awkpath == envsep && awkpath[1] != '\0')



Tim



reply via email to

[Prev in Thread] Current Thread [Next in Thread]