2a30b8f4b2
Upstream commit: dcaf51b41e259387602774829c45222d0507f90a - elf: Change ldconfig auxcache magic number (bug 32231) - Make tst-strtod-underflow type-generic - Add crt1-2.0.o for glibc 2.0 compatibility tests - Add tests of more strtod special cases - Add more tests of strtod end pointer - Make tst-strtod2 and tst-strtod5 type-generic - powerpc64le: Build new strtod tests with long double ABI flags (bug 32145) - Do not set errno for overflowing NaN payload in strtod/nan (bug 32045) - Improve NaN payload testing - Make __strtod_internal tests type-generic - Fix strtod subnormal rounding (bug 30220) - More thoroughly test underflow / errno in tst-strtod-round - Test errno setting on strtod overflow in tst-strtod-round - Add tests of fread - stdio-common: Add new test for fdopen - libio: Attempt wide backup free only for non-legacy code - debug: Fix read error handling in pcprofiledump - elf: Fix tst-dlopen-tlsreinit1.out test dependency - elf: Avoid re-initializing already allocated TLS in dlopen (bug 31717) - elf: Clarify and invert second argument of _dl_allocate_tls_init - elf: Support recursive use of dynamic TLS in interposed malloc - nptl: Use <support/check.h> facilities in tst-setuid3 - posix: Use <support/check.h> facilities in tst-truncate and tst-truncate64 - ungetc: Fix backup buffer leak on program exit [BZ #27821] - ungetc: Fix uninitialized read when putting into unused streams [BZ #27821] - Make tst-ungetc use libsupport - stdio-common: Add test for vfscanf with matches longer than INT_MAX [BZ #27650] - support: Add FAIL test failure helper - string: strerror, strsignal cannot use buffer after dlmopen (bug 32026) - Define __libc_initial for the static libc - x86: Fix bug in strchrnul-evex512 [BZ #32078] - Adjust check-local-headers test for libaudit 4.0 - x32/cet: Support shadow stack during startup for Linux 6.10 - x86-64: Remove sysdeps/x86_64/x32/dl-machine.h - support: Add options list terminator to the test driver - manual/stdio: Further clarify putc, putwc, getc, and getwc - Fix name space violation in fortify wrappers (bug 32052) - resolv: Fix tst-resolv-short-response for older GCC (bug 32042) - Add mremap tests - mremap: Update manual entry - linux: Update the mremap C implementation [BZ #31968] - Enhanced test coverage for strncmp, wcsncmp - Enhance test coverage for strnlen, wcsnlen Resolves: RHEL-57776 Resolves: RHEL-57777 Resolves: RHEL-61392
157 lines
3.8 KiB
Diff
157 lines
3.8 KiB
Diff
commit 49953727d1768baeef2914f709f35cb4acad2d0b
|
|
Author: Noah Goldstein <goldstein.w.n@gmail.com>
|
|
Date: Tue Aug 13 23:29:14 2024 +0800
|
|
|
|
x86: Fix bug in strchrnul-evex512 [BZ #32078]
|
|
|
|
Issue was we were expecting not matches with CHAR before the start of
|
|
the string in the page cross case.
|
|
|
|
The check code in the page cross case:
|
|
```
|
|
and $0xffffffffffffffc0,%rax
|
|
vmovdqa64 (%rax),%zmm17
|
|
vpcmpneqb %zmm17,%zmm16,%k1
|
|
vptestmb %zmm17,%zmm17,%k0{%k1}
|
|
kmovq %k0,%rax
|
|
inc %rax
|
|
shr %cl,%rax
|
|
je L(continue)
|
|
```
|
|
|
|
expects that all characters that neither match null nor CHAR will be
|
|
1s in `rax` prior to the `inc`. Then the `inc` will overflow all of
|
|
the 1s where no relevant match was found.
|
|
|
|
This is incorrect in the page-cross case, as the
|
|
`vmovdqa64 (%rax),%zmm17` loads from before the start of the input
|
|
string.
|
|
|
|
If there are matches with CHAR before the start of the string, `rax`
|
|
won't properly overflow.
|
|
|
|
The fix is quite simple. Just replace:
|
|
|
|
```
|
|
inc %rax
|
|
shr %cl,%rax
|
|
```
|
|
With:
|
|
```
|
|
sar %cl,%rax
|
|
inc %rax
|
|
```
|
|
|
|
The arithmetic shift will clear any matches prior to the start of the
|
|
string while maintaining the signbit so the 1s can properly overflow
|
|
to zero in the case of no matches.
|
|
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
|
|
|
(cherry picked from commit 7da08862471dfec6fdae731c2a5f351ad485c71f)
|
|
|
|
diff --git a/string/test-strchr.c b/string/test-strchr.c
|
|
index c795eac6fa7b93b9..72b17af687f6ad0e 100644
|
|
--- a/string/test-strchr.c
|
|
+++ b/string/test-strchr.c
|
|
@@ -255,6 +255,69 @@ check1 (void)
|
|
check_result (impl, s, c, exp_result);
|
|
}
|
|
|
|
+static void
|
|
+check2 (void)
|
|
+{
|
|
+ CHAR *s = (CHAR *) (buf1 + getpagesize () - 4 * sizeof (CHAR));
|
|
+ CHAR *s_begin = (CHAR *) (buf1 + getpagesize () - 64);
|
|
+#ifndef USE_FOR_STRCHRNUL
|
|
+ CHAR *exp_result = NULL;
|
|
+#else
|
|
+ CHAR *exp_result = s + 1;
|
|
+#endif
|
|
+ CHAR val = 0x12;
|
|
+ for (; s_begin != s; ++s_begin)
|
|
+ *s_begin = val;
|
|
+
|
|
+ s[0] = val + 1;
|
|
+ s[1] = 0;
|
|
+ s[2] = val + 1;
|
|
+ s[3] = val + 1;
|
|
+
|
|
+ {
|
|
+ FOR_EACH_IMPL (impl, 0)
|
|
+ check_result (impl, s, val, exp_result);
|
|
+ }
|
|
+ s[3] = val;
|
|
+ {
|
|
+ FOR_EACH_IMPL (impl, 0)
|
|
+ check_result (impl, s, val, exp_result);
|
|
+ }
|
|
+ exp_result = s;
|
|
+ s[0] = val;
|
|
+ {
|
|
+ FOR_EACH_IMPL (impl, 0)
|
|
+ check_result (impl, s, val, exp_result);
|
|
+ }
|
|
+
|
|
+ s[3] = val + 1;
|
|
+ {
|
|
+ FOR_EACH_IMPL (impl, 0)
|
|
+ check_result (impl, s, val, exp_result);
|
|
+ }
|
|
+
|
|
+ s[0] = val + 1;
|
|
+ s[1] = val + 1;
|
|
+ s[2] = val + 1;
|
|
+ s[3] = val + 1;
|
|
+ s[4] = val;
|
|
+ exp_result = s + 4;
|
|
+ {
|
|
+ FOR_EACH_IMPL (impl, 0)
|
|
+ check_result (impl, s, val, exp_result);
|
|
+ }
|
|
+ s[4] = 0;
|
|
+#ifndef USE_FOR_STRCHRNUL
|
|
+ exp_result = NULL;
|
|
+#else
|
|
+ exp_result = s + 4;
|
|
+#endif
|
|
+ {
|
|
+ FOR_EACH_IMPL (impl, 0)
|
|
+ check_result (impl, s, val, exp_result);
|
|
+ }
|
|
+}
|
|
+
|
|
int
|
|
test_main (void)
|
|
{
|
|
@@ -263,7 +326,7 @@ test_main (void)
|
|
test_init ();
|
|
|
|
check1 ();
|
|
-
|
|
+ check2 ();
|
|
printf ("%20s", "");
|
|
FOR_EACH_IMPL (impl, 0)
|
|
printf ("\t%s", impl->name);
|
|
diff --git a/sysdeps/x86_64/multiarch/strchr-evex-base.S b/sysdeps/x86_64/multiarch/strchr-evex-base.S
|
|
index 04e2c0e79e381691..3a0b7c9d6429fb20 100644
|
|
--- a/sysdeps/x86_64/multiarch/strchr-evex-base.S
|
|
+++ b/sysdeps/x86_64/multiarch/strchr-evex-base.S
|
|
@@ -124,13 +124,13 @@ L(page_cross):
|
|
VPCMPNE %VMM(1), %VMM(0), %k1
|
|
VPTEST %VMM(1), %VMM(1), %k0{%k1}
|
|
KMOV %k0, %VRAX
|
|
-# ifdef USE_AS_WCSCHR
|
|
+ sar %cl, %VRAX
|
|
+#ifdef USE_AS_WCSCHR
|
|
sub $VEC_MATCH_MASK, %VRAX
|
|
-# else
|
|
+#else
|
|
inc %VRAX
|
|
-# endif
|
|
+#endif
|
|
/* Ignore number of character for alignment adjustment. */
|
|
- shr %cl, %VRAX
|
|
jz L(align_more)
|
|
|
|
bsf %VRAX, %VRAX
|