opnsense-src/lib/libc/amd64/string
Robert Clausecker 644d814471 lib/libc/amd64/string: fix overread condition in memccpy
An overread condition in memccpy(dst, src, c, len) would occur if
src does not cross a 16 byte boundary and there is no instance of
c between *src and the next 16 byte boundary.  This could cause a
read fault if src is just before the end of a page and the next page
is unmapped or unreadable.

The bug is a consequence of basing memccpy() on the strlcpy() code:
whereas strlcpy() assumes that src is a nul-terminated string and
hence a terminator is always present, c may not be present at all in
the source string.  It was not caught earlier due to insufficient
unit test design.

As a part of the fix, the function is refactored such that the runt
case (buffer length from last alignment boundary between 1 and 32 B)
is handled separately.  This reduces the number of conditional
branches on all code paths and simplifies the handling of early
matches in the non-runt case.  Performance is improved slightly.

os: FreeBSD
arch: amd64
cpu: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
        │ memccpy.unfixed.out │        memccpy.fixed.out           │
        │       sec/op        │   sec/op     vs base               │
Short             66.76µ ± 0%   62.45µ ± 1%  -6.44% (p=0.000 n=20)
Mid               7.938µ ± 0%   7.967µ ± 0%  +0.36% (p=0.001 n=20)
Long              3.577µ ± 0%   3.577µ ± 0%       ~ (p=0.429 n=20)
geomean           12.38µ        12.12µ       -2.08%

        │ memccpy.unfixed.out │         memccpy.fixed.out           │
        │         B/s         │     B/s       vs base               │
Short            1.744Gi ± 0%   1.864Gi ± 1%  +6.89% (p=0.000 n=20)
Mid              14.67Gi ± 0%   14.61Gi ± 0%  -0.36% (p=0.001 n=20)
Long             32.55Gi ± 0%   32.55Gi ± 0%       ~ (p=0.429 n=20)
geomean          9.407Gi        9.606Gi       +2.12%

Reported by:	getz
Reviewed by:	getz
Approved by:	mjg (blanket, via IRC)
See also:	D46051
MFC:		stable/14
Event:		GSoC 2024
Differential Revision:	https://reviews.freebsd.org/D46052
2024-08-07 16:18:40 +02:00
..
amd64_archlevel.c lib/libc/amd64: add archlevel-based simd dispatch framework 2023-08-04 01:53:43 +03:00
bcmp.S amd64: bring back asm bcmp, shared with memcmp 2022-03-26 09:10:03 +00:00
bcopy.c libc: Purge unneeded cdefs.h 2023-11-26 21:20:09 -07:00
bzero.c libc: Purge unneeded cdefs.h 2023-11-26 21:20:09 -07:00
Makefile.inc libc/amd64: Disable ASAN for amd64_archlevel.c 2024-01-30 13:01:58 -05:00
memccpy.S lib/libc/amd64/string: fix overread condition in memccpy 2024-08-07 16:18:40 +02:00
memchr.S lib/libc/amd64/string: add memchr(3) scalar, baseline implementation 2023-09-23 14:20:28 -04:00
memcmp.S lib/libc/amd64/string/memcmp.S: harden against phony buffer lengths 2023-09-23 14:21:42 -04:00
memcpy.S Remove $FreeBSD$: one-line .c comment pattern 2023-08-16 11:54:29 -06:00
memmove.S Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:42 -06:00
memrchr.S lib/libc/amd64/string: add memrchr() scalar, baseline implementation 2024-01-24 20:39:31 +01:00
memset.S Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:42 -06:00
stpcpy.S lib/libc/amd64/string/stpcpy.S: add baseline implementation 2023-08-21 20:59:38 +02:00
stpncpy.S lib/libc/amd64/string: add stpncpy scalar, baseline implementation 2024-01-24 20:39:27 +01:00
strcat.S lib/libc/amd64/string/strcat.S: enable use of SIMD 2024-01-24 20:39:28 +01:00
strchrnul.S lib/libc/amd64/string/strchrnul.S: fix edge case in scalar code 2023-08-28 19:45:51 +02:00
strcmp.S lib/libc/amd64/string/strcmp.S: add baseline implementation 2024-01-24 20:39:24 +01:00
strcpy.c libc: Purge unneeded cdefs.h 2023-11-26 21:20:09 -07:00
strcspn.S lib/libc/amd64/string: implement strpbrk() through strcspn() 2024-01-24 20:39:24 +01:00
strlcat.c lib/libc/amd64/string: implement strlcat() through strlcpy() 2024-01-24 20:39:29 +01:00
strlcpy.S lib/libc/amd64/string: add strlcpy scalar, baseline implementation 2024-01-24 20:39:28 +01:00
strlen.S Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:42 -06:00
strncat.c lib/libc/amd64/string: implement strncat() by calling strlen(), memccpy() 2024-01-24 20:39:30 +01:00
strncmp.S lib/libc/amd64/string: add strncmp scalar, baseline implementation 2024-01-24 20:39:25 +01:00
strncpy.c lib/libc/amd64/string: implement strncpy() by calling stpncpy() 2024-01-24 20:39:27 +01:00
strnlen.c libc: Purge unneeded cdefs.h 2023-11-26 21:20:09 -07:00
strpbrk.c lib/libc/amd64/string: implement strpbrk() through strcspn() 2024-01-24 20:39:24 +01:00
strrchr.S lib/libc/amd64/string: add strrchr scalar, baseline implementation 2024-01-24 20:39:26 +01:00
strsep.c lib/libc/amd64/string: implement strsep() through strcspn() 2024-01-24 20:39:26 +01:00
strspn.S lib/libc/amd64/string: add strspn(3) scalar, x86-64-v2 implementation 2023-09-23 14:20:28 -04:00
timingsafe_bcmp.S lib/libc/amd64/string: add timingsafe_bcmp(3) scalar, baseline implementations 2023-12-28 18:02:41 +01:00
timingsafe_memcmp.S lib/libc/amd64/string: add timingsafe_memcmp() assembly implementation 2023-12-28 18:02:41 +01:00