summaryrefslogtreecommitdiff
path: root/posix
diff options
context:
space:
mode:
authorPaul Pluzhnikov <ppluzhnikov@google.com>2015-03-08 21:37:31 -0700
committerPaul Pluzhnikov <ppluzhnikov@google.com>2015-03-08 21:37:31 -0700
commit36103ba2f5db530bff24896dfc9076955fba3b5f (patch)
tree64edf820d8774dcf68f7b45cf6307b7d24fe92e4 /posix
parent18d26750dd8fd328a78cf639fd0ec2494680a2a4 (diff)
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')
-rw-r--r--posix/wordexp-test.c67
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;
}