diff options
author | Paul Pluzhnikov <ppluzhnikov@google.com> | 2015-03-06 09:13:16 -0800 |
---|---|---|
committer | Paul Pluzhnikov <ppluzhnikov@google.com> | 2015-03-06 09:13:16 -0800 |
commit | 895c30cb003857b52c1675f9078e6a799b231bcb (patch) | |
tree | 5efa6be9373ca6e1d8dafe195aa639c19060e494 | |
parent | 5df56c7e3a236b39b3395e042015b541172f652b (diff) | |
download | glibc-895c30cb003857b52c1675f9078e6a799b231bcb.tar glibc-895c30cb003857b52c1675f9078e6a799b231bcb.tar.gz glibc-895c30cb003857b52c1675f9078e6a799b231bcb.tar.bz2 glibc-895c30cb003857b52c1675f9078e6a799b231bcb.zip |
Fix BZ #18043: buffer-overflow (read past the end) in wordexp/parse_dollars/parse_param
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | posix/wordexp-test.c | 31 | ||||
-rw-r--r-- | posix/wordexp.c | 2 |
4 files changed, 39 insertions, 2 deletions
@@ -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 @@ -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 8a312e0bcd..137044e95f 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 e3d8d6bd0d..1c144014b3 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; |