Fix BZ #18043: buffer-overflow (read past the end) in wordexp/parse_dollars/parse_param

This commit is contained in:
Paul Pluzhnikov 2015-03-06 09:13:16 -08:00
parent 5df56c7e3a
commit 895c30cb00
4 changed files with 39 additions and 2 deletions

View File

@ -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

2
NEWS
View File

@ -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

View 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;
}

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