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
|
Name: glibc
|
||||||
Version: 2.34
|
Version: 2.34
|
||||||
Release: 103
|
Release: 104
|
||||||
Summary: The GNU libc libraries
|
Summary: The GNU libc libraries
|
||||||
License: %{all_license}
|
License: %{all_license}
|
||||||
URL: http://www.gnu.org/software/glibc/
|
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
|
Patch157: backport-elf-Remove-allocate-use-on-_dl_debug_printf.patch
|
||||||
Patch158: backport-elf-Do-not-completely-clear-reused-namespace-in-dlmo.patch
|
Patch158: backport-elf-Do-not-completely-clear-reused-namespace-in-dlmo.patch
|
||||||
Patch159: io-Fix-use-after-free-in-ftw-BZ-26779.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
|
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
|
Patch9001: delete-no-hard-link-to-avoid-all_language-package-to.patch
|
||||||
@ -1425,6 +1426,9 @@ fi
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%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
|
* Mon Dec 12 2022 Qingqing Li <liqingqing3@huawei.com> - 2.34-103
|
||||||
- io: Fix use after free in ftw (BZ 26779)
|
- io: Fix use after free in ftw (BZ 26779)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user