From: Paul Pluzhnikov Date: Fri, 6 Mar 2015 17:13:16 +0000 (-0800) Subject: Fix BZ #18043: buffer-overflow (read past the end) in wordexp/parse_dollars/parse_param X-Git-Tag: glibc-2.22~505 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=895c30cb003857b52c1675f9078e6a799b231bcb;p=thirdparty%2Fglibc.git Fix BZ #18043: buffer-overflow (read past the end) in wordexp/parse_dollars/parse_param --- diff --git a/ChangeLog b/ChangeLog index 0eb779d91fc..da0b76943a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2015-03-06 Paul Pluzhnikov + + [BZ #18043] + * posix/wordexp.c (parse_param): Fix buffer overflow. + * posix/wordexp-test.c (do_bz18043): Add test case. + 2015-03-06 Vincent Bernat * time/tst-strptime2.c (do_test): Ensure failing tests are diff --git a/NEWS b/NEWS index 1f98e58da22..b4df84900f4 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 8a312e0bcd8..137044e95f3 100644 --- a/posix/wordexp-test.c +++ b/posix/wordexp-test.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -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 e3d8d6bd0d0..1c144014b36 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;