bug-coreutils
[Top][All Lists]
Advanced

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

FYI: format string can cause stack overflow in ls


From: Jim Meyering
Subject: FYI: format string can cause stack overflow in ls
Date: Thu, 10 Mar 2005 13:41:14 +0100

A mischievously chosen format string can make ls overflow its stack.
Format strings can come from the command line, or via gettext.

Note however, that the new code below will rarely be used in practice,
since the initial, non-malloc'd, array sizes are so conservatively sized.
On one system I checked, sizeof init_bigbuf is over 2600.

2005-03-10  Jim Meyering  <address@hidden>

        Don't segfault for a very long date format string, e.g.,
        ls -ld --time-style=+%99999999H .
        * src/ls.c (long_time_expected_width): Use x2nrealloc, not alloca,
        so format string abuse cannot provoke stack overflow.
        (print_long_format): Likewise.

Index: ls.c
===================================================================
RCS file: /fetish/cu/src/ls.c,v
retrieving revision 1.375
diff -u -p -r1.375 ls.c
--- ls.c        6 Mar 2005 16:31:51 -0000       1.375
+++ ls.c        10 Mar 2005 12:06:42 -0000
@@ -3059,12 +3059,20 @@ long_time_expected_width (void)
          len = nstrftime (buf, bufsize, fmt, tm, 0, 0);
          if (len || ! *buf)
            break;
-         buf = alloca (bufsize *= 2);
+         if (buf == initbuf)
+           {
+             buf = NULL;
+             bufsize *= 2;
+           }
+         buf = x2nrealloc (buf, &bufsize, sizeof *buf);
        }
 
       width = mbsnwidth (buf, len, 0);
       if (width < 0)
        width = 0;
+
+      if (buf != initbuf)
+       free (buf);
     }
 
   return width;
@@ -3349,8 +3357,16 @@ print_long_format (const struct fileinfo
                         when_local, 0, when_ns);
          if (s || ! *p)
            break;
-         newbuf = alloca (bufsize *= 2);
-         memcpy (newbuf, buf, p - buf);
+         if (buf == init_bigbuf)
+           {
+             bufsize *= 2;
+             newbuf = xmalloc (bufsize);
+             memcpy (newbuf, buf, p - buf);
+           }
+         else
+           {
+             newbuf = x2nrealloc (buf, &bufsize, sizeof *buf);
+           }
          p = newbuf + (p - buf);
          buf = newbuf;
        }
@@ -3374,6 +3390,8 @@ print_long_format (const struct fileinfo
     }
 
   DIRED_FPUTS (buf, stdout, p - buf);
+  if (buf != init_bigbuf)
+    free (buf);
   print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok,
                           &dired_obstack);
 




reply via email to

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