Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 10 Sep 2023 12:59:16 GMT
From:      Robert Clausecker <fuz@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: b2618b651b28 - main - lib/libc/amd64/string/memchr.S: fix behaviour with overly long buffers
Message-ID:  <202309101259.38ACxGYQ090164@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by fuz:

URL: https://cgit.FreeBSD.org/src/commit/?id=b2618b651b28fd29e62a4e285f5be09ea30a85d4

commit b2618b651b28fd29e62a4e285f5be09ea30a85d4
Author:     Robert Clausecker <fuz@FreeBSD.org>
AuthorDate: 2023-09-10 04:11:07 +0000
Commit:     Robert Clausecker <fuz@FreeBSD.org>
CommitDate: 2023-09-10 12:52:59 +0000

    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
---
 lib/libc/amd64/string/memchr.S | 9 ++++++---
 1 file 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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202309101259.38ACxGYQ090164>