This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] Fixing where test-strncmp could read beyond page boundary
- From: Paul Clarke <pc at us dot ibm dot com>
- To: libc-alpha at sourceware dot org
- Date: Tue, 20 Dec 2016 11:19:27 -0600
- Subject: [PATCH] Fixing where test-strncmp could read beyond page boundary
- Authentication-results: sourceware.org; auth=none
- Reply-to: pc at us dot ibm dot com
In do_random_tests(), 2 "page" size buffers are used with various
offsets and lengths where the operations are fairly close to the end
of a page boundary. Most of the computations are done carefully to
avoid crossing the page boundary, except the actual "size" which is
eventually passed to strncmp() (via CALL_IMPL()) is not. "size" is
computed once and not adjusted to accommodate for the random offsets
into the buffers at which the strings to be compared start.
This change ensures that the "size" passed to strncmp() contains the
strings within the page.
I also added a number of comments within do_random_tests() in the
hope that someone new to the code will find it much more
comprehensible than I did.
2016-12-16 Paul A. Clarke <pc@us.ibm.com>
* string/test-strncmp.c (do_random_tests): Ensure "size" defines
strings within a single page.
---
string/test-strncmp.c | 40 +++++++++++++++++++++++++++++++++++++---
1 file changed, 37 insertions(+), 3 deletions(-)
diff --git a/string/test-strncmp.c b/string/test-strncmp.c
index fb57a9b..97768f9 100644
--- a/string/test-strncmp.c
+++ b/string/test-strncmp.c
@@ -264,33 +264,58 @@ do_random_tests (void)
size_t i, j, n, align1, align2, pos, len1, len2, size;
int result;
long r;
+ /* Get pointers near the end of a "page". */
UCHAR *p1 = (UCHAR *) (buf1 + page_size - 512 * CHARBYTES);
UCHAR *p2 = (UCHAR *) (buf2 + page_size - 512 * CHARBYTES);
for (n = 0; n < ITERATIONS; n++)
{
+ /* Start index for first string within p1. */
align1 = random () & 31;
+
+ /* Start index for second string within p2. */
if (random () & 1)
align2 = random () & 31;
else
align2 = align1 + (random () & 24);
- pos = random () & 511;
- size = random () & 511;
+
+ /* Compute larger offset into buffers. */
j = align1 > align2 ? align1 : align2;
- if (pos + j >= 511)
+
+ /* Position of difference between strings. */
+ pos = random () & 511;
+
+ /* Ensure pos within range for strings. */
+ if (j + pos >= 511)
pos = 510 - j - (random () & 7);
+
+ /* Maximum size of operation. */
+ size = random () & 511;
+
+ /* Ensure size within range for buffers. */
+ if (j + size >= 512)
+ size = 512 - j;
+
+ /* Actual length of 1st string. */
len1 = random () & 511;
if (pos >= len1 && (random () & 1))
len1 = pos + (random () & 7);
if (len1 + j >= 512)
len1 = 511 - j - (random () & 7);
+
+ /* Actual length of 2nd string. */
+ /* Note len2 >= len1. */
if (pos >= len1)
len2 = len1;
else
len2 = len1 + (len1 != 511 - j ? random () % (511 - j - len1) : 0);
+
+ /* Compute max length of strings, plus margin of dword. */
j = (pos > len2 ? pos : len2) + align1 + 64;
if (j > 512)
j = 512;
+
+ /* Fill p1 with random data. */
for (i = 0; i < j; ++i)
{
p1[i] = random () & 255;
@@ -301,6 +326,8 @@ do_random_tests (void)
p1[i] = 1 + (random () & 127);
}
}
+
+ /* Fill p2 with random data. */
for (i = 0; i < j; ++i)
{
p2[i] = random () & 255;
@@ -313,11 +340,15 @@ do_random_tests (void)
}
result = 0;
+
+ /* Make strings the same, up to position pos. */
MEMCPY (p2 + align2, p1 + align1, pos);
+
if (pos < len1)
{
if (p2[align2 + pos] == p1[align1 + pos])
{
+ /* Insert difference. */
p2[align2 + pos] = random () & 255;
if (p2[align2 + pos] == p1[align1 + pos])
p2[align2 + pos] = p1[align1 + pos] + 3 + (random () & 127);
@@ -325,12 +356,15 @@ do_random_tests (void)
if (pos < size)
{
+ /* Set expectations. */
if (p1[align1 + pos] < p2[align2 + pos])
result = -1;
else
result = 1;
}
}
+
+ /* Null terminate strings. */
p1[len1 + align1] = 0;
p2[len2 + align2] = 0;
--
Regards,
Paul Clarke, IBM