aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--NEWS2
-rw-r--r--posix/wordexp-test.c31
-rw-r--r--posix/wordexp.c2
4 files changed, 39 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 0eb779d..da0b769 100644
--- 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 1f98e58..b4df849 100644
--- 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
diff --git a/posix/wordexp-test.c b/posix/wordexp-test.c
index 8a312e0..137044e 100644
--- a/posix/wordexp-test.c
+++ b/posix/wordexp-test.c
@@ -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;
}
diff --git a/posix/wordexp.c b/posix/wordexp.c
index e3d8d6b..1c14401 100644
--- a/posix/wordexp.c
+++ b/posix/wordexp.c
@@ -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;