summary refs log tree commit diff
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2017-12-14 09:05:46 -0200
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2017-12-19 12:02:36 -0200
commit3bb1ef58b989012f8199b82af6ec136da2f9fda3 (patch)
treed889f9c9f475b0941cf558ede5af73d5cefebc1b
parent554e3d51efdd7d15c15876b80a7cba3ad9b6a738 (diff)
downloadglibc-3bb1ef58b989012f8199b82af6ec136da2f9fda3.tar.gz
glibc-3bb1ef58b989012f8199b82af6ec136da2f9fda3.tar.xz
glibc-3bb1ef58b989012f8199b82af6ec136da2f9fda3.zip
ia64: Fix memchr for large input sizes (BZ #22603)
Current optimized ia64 memchr uses a strategy to check for last address
by adding the input one with expected size.  However it does not take
care for possible overflow.

It was triggered by 3038145ca23 where default rawmemchr now uses memchr
(p, c, (size_t)-1).

This patch fixes it by implement a satured addition where overflows
sets the maximum pointer size to UINTPTR_MAX.

Checked on ia64-linux-gnu where it fixes both stratcliff and
test-rawmemchr failures.

	Adhemerval Zanella  <adhemerval.zanella@linaro.org>
	James Clarke <jrtc27@jrtc27.com>

	[BZ #22603]
	* sysdeps/ia64/memchr.S (__memchr): Avoid overflow in pointer
	addition.
-rw-r--r--ChangeLog7
-rw-r--r--sysdeps/ia64/memchr.S4
2 files changed, 11 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index b608b24814..4b88a8601d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,11 @@
 2017-12-19  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+	    James Clarke <jrtc27@jrtc27.com>
+
+	[BZ #22603]
+	* sysdeps/ia64/memchr.S (__memchr): Avoid overflow in pointer
+	addition.
+
+2017-12-19  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
 
 	[BZ #22605]
 	* sysdeps/unix/sysv/linux/sh/clone.S (__clone): Fix exit return
diff --git a/sysdeps/ia64/memchr.S b/sysdeps/ia64/memchr.S
index d60cf7bd87..9a0abc6f0a 100644
--- a/sysdeps/ia64/memchr.S
+++ b/sysdeps/ia64/memchr.S
@@ -67,6 +67,10 @@ ENTRY(__memchr)
 	.body
 	mov	ret0 = str
 	add	last = str, in2		// last byte
+	;;
+	cmp.ltu	p6, p0 = last, str
+	;;
+(p6)	mov	last = -1
 	and	tmp = 7, str		// tmp = str % 8
 	cmp.ne	p7, p0 = r0, r0		// clear p7
 	extr.u	chr = in1, 0, 8		// chr = (unsigned char) in1