Refactor wordexp-test.c such that words always ends at the edge of
authorPaul Pluzhnikov <ppluzhnikov@google.com>
Mon, 9 Mar 2015 04:37:31 +0000 (21:37 -0700)
committerPaul Pluzhnikov <ppluzhnikov@google.com>
Mon, 9 Mar 2015 04:37:31 +0000 (21:37 -0700)
unreadable page.

This makes it easy to catch overflows, such as BZ #18043 (and BZ #18042).

ChangeLog
posix/wordexp-test.c

index 4a5cd16..7858d6b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2015-03-09  Paul Pluzhnikov  <ppluzhnikov@google.com>
+
+       [BZ #18043]
+       * posix/wordexp-test.c (test_case): Add test for BZ #18043
+       (do_bz18043): Delete.
+       (at_page_end): New.
+       (testit): Refactor to have words at the edge of unreadable page.
+
 2015-03-08  Paul Pluzhnikov  <ppluzhnikov@google.com>
 
        [BZ #16734]
index 137044e..dfe4443 100644 (file)
@@ -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;
 }