]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix BZ #18043: buffer-overflow (read past the end) in wordexp/parse_dollars/parse_param
authorPaul Pluzhnikov <ppluzhnikov@google.com>
Fri, 6 Mar 2015 17:13:16 +0000 (09:13 -0800)
committerPaul Pluzhnikov <ppluzhnikov@google.com>
Fri, 6 Mar 2015 17:13:16 +0000 (09:13 -0800)
ChangeLog
NEWS
posix/wordexp-test.c
posix/wordexp.c

index 0eb779d91fced36b5ad4f063af8aa6b48ac29cef..da0b76943a253847e435d2ee8adb0795f5d00cb0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2015-03-06  Paul Pluzhnikov  <ppluzhnikov@google.com>
+
+       [BZ #18043]
+       * posix/wordexp.c (parse_param): Fix buffer overflow.
+       * posix/wordexp-test.c (do_bz18043): Add test case.
+
 2015-03-06  Vincent Bernat  <vincent@bernat.im>
 
        * time/tst-strptime2.c (do_test): Ensure failing tests are
diff --git a/NEWS b/NEWS
index 1f98e58da22a2fda7f6d9e338b1b1c6339dbbe30..b4df84900f4da61857c59017dc05f6623636b667 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -13,7 +13,7 @@ Version 2.22
   16560, 16783, 17269, 17523, 17569, 17588, 17631, 17711, 17776, 17779,
   17792, 17836, 17912, 17916, 17932, 17944, 17949, 17964, 17965, 17967,
   17969, 17978, 17987, 17991, 17996, 17998, 17999, 18019, 18020, 18029,
-  18030, 18032, 18036, 18038, 18039, 18046, 18047.
+  18030, 18032, 18036, 18038, 18039, 18043, 18046, 18047.
 
 * Character encoding and ctype tables were updated to Unicode 7.0.0, using
   new generator scripts contributed by Pravin Satpute and Mike FABIAN (Red
index 8a312e0bcd83bf98ab6ca2e7d443ed9b5051fd5f..137044e95f30591fd1fd0274e5555f626f3e5027 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/mman.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <pwd.h>
@@ -249,6 +250,33 @@ command_line_test (const char *words)
     printf ("we_wordv[%d] = \"%s\"\n", i, we.we_wordv[i]);
 }
 
+static int
+do_bz18043 (void)
+{
+  const int pagesize = getpagesize ();
+  char *start = mmap (0, 2 * pagesize, PROT_READ|PROT_WRITE,
+                     MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+
+  if (start == MAP_FAILED)
+    return 1;
+
+  if (mprotect (start + pagesize, pagesize, PROT_NONE))
+    return 2;
+
+  const char word[] = "${";
+  char *word_start = start + pagesize - sizeof (word);
+  memcpy (word_start, word, sizeof (word));
+
+  wordexp_t w;
+  if (wordexp (word_start, &w, 0) != WRDE_SYNTAX)
+    return 3;
+
+  if (munmap (start, 2 * pagesize) != 0)
+    return 4;
+
+  return 0;
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -370,6 +398,9 @@ main (int argc, char *argv[])
 
   printf ("tests failed: %d\n", fail);
 
+  if (do_bz18043 ())
+    ++fail;
+
   return fail != 0;
 }
 
index e3d8d6bd0d085599a3b72fbbf4b9bcb6ea53b8ef..1c144014b3607597e23f5005ea697754b2a654f7 100644 (file)
@@ -1299,7 +1299,7 @@ parse_param (char **word, size_t *word_length, size_t *max_length,
        }
       while (isdigit(words[++*offset]));
     }
-  else if (strchr ("*@$", words[*offset]) != NULL)
+  else if (words[*offset] != '\0' && strchr ("*@$", words[*offset]) != NULL)
     {
       /* Special parameter. */
       special = 1;