about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@mellanox.com>2017-01-16 15:38:25 -0500
committerChris Metcalf <cmetcalf@mellanox.com>2017-01-16 15:44:48 -0500
commit502697713f4f129b602d7213253a9982ee1989f1 (patch)
tree933c5eb4537e278df0cb0e2e664c40bc0afe6b38
parent4cb89c158124c27006903f10e309b09d5311053a (diff)
downloadglibc-502697713f4f129b602d7213253a9982ee1989f1.tar.gz
glibc-502697713f4f129b602d7213253a9982ee1989f1.tar.xz
glibc-502697713f4f129b602d7213253a9982ee1989f1.zip
tile: Check for pointer add overflow in memchr
As was done in b224637928e9, check for large size causing an overflow
in the loop that walks over the array.

Branching out of line here is the fastest approach for handling this
problem, since tile can bundle the instructions to compute the branch
test in parallel with doing the required memchr loop setup computation.

Unfortunately, the existing saturated ops (e.g. tilegx addxsc) are
all signed saturing ops, so don't help with unsigned saturation.
-rw-r--r--ChangeLog4
-rw-r--r--sysdeps/tile/tilegx/memchr.c4
-rw-r--r--sysdeps/tile/tilepro/memchr.c4
3 files changed, 12 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 5388306806..9498803f7f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2017-01-16  Chris Metcalf  <cmetcalf@mellanox.com>
 
+	* sysdeps/tile/tilegx/memchr.c (__memchr): Handle pointer
+	wrap-around.
+	* sysdeps/tile/tilepro/memchr.c (__memchr): Likewise.
+
 	* sysdeps/unix/sysv/linux/tile/ipc_priv.h: New file.
 
 2016-01-14  Siddhesh Poyarekar  <siddhesh@sourceware.org>
diff --git a/sysdeps/tile/tilegx/memchr.c b/sysdeps/tile/tilegx/memchr.c
index 34df19d231..7da0f79da2 100644
--- a/sysdeps/tile/tilegx/memchr.c
+++ b/sysdeps/tile/tilegx/memchr.c
@@ -51,6 +51,10 @@ __memchr (const void *s, int c, size_t n)
   /* Compute the address of the last byte. */
   last_byte_ptr = (const char *) s + n - 1;
 
+  /* Handle possible addition overflow.  */
+  if (__glibc_unlikely ((uintptr_t) last_byte_ptr < (uintptr_t) s))
+    last_byte_ptr = (const char *) UINTPTR_MAX;
+
   /* Compute the address of the word containing the last byte. */
   last_word_ptr = (const uint64_t *) ((uintptr_t) last_byte_ptr & -8);
 
diff --git a/sysdeps/tile/tilepro/memchr.c b/sysdeps/tile/tilepro/memchr.c
index 1848a9cadb..fba1f70c2c 100644
--- a/sysdeps/tile/tilepro/memchr.c
+++ b/sysdeps/tile/tilepro/memchr.c
@@ -51,6 +51,10 @@ __memchr (const void *s, int c, size_t n)
   /* Compute the address of the last byte. */
   last_byte_ptr = (const char *) s + n - 1;
 
+  /* Handle possible addition overflow.  */
+  if (__glibc_unlikely ((uintptr_t) last_byte_ptr < (uintptr_t) s))
+    last_byte_ptr = (const char *) UINTPTR_MAX;
+
   /* Compute the address of the word containing the last byte. */
   last_word_ptr = (const uint32_t *) ((uintptr_t) last_byte_ptr & -4);