From patchwork Tue Dec 20 17:19:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Paul A. Clarke" X-Patchwork-Id: 18597 X-Patchwork-Delegate: rth@twiddle.net Received: (qmail 113091 invoked by alias); 20 Dec 2016 17:19:36 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 113079 invoked by uid 89); 20 Dec 2016 17:19:35 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=margin, buffers, Actual, clarke X-HELO: mx0a-001b2d01.pphosted.com Reply-To: pc@us.ibm.com To: libc-alpha@sourceware.org From: Paul Clarke Subject: [PATCH] Fixing where test-strncmp could read beyond page boundary Date: Tue, 20 Dec 2016 11:19:27 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1 MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16122017-0016-0000-0000-00000576DAAB X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00006284; HX=3.00000240; KW=3.00000007; PH=3.00000004; SC=3.00000198; SDB=6.00796564; UDB=6.00386610; IPR=6.00574377; BA=6.00004991; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00013665; XFM=3.00000011; UTC=2016-12-20 17:19:29 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16122017-0017-0000-0000-000035A5405E Message-Id: X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-12-20_12:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1612050000 definitions=main-1612200219 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 * 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;