opnsense-src/lib/libc/amd64
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
..
gen libc: Purge unneeded cdefs.h 2023-11-26 21:20:09 -07:00
stdlib Remove $FreeBSD$: one-line sh pattern 2023-08-16 11:55:03 -06:00
string lib/libc/amd64/string: fix overread condition in memccpy 2024-08-07 16:18:40 +02:00
sys libc: don't needlessly add vfork.o to NOASM 2024-01-02 16:58:54 +00:00
_fpmath.h Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:16 -06:00
amd64_archlevel.h lib/libc/amd64: add archlevel-based simd dispatch framework 2023-08-04 01:53:43 +03:00
arith.h Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:16 -06:00
gd_qnan.h Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:16 -06:00
Makefile.inc Remove $FreeBSD$: one-line sh pattern 2023-08-16 11:55:03 -06:00
static_tls.h Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:16 -06:00
Symbol.map libc: centralize a few numeric symbols 2023-12-13 22:08:14 +00:00
SYS.h Remove $FreeBSD$: one-line .h pattern 2023-08-16 11:54:23 -06:00