aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Clausecker <fuz@FreeBSD.org>2023-09-10 04:11:07 +0000
committerRobert Clausecker <fuz@FreeBSD.org>2023-09-10 12:52:59 +0000
commitb2618b651b28fd29e62a4e285f5be09ea30a85d4 (patch)
treeb5c14246f6b91423b9055f8745e9517683a21a95
parent4fc08109fe32264485a54a7ea45f4ec09a8fcf86 (diff)
downloadsrc-b2618b651b28fd29e62a4e285f5be09ea30a85d4.tar.gz
src-b2618b651b28fd29e62a4e285f5be09ea30a85d4.zip
lib/libc/amd64/string/memchr.S: fix behaviour with overly long buffers
When memchr(buf, c, len) is called with a phony len (say, SIZE_MAX), buf + len overflows and we have buf + len < buf. This confuses the implementation and makes it return incorrect results. Neverthless we must support this case as memchr() is guaranteed to work even with phony buffer lengths, as long as a match is found before the buffer actually ends. Sponsored by: The FreeBSD Foundation Reported by: yuri, des Tested by: des Approved by: mjg (blanket, via IRC) MFC after: 1 week MFC to: stable/14 PR: 273652
-rw-r--r--lib/libc/amd64/string/memchr.S9
1 files changed, 6 insertions, 3 deletions
diff --git a/lib/libc/amd64/string/memchr.S b/lib/libc/amd64/string/memchr.S
index e10bd6c22f90..cfab9b1302de 100644
--- a/lib/libc/amd64/string/memchr.S
+++ b/lib/libc/amd64/string/memchr.S
@@ -44,7 +44,9 @@ ARCHENTRY(__memchr, scalar)
je .Lnomatch
lea (, %rdi, 8), %ecx
- add %rdi, %rdx # pointer to end of buffer
+ mov $-1, %rax
+ add %rdi, %rdx # pointer to end of buffer or to end of
+ cmovc %rax, %rdx # address space (whichever comes first)
and $~7, %rdi # align to 8 bytes
mov (%rdi), %rax # load first word
movzbl %sil, %esi # clear stray high bits
@@ -118,14 +120,15 @@ ARCHENTRY(__memchr, baseline)
movd %esi, %xmm2
mov %edi, %ecx
- add %rdi, %rdx # pointer to end of buffer
+ mov $-1, %r9
+ add %rdi, %rdx # pointer to end of buffer or to end of
+ cmovc %r9, %rdx # address space (whichever comes first)
and $~0x1f, %rdi # align to 32 bytes
movdqa (%rdi), %xmm0 # load first 32 bytes
movdqa 16(%rdi), %xmm1
punpcklbw %xmm2, %xmm2 # c -> cc
- mov $-1, %r9d
shl %cl, %r9d # mask with zeroes before the string
punpcklwd %xmm2, %xmm2 # cc -> cccc