[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