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  <[EMAIL PROTECTED]>

        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);
 


_______________________________________________
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils

Reply via email to