Go to file
Noah Goldstein b712be5264 x86: Prevent SIGSEGV in memcmp-sse2 when data is concurrently modified [BZ #29863]
In the case of INCORRECT usage of `memcmp(a, b, N)` where `a` and `b`
are concurrently modified as `memcmp` runs, there can be a SIGSEGV
in `L(ret_nonzero_vec_end_0)` because the sequential logic
assumes that `(rdx - 32 + rax)` is a positive 32-bit integer.

To be clear, this change does not mean the usage of `memcmp` is
supported.  The program behaviour is undefined (UB) in the
presence of data races, and `memcmp` is incorrect when the values
of `a` and/or `b` are modified concurrently (data race). This UB
may manifest itself as a SIGSEGV. That being said, if we can
allow the idiomatic use cases, like those in yottadb with
opportunistic concurrency control (OCC), to execute without a
SIGSEGV, at no cost to regular use cases, then we can aim to
minimize harm to those existing users.

The fix replaces a 32-bit `addl %edx, %eax` with the 64-bit variant
`addq %rdx, %rax`. The 1-extra byte of code size from using the
64-bit instruction doesn't contribute to overall code size as the
next target is aligned and has multiple bytes of `nop` padding
before it. As well all the logic between the add and `ret` still
fits in the same fetch block, so the cost of this change is
basically zero.

The relevant sequential logic can be seen in the following
pseudo-code:
```
    /*
     * rsi = a
     * rdi = b
     * rdx = len - 32
     */
    /* cmp a[0:15] and b[0:15]. Since length is known to be [17, 32]
    in this case, this check is also assumed to cover a[0:(31 - len)]
    and b[0:(31 - len)].  */
    movups  (%rsi), %xmm0
    movups  (%rdi), %xmm1
    PCMPEQ  %xmm0, %xmm1
    pmovmskb %xmm1, %eax
    subl    %ecx, %eax
    jnz L(END_NEQ)

    /* cmp a[len-16:len-1] and b[len-16:len-1].  */
    movups  16(%rsi, %rdx), %xmm0
    movups  16(%rdi, %rdx), %xmm1
    PCMPEQ  %xmm0, %xmm1
    pmovmskb %xmm1, %eax
    subl    %ecx, %eax
    jnz L(END_NEQ2)
    ret

L(END2):
    /* Position first mismatch.  */
    bsfl    %eax, %eax

    /* The sequential version is able to assume this value is a
    positive 32-bit value because the first check included bytes in
    range a[0:(31 - len)] and b[0:(31 - len)] so `eax` must be
    greater than `31 - len` so the minimum value of `edx` + `eax` is
    `(len - 32) + (32 - len) >= 0`. In the concurrent case, however,
    `a` or `b` could have been changed so a mismatch in `eax` less or
    equal than `(31 - len)` is possible (the new low bound is `(16 -
    len)`. This can result in a negative 32-bit signed integer, which
    when zero extended to 64-bits is a random large value this out
    out of bounds. */
    addl %edx, %eax

    /* Crash here because 32-bit negative number in `eax` zero
    extends to out of bounds 64-bit offset.  */
    movzbl  16(%rdi, %rax), %ecx
    movzbl  16(%rsi, %rax), %eax
```

This fix is quite simple, just make the `addl %edx, %eax` 64 bit (i.e
`addq %rdx, %rax`). This prevents the 32-bit zero extension
and since `eax` is still a low bound of `16 - len` the `rdx + rax`
is bound by `(len - 32) - (16 - len) >= -16`. Since we have a
fixed offset of `16` in the memory access this must be in bounds.
2022-12-15 09:09:35 -08:00
argp configure: Use -Wno-ignored-attributes if compiler warns about multiple aliases 2022-11-01 09:51:06 -03:00
assert
benchtests benchtests: Make str{n}{cat|cpy} benchmarks output json 2022-11-08 19:22:33 -08:00
bits
catgets
ChangeLog.old
conform
crypt
csu elf: Introduce <dl-call_tls_init_tp.h> and call_tls_init_tp (bug 29249) 2022-11-03 17:28:03 +01:00
ctype
debug debug: Fix typo in tests-unsupported rule 2022-11-09 11:24:45 -03:00
dirent configure: Use -Wno-ignored-attributes if compiler warns about multiple aliases 2022-11-01 09:51:06 -03:00
dlfcn
elf elf: Do not assume symbol order on tst-audit25{a,b} 2022-12-12 09:53:20 -03:00
gmon
gnulib
grp
gshadow
hesiod
htl
hurd
iconv
iconvdata iconvdata/tst-table-charmap.sh: remove handling of old, borrowed format 2022-11-09 13:48:46 +01:00
include Define in_int32_t_range to check if the 64 bit time_t syscall should be used 2022-11-17 14:35:13 -03:00
inet configure: Use -Wno-ignored-attributes if compiler warns about multiple aliases 2022-11-01 09:51:06 -03:00
intl
io Linux: Add ppoll fortify symbol for 64 bit time_t (BZ# 29746) 2022-11-08 13:37:06 -03:00
libio stdlib: Move _IO_cleanup to call_function_static_weak 2022-12-12 09:53:23 -03:00
locale
localedata
login configure: Use -Wno-ignored-attributes if compiler warns about multiple aliases 2022-11-01 09:51:06 -03:00
mach
malloc realloc: Return unchanged if request is within usable size 2022-12-08 11:23:43 -05:00
manual
math Disable use of -fsignaling-nans if compiler does not support it 2022-11-01 09:46:08 -03:00
mathvec
misc Apply asm redirections in syslog.h before first use [BZ #27087] 2022-11-29 15:07:22 -03:00
nis nis: Build libnsl with 64 bit time_t 2022-12-09 09:56:09 -03:00
nptl Define in_int32_t_range to check if the 64 bit time_t syscall should be used 2022-11-17 14:35:13 -03:00
nptl_db
nscd nscd: Use 64 bit time_t on libc nscd routines (BZ# 29402) 2022-12-09 09:56:09 -03:00
nss
po
posix posix: Make posix_spawn extensions available by default 2022-11-04 13:29:52 +01:00
pwd
resolv configure: Use -Wno-ignored-attributes if compiler warns about multiple aliases 2022-11-01 09:51:06 -03:00
resource configure: Use -Wno-ignored-attributes if compiler warns about multiple aliases 2022-11-01 09:51:06 -03:00
rt
scripts configure: Remove AS check 2022-12-06 09:40:19 -03:00
setjmp
shadow
signal
socket configure: Use -Wno-ignored-attributes if compiler warns about multiple aliases 2022-11-01 09:51:06 -03:00
soft-fp
stdio-common stdio-common: Add missing dependencies (bug 29780) 2022-11-21 17:37:33 +01:00
stdlib stdlib: Move _IO_cleanup to call_function_static_weak 2022-12-12 09:53:23 -03:00
string string: Add len=0 to {w}memcmp{eq} tests and benchtests 2022-11-08 19:19:35 -08:00
sunrpc
support scripts: Add "|" operator support to glibcpp's parsing 2022-11-29 14:33:56 -08:00
sysdeps x86: Prevent SIGSEGV in memcmp-sse2 when data is concurrently modified [BZ #29863] 2022-12-15 09:09:35 -08:00
sysvipc
termios configure: Use -Wno-ignored-attributes if compiler warns about multiple aliases 2022-11-01 09:51:06 -03:00
time time: Use 64 bit time on tzfile 2022-12-09 09:56:09 -03:00
timezone
wcsmbs configure: Use -Wno-ignored-attributes if compiler warns about multiple aliases 2022-11-01 09:51:06 -03:00
wctype configure: Use -Wno-ignored-attributes if compiler warns about multiple aliases 2022-11-01 09:51:06 -03:00
.clang-format
.gitattributes
.gitignore
abi-tags
aclocal.m4 configure: Remove AS check 2022-12-06 09:40:19 -03:00
config.h.in
config.make.in
configure configure: Remove AS check 2022-12-06 09:40:19 -03:00
configure.ac configure: Remove AS check 2022-12-06 09:40:19 -03:00
CONTRIBUTED-BY
COPYING
COPYING.LIB
extra-lib.mk
gen-locales.mk
INSTALL
libc-abis
libof-iterator.mk
LICENSES arc4random: simplify design for better safety 2022-07-27 08:58:27 -03:00
MAINTAINERS
Makeconfig nis: Build libnsl with 64 bit time_t 2022-12-09 09:56:09 -03:00
Makefile
Makefile.help
Makefile.in
Makerules stdlib: Move _IO_cleanup to call_function_static_weak 2022-12-12 09:53:23 -03:00
NEWS
o-iterator.mk
README
Rules
SHARED-FILES
shlib-versions
test-skeleton.c
version.h

This directory contains the sources of the GNU C Library.
See the file "version.h" for what release version you have.

The GNU C Library is the standard system C library for all GNU systems,
and is an important part of what makes up a GNU system.  It provides the
system API for all programs written in C and C-compatible languages such
as C++ and Objective C; the runtime facilities of other programming
languages use the C library to access the underlying operating system.

In GNU/Linux systems, the C library works with the Linux kernel to
implement the operating system behavior seen by user applications.
In GNU/Hurd systems, it works with a microkernel and Hurd servers.

The GNU C Library implements much of the POSIX.1 functionality in the
GNU/Hurd system, using configurations i[4567]86-*-gnu.

When working with Linux kernels, this version of the GNU C Library
requires Linux kernel version 3.2 or later.

Also note that the shared version of the libgcc_s library must be
installed for the pthread library to work correctly.

The GNU C Library supports these configurations for using Linux kernels:

	aarch64*-*-linux-gnu
	alpha*-*-linux-gnu
	arc*-*-linux-gnu
	arm-*-linux-gnueabi
	csky-*-linux-gnuabiv2
	hppa-*-linux-gnu
	i[4567]86-*-linux-gnu
	x86_64-*-linux-gnu	Can build either x86_64 or x32
	ia64-*-linux-gnu
	loongarch64-*-linux-gnu Hardware floating point, LE only.
	m68k-*-linux-gnu
	microblaze*-*-linux-gnu
	mips-*-linux-gnu
	mips64-*-linux-gnu
	or1k-*-linux-gnu
	powerpc-*-linux-gnu	Hardware or software floating point, BE only.
	powerpc64*-*-linux-gnu	Big-endian and little-endian.
	s390-*-linux-gnu
	s390x-*-linux-gnu
	riscv32-*-linux-gnu
	riscv64-*-linux-gnu
	sh[34]-*-linux-gnu
	sparc*-*-linux-gnu
	sparc64*-*-linux-gnu

If you are interested in doing a port, please contact the glibc
maintainers; see https://www.gnu.org/software/libc/ for more
information.

See the file INSTALL to find out how to configure, build, and install
the GNU C Library.  You might also consider reading the WWW pages for
the C library at https://www.gnu.org/software/libc/.

The GNU C Library is (almost) completely documented by the Texinfo manual
found in the `manual/' subdirectory.  The manual is still being updated
and contains some known errors and omissions; we regret that we do not
have the resources to work on the manual as much as we would like.  For
corrections to the manual, please file a bug in the `manual' component,
following the bug-reporting instructions below.  Please be sure to check
the manual in the current development sources to see if your problem has
already been corrected.

Please see https://www.gnu.org/software/libc/bugs.html for bug reporting
information.  We are now using the Bugzilla system to track all bug reports.
This web page gives detailed information on how to report bugs properly.

The GNU C Library is free software.  See the file COPYING.LIB for copying
conditions, and LICENSES for notices about a few contributions that require
these additional notices to be distributed.  License copyright years may be
listed using range notation, e.g., 1996-2015, indicating that every year in
the range, inclusive, is a copyrightable year that would otherwise be listed
individually.