[PATCH v2] string: Improve test-memchr page cross checks

Wilco Dijkstra Wilco.Dijkstra@arm.com
Mon May 11 12:58:55 GMT 2026


The tests for memchr attempt to check for accidental overreads that cross a page.
However they weren't done at the end of a page and don't check for the case where
we match right at the end.  Add buf1_size/buf2_size to make finding end of buffer
easier.

OK for commit?

---

diff --git a/string/test-memchr.c b/string/test-memchr.c
index 434b50d0271668100a3d3b984021e1decc458fd8..df9ce0f22c04c73472b134e89585c7557cd00dfc 100644
--- a/string/test-memchr.c
+++ b/string/test-memchr.c
@@ -85,30 +85,25 @@ do_test (size_t align, size_t pos, size_t len, size_t n, int seek_char)
   size_t i;
   CHAR *result;
 
-  if ((align + len) * sizeof (CHAR) >= page_size)
+  if ((align + len) * sizeof (CHAR) >= buf1_size)
     return;
 
   CHAR *buf = (CHAR *) (buf1);
 
-  for (i = 0; i < len; ++i)
+  for (i = 0; i <= len; ++i)
     {
       buf[align + i] = 1 + 23 * i % SMALL_CHAR;
       if (buf[align + i] == seek_char)
 	buf[align + i] = seek_char + 1;
     }
-  buf[align + len] = 0;
 
-  if (pos < MIN(n, len))
+  if (pos < MIN (n, len) || (pos == len && n > len))
     {
       buf[align + pos] = seek_char;
-      buf[align + len] = -seek_char;
       result = (CHAR *) (buf + align + pos);
     }
   else
-    {
-      result = NULL;
-      buf[align + len] = seek_char;
-    }
+    result = NULL;
 
   FOR_EACH_IMPL (impl, 0)
     do_one_test (impl, (CHAR *) (buf + align), seek_char, n, result);
@@ -152,7 +147,7 @@ do_random_tests (void)
   size_t i, j, n, align, pos, len;
   int seek_char;
   CHAR *result;
-  UCHAR *p = (UCHAR *) (buf1 + page_size) - 512;
+  UCHAR *p = (UCHAR *) (buf1 + buf1_size) - 512;
 
   for (n = 0; n < ITERATIONS; n++)
     {
@@ -257,12 +252,14 @@ test_main (void)
      with address near end of the page.  */
   for (i = 2; i < 16; ++i)
     {
-      /* page_size is in fact getpagesize() * 2.  */
-      do_test (page_size / 2 - i, i, i, 1, 0x9B);
-      do_test (page_size / 2 - i, i - 1, i - 1, 1, 0x9B);
-      do_test (page_size / 2 - (i * 4), i + 128, i + 128, i, 0x9B);
+      do_test ((buf1_size / sizeof(CHAR)) - i, i - 1, i - 1, 1, 0x9B);
+      do_test ((buf1_size / sizeof(CHAR)) - (i * 4), 128, i * 4 - 1, i, 0x9B);
     }
 
+  /* Check memchr won't overread after matching at the end of a page.  */
+  for (i = 1; i <= 256; i += 5)
+    do_test ((buf1_size / sizeof(CHAR)) - i - 1, i, i, 1024, 0x9B);
+
   do_random_tests ();
   do_overflow_tests ();
   return ret;
diff --git a/string/test-string.h b/string/test-string.h
index f2877662273d91507276e39c7bcb0f396b4c74c8..bc7e8fd0dfdf6d2f1d01e45045c8c26da8efffca 100644
--- a/string/test-string.h
+++ b/string/test-string.h
@@ -69,7 +69,7 @@ extern impl_t __start_impls[], __stop_impls[];
 unsigned char *buf1, *buf2;
 int ret, do_srandom;
 unsigned int seed;
-size_t page_size;
+size_t page_size, buf1_size, buf2_size;
 
 # ifndef ITERATIONS
 size_t iterations = 100000;
@@ -207,6 +207,9 @@ test_init (void)
 
   memset (buf1, 0xa5, BUF1PAGES * page_size);
   memset (buf2, 0x5a, page_size);
+
+  buf1_size = BUF1PAGES * page_size;
+  buf2_size = page_size;
 }
 
 #endif



More information about the Libc-alpha mailing list