diff options
author | Paul Pluzhnikov <ppluzhnikov@google.com> | 2015-03-08 21:37:31 -0700 |
---|---|---|
committer | Paul Pluzhnikov <ppluzhnikov@google.com> | 2015-03-08 21:37:31 -0700 |
commit | 36103ba2f5db530bff24896dfc9076955fba3b5f (patch) | |
tree | 64edf820d8774dcf68f7b45cf6307b7d24fe92e4 /posix/wordexp-test.c | |
parent | 18d26750dd8fd328a78cf639fd0ec2494680a2a4 (diff) | |
download | glibc-36103ba2f5db530bff24896dfc9076955fba3b5f.tar.gz glibc-36103ba2f5db530bff24896dfc9076955fba3b5f.tar.xz glibc-36103ba2f5db530bff24896dfc9076955fba3b5f.zip |
Refactor wordexp-test.c such that words always ends at the edge of
unreadable page. This makes it easy to catch overflows, such as BZ #18043 (and BZ #18042).
Diffstat (limited to 'posix/wordexp-test.c')
-rw-r--r-- | posix/wordexp-test.c | 67 |
1 files changed, 36 insertions, 31 deletions
diff --git a/posix/wordexp-test.c b/posix/wordexp-test.c index 137044e95f..dfe4443cce 100644 --- a/posix/wordexp-test.c +++ b/posix/wordexp-test.c @@ -25,6 +25,7 @@ #include <stdlib.h> #include <string.h> #include <wordexp.h> +#include <libc-internal.h> #define IFS " \n\t" @@ -233,6 +234,8 @@ struct test_case_struct { WRDE_CMDSUB, NULL, "$((1+`echo 1`))", WRDE_NOCMD, 0, { NULL, }, IFS }, { WRDE_CMDSUB, NULL, "$((1+$((`echo 1`))))", WRDE_NOCMD, 0, { NULL, }, IFS }, + { WRDE_SYNTAX, NULL, "${", 0, 0, { NULL, }, IFS }, /* BZ 18043 */ + { -1, NULL, NULL, 0, 0, { NULL, }, IFS }, }; @@ -250,33 +253,6 @@ 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[]) { @@ -398,12 +374,32 @@ main (int argc, char *argv[]) printf ("tests failed: %d\n", fail); - if (do_bz18043 ()) - ++fail; - return fail != 0; } +static const char * +at_page_end (const char *words) +{ + 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 start; + + if (mprotect (start + pagesize, pagesize, PROT_NONE)) + { + munmap (start, 2 * pagesize); + return MAP_FAILED; + } + + /* Includes terminating NUL. */ + const size_t words_size = strlen (words) + 1; + char *words_start = start + pagesize - words_size; + memcpy (words_start, words, words_size); + + return words_start; +} static int testit (struct test_case_struct *tc) @@ -431,6 +427,8 @@ testit (struct test_case_struct *tc) we = sav_we; printf ("Test %d (%s): ", ++tests, tc->words); + fflush (NULL); + const char *words = at_page_end (tc->words); if (tc->flags & WRDE_NOCMD) registered_forks = 0; @@ -444,7 +442,7 @@ testit (struct test_case_struct *tc) return 1; } } - retval = wordexp (tc->words, &we, tc->flags); + retval = wordexp (words, &we, tc->flags); if ((tc->flags & WRDE_NOCMD) && (registered_forks > 0)) @@ -508,5 +506,12 @@ testit (struct test_case_struct *tc) if (retval == 0 || retval == WRDE_NOSPACE) wordfree (&we); + const int page_size = getpagesize (); + char *start = (char *) PTR_ALIGN_DOWN (words, page_size); + + if (munmap (start, 2 * page_size) != 0) + return 1; + + fflush (NULL); return bzzzt; } |