This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.24-482-gb224637


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  b224637928e9fc04e3cef3e10d02ccf042d01584 (commit)
      from  e4d6a83565479c533aabae9046377a59712a5b22 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b224637928e9fc04e3cef3e10d02ccf042d01584

commit b224637928e9fc04e3cef3e10d02ccf042d01584
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Thu Dec 15 18:27:10 2016 +0000

    Fix powerpc64/power7 memchr for large input sizes
    
    Current optimized powercp64/power7 memchr uses a strategy to check for
    p versus align(p+n) (where 'p' is the input char pointer and n the
    maximum size to check for the byte) without taking care for possible
    overflow on the pointer addition in case of large 'n'.
    
    It was triggered by 3038145ca23 where default rawmemchr (used to
    created ppc64 rawmemchr in ifunc selection) now uses memchr (p, c, (size_t)-1)
    on its implementation.
    
    This patch fixes it by implement a satured addition where overflows
    sets the maximum pointer size to UINTPTR_MAX.
    
    Checked on powerpc64le-linux-gnu.
    
    	[BZ# 20971]
    	* sysdeps/powerpc/powerpc64/power7/memchr.S (__memchr): Avoid
    	overflow in pointer addition.
    	* string/test-memchr.c (do_test): Add an argument to pass as
    	the size on memchr.
    	(test_main): Add check for SIZE_MAX.

diff --git a/ChangeLog b/ChangeLog
index 374a69f..6285405 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2016-12-16  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+	[BZ# 20971]
+	* sysdeps/powerpc/powerpc64/power7/memchr.S (__memchr): Avoid
+	overflow in pointer addition.
+	* string/test-memchr.c (do_test): Add an argument to pass as
+	the size on memchr.
+	(test_main): Add check for SIZE_MAX.
+
 2016-12-16  Gabriel F. T. Gomes  <gftg@linux.vnet.ibm.com>
 
 	* math/Makefile (gen-libm-calls): Remove w_scalblnF.
diff --git a/string/test-memchr.c b/string/test-memchr.c
index 449a19a..e7ba02b 100644
--- a/string/test-memchr.c
+++ b/string/test-memchr.c
@@ -71,7 +71,7 @@ do_one_test (impl_t *impl, const CHAR *s, int c, size_t n, CHAR *exp_res)
 }
 
 static void
-do_test (size_t align, size_t pos, size_t len, int seek_char)
+do_test (size_t align, size_t pos, size_t len, size_t n, int seek_char)
 {
   size_t i;
   CHAR *result;
@@ -103,7 +103,7 @@ do_test (size_t align, size_t pos, size_t len, int seek_char)
     }
 
   FOR_EACH_IMPL (impl, 0)
-    do_one_test (impl, (CHAR *) (buf + align), seek_char, len, result);
+    do_one_test (impl, (CHAR *) (buf + align), seek_char, n, result);
 }
 
 static void
@@ -167,7 +167,7 @@ do_random_tests (void)
 int
 test_main (void)
 {
-  size_t i;
+  size_t i, j;
 
   test_init ();
 
@@ -178,15 +178,35 @@ test_main (void)
 
   for (i = 1; i < 8; ++i)
     {
-      do_test (0, 16 << i, 2048, 23);
-      do_test (i, 64, 256, 23);
-      do_test (0, 16 << i, 2048, 0);
-      do_test (i, 64, 256, 0);
+      do_test (0, 16 << i, 2048, 2048, 23);
+      do_test (i, 64, 256, 256, 23);
+      do_test (0, 16 << i, 2048, 2048, 0);
+      do_test (i, 64, 256, 256, 0);
+
+      /* Check for large input sizes and for these cases we need to
+	 make sure the bye is within the size range (that's why
+	 7 << i must be smaller than 2048.  */
+      do_test (0, 7 << i, 2048, SIZE_MAX, 23);
+      do_test (0, 2048 - i, 2048, SIZE_MAX, 23);
+      do_test (i, 64, 256, SIZE_MAX, 23);
+      do_test (0, 7 << i, 2048, SIZE_MAX, 0);
+      do_test (0, 2048 - i, 2048, SIZE_MAX, 0);
+      do_test (i, 64, 256, SIZE_MAX, 0);
     }
+
+  for (i = 1; i < 16; ++i)
+    {
+      for (j = 1; j < 16; j++)
+        {
+	  do_test (0, 16 - j, 16, SIZE_MAX, 23);
+	  do_test (i, 16 - j, 16, SIZE_MAX, 23);
+        }
+    }
+
   for (i = 1; i < 32; ++i)
     {
-      do_test (0, i, i + 1, 23);
-      do_test (0, i, i + 1, 0);
+      do_test (0, i, i + 1, i + 1, 23);
+      do_test (0, i, i + 1, i + 1, 0);
     }
 
   do_random_tests ();
diff --git a/sysdeps/powerpc/powerpc64/power7/memchr.S b/sysdeps/powerpc/powerpc64/power7/memchr.S
index 03f0d7c..0737100 100644
--- a/sysdeps/powerpc/powerpc64/power7/memchr.S
+++ b/sysdeps/powerpc/powerpc64/power7/memchr.S
@@ -26,7 +26,17 @@ ENTRY (__memchr)
 	dcbt	0,r3
 	clrrdi  r8,r3,3
 	insrdi	r4,r4,8,48
-	add	r7,r3,r5      /* Calculate the last acceptable address.  */
+
+	/* Calculate the last acceptable address and check for possible
+	   addition overflow by using satured math:
+	   r7 = r3 + r5
+	   r7 |= -(r7 < x)  */
+	add     r7,r3,r5
+	subfc   r6,r3,r7
+	subfe   r9,r9,r9
+	extsw   r6,r9
+	or      r7,r7,r6
+
 	insrdi	r4,r4,16,32
 	cmpldi	r5,32
 	li	r9, -1

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                 |    9 +++++++
 string/test-memchr.c                      |   38 ++++++++++++++++++++++-------
 sysdeps/powerpc/powerpc64/power7/memchr.S |   12 ++++++++-
 3 files changed, 49 insertions(+), 10 deletions(-)


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]