x86: Fix wcsnlen-avx2 page cross length comparison
(cherry picked from commit 37e8226583d88a2b812ae226ad51ca3b0df08f67)
This commit is contained in:
parent
a66e7ff97f
commit
bd29306baa
@ -0,0 +1,136 @@
|
||||
From b0969fa53a28b4ab2159806bf6c99a98999502ee Mon Sep 17 00:00:00 2001
|
||||
From: Noah Goldstein <goldstein.w.n@gmail.com>
|
||||
Date: Tue, 20 Sep 2022 17:58:04 -0700
|
||||
Subject: [PATCH] x86: Fix wcsnlen-avx2 page cross length comparison [BZ
|
||||
#29591]
|
||||
|
||||
Previous implementation was adjusting length (rsi) to match
|
||||
bytes (eax), but since there is no bound to length this can cause
|
||||
overflow.
|
||||
|
||||
Fix is to just convert the byte-count (eax) to length by dividing by
|
||||
sizeof (wchar_t) before the comparison.
|
||||
|
||||
Conflict:adapt context.
|
||||
Reference:https://sourceware.org/git/?p=glibc.git;a=commit;h=b0969fa53a28b4ab2159806bf6c99a98999502ee
|
||||
|
||||
Full check passes on x86-64 and build succeeds w/ and w/o multiarch.
|
||||
---
|
||||
string/test-strnlen.c | 70 +++++++++++++++-----------
|
||||
sysdeps/x86_64/multiarch/strlen-avx2.S | 7 +--
|
||||
2 files changed, 43 insertions(+), 34 deletions(-)
|
||||
|
||||
diff --git a/string/test-strnlen.c b/string/test-strnlen.c
|
||||
index 4a9375112a..5cbaf4b734 100644
|
||||
--- a/string/test-strnlen.c
|
||||
+++ b/string/test-strnlen.c
|
||||
@@ -73,7 +73,7 @@ do_test (size_t align, size_t len, size_t maxlen, int max_char)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
- align &= 63;
|
||||
+ align &= (getpagesize () / sizeof (CHAR) - 1);
|
||||
if ((align + len) * sizeof (CHAR) >= page_size)
|
||||
return;
|
||||
|
||||
@@ -90,36 +90,50 @@ do_test (size_t align, size_t len, size_t maxlen, int max_char)
|
||||
static void
|
||||
do_overflow_tests (void)
|
||||
{
|
||||
- size_t i, j, len;
|
||||
+ size_t i, j, al_idx, repeats, len;
|
||||
const size_t one = 1;
|
||||
uintptr_t buf_addr = (uintptr_t) buf1;
|
||||
+ const size_t alignments[] = { 0, 1, 7, 9, 31, 33, 63, 65, 95, 97, 127, 129 };
|
||||
|
||||
- for (i = 0; i < 750; ++i)
|
||||
+ for (al_idx = 0; al_idx < sizeof (alignments) / sizeof (alignments[0]);
|
||||
+ al_idx++)
|
||||
{
|
||||
- do_test (0, i, SIZE_MAX - i, BIG_CHAR);
|
||||
- do_test (0, i, i - buf_addr, BIG_CHAR);
|
||||
- do_test (0, i, -buf_addr - i, BIG_CHAR);
|
||||
- do_test (0, i, SIZE_MAX - buf_addr - i, BIG_CHAR);
|
||||
- do_test (0, i, SIZE_MAX - buf_addr + i, BIG_CHAR);
|
||||
-
|
||||
- len = 0;
|
||||
- for (j = 8 * sizeof(size_t) - 1; j ; --j)
|
||||
- {
|
||||
- len |= one << j;
|
||||
- do_test (0, i, len - i, BIG_CHAR);
|
||||
- do_test (0, i, len + i, BIG_CHAR);
|
||||
- do_test (0, i, len - buf_addr - i, BIG_CHAR);
|
||||
- do_test (0, i, len - buf_addr + i, BIG_CHAR);
|
||||
-
|
||||
- do_test (0, i, ~len - i, BIG_CHAR);
|
||||
- do_test (0, i, ~len + i, BIG_CHAR);
|
||||
- do_test (0, i, ~len - buf_addr - i, BIG_CHAR);
|
||||
- do_test (0, i, ~len - buf_addr + i, BIG_CHAR);
|
||||
-
|
||||
- do_test (0, i, -buf_addr, BIG_CHAR);
|
||||
- do_test (0, i, j - buf_addr, BIG_CHAR);
|
||||
- do_test (0, i, -buf_addr - j, BIG_CHAR);
|
||||
- }
|
||||
+ for (repeats = 0; repeats < 2; ++repeats)
|
||||
+ {
|
||||
+ size_t align = repeats ? (getpagesize () - alignments[al_idx])
|
||||
+ : alignments[al_idx];
|
||||
+ align /= sizeof (CHAR);
|
||||
+ for (i = 0; i < 750; ++i)
|
||||
+ {
|
||||
+ do_test (align, i, SIZE_MAX, BIG_CHAR);
|
||||
+
|
||||
+ do_test (align, i, SIZE_MAX - i, BIG_CHAR);
|
||||
+ do_test (align, i, i - buf_addr, BIG_CHAR);
|
||||
+ do_test (align, i, -buf_addr - i, BIG_CHAR);
|
||||
+ do_test (align, i, SIZE_MAX - buf_addr - i, BIG_CHAR);
|
||||
+ do_test (align, i, SIZE_MAX - buf_addr + i, BIG_CHAR);
|
||||
+
|
||||
+ len = 0;
|
||||
+ for (j = 8 * sizeof (size_t) - 1; j; --j)
|
||||
+ {
|
||||
+ len |= one << j;
|
||||
+ do_test (align, i, len, BIG_CHAR);
|
||||
+ do_test (align, i, len - i, BIG_CHAR);
|
||||
+ do_test (align, i, len + i, BIG_CHAR);
|
||||
+ do_test (align, i, len - buf_addr - i, BIG_CHAR);
|
||||
+ do_test (align, i, len - buf_addr + i, BIG_CHAR);
|
||||
+
|
||||
+ do_test (align, i, ~len - i, BIG_CHAR);
|
||||
+ do_test (align, i, ~len + i, BIG_CHAR);
|
||||
+ do_test (align, i, ~len - buf_addr - i, BIG_CHAR);
|
||||
+ do_test (align, i, ~len - buf_addr + i, BIG_CHAR);
|
||||
+
|
||||
+ do_test (align, i, -buf_addr, BIG_CHAR);
|
||||
+ do_test (align, i, j - buf_addr, BIG_CHAR);
|
||||
+ do_test (align, i, -buf_addr - j, BIG_CHAR);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/sysdeps/x86_64/multiarch/strlen-avx2.S b/sysdeps/x86_64/multiarch/strlen-avx2.S
|
||||
index 0593fb303b..b9b58ef599 100644
|
||||
--- a/sysdeps/x86_64/multiarch/strlen-avx2.S
|
||||
+++ b/sysdeps/x86_64/multiarch/strlen-avx2.S
|
||||
@@ -544,14 +544,11 @@ L(return_vzeroupper):
|
||||
L(cross_page_less_vec):
|
||||
tzcntl %eax, %eax
|
||||
# ifdef USE_AS_WCSLEN
|
||||
- /* NB: Multiply length by 4 to get byte count. */
|
||||
- sall $2, %esi
|
||||
+ /* NB: Divide by 4 to convert from byte-count to length. */
|
||||
+ shrl $2, %eax
|
||||
# endif
|
||||
cmpq %rax, %rsi
|
||||
cmovb %esi, %eax
|
||||
-# ifdef USE_AS_WCSLEN
|
||||
- shrl $2, %eax
|
||||
-# endif
|
||||
VZEROUPPER_RETURN
|
||||
# endif
|
||||
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -66,7 +66,7 @@
|
||||
##############################################################################
|
||||
Name: glibc
|
||||
Version: 2.34
|
||||
Release: 103
|
||||
Release: 104
|
||||
Summary: The GNU libc libraries
|
||||
License: %{all_license}
|
||||
URL: http://www.gnu.org/software/glibc/
|
||||
@ -244,6 +244,7 @@ Patch156: backport-Fix-OOB-read-in-stdlib-thousand-grouping-parsing-BZ.patch
|
||||
Patch157: backport-elf-Remove-allocate-use-on-_dl_debug_printf.patch
|
||||
Patch158: backport-elf-Do-not-completely-clear-reused-namespace-in-dlmo.patch
|
||||
Patch159: io-Fix-use-after-free-in-ftw-BZ-26779.patch
|
||||
Patch160: backport-x86-Fix-wcsnlen-avx2-page-cross-length-comparison-BZ.patch
|
||||
|
||||
Patch9000: turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch
|
||||
Patch9001: delete-no-hard-link-to-avoid-all_language-package-to.patch
|
||||
@ -1425,6 +1426,9 @@ fi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Fri Dec 16 2022 lijianglin <lijianglin2@huawei.com> - 2.34-104
|
||||
- x86: Fix wcsnlen-avx2 page cross length comparison(BZ #29591)
|
||||
|
||||
* Mon Dec 12 2022 Qingqing Li <liqingqing3@huawei.com> - 2.34-103
|
||||
- io: Fix use after free in ftw (BZ 26779)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user