diff options
author | Marius Bakke <mbakke@fastmail.com> | 2018-06-11 23:52:15 +0200 |
---|---|---|
committer | Marius Bakke <mbakke@fastmail.com> | 2018-06-11 23:52:15 +0200 |
commit | a032b4454b3fc67e11e9fc2d8c2345288065fa29 (patch) | |
tree | c208124b79dbd2224b68c52106aa72ff2ebfa7ab /gnu/packages/patches/glibc-2.27-git-fixes.patch | |
parent | b5724230fed2d043206df20d12a45bb962b7ee77 (diff) | |
parent | 6321ce42ab4d9ab788d858cb19bde4aa7a0e3ecc (diff) | |
download | guix-a032b4454b3fc67e11e9fc2d8c2345288065fa29.tar.gz |
Merge branch 'master' into staging
Diffstat (limited to 'gnu/packages/patches/glibc-2.27-git-fixes.patch')
-rw-r--r-- | gnu/packages/patches/glibc-2.27-git-fixes.patch | 702 |
1 files changed, 702 insertions, 0 deletions
diff --git a/gnu/packages/patches/glibc-2.27-git-fixes.patch b/gnu/packages/patches/glibc-2.27-git-fixes.patch new file mode 100644 index 0000000000..4ed67c7c25 --- /dev/null +++ b/gnu/packages/patches/glibc-2.27-git-fixes.patch @@ -0,0 +1,702 @@ +These commits are cherry-picked from the "release/2.27/master" branch. + +https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/release/2.27/master + +Currently, we have the following (with NEWS and ChangeLog entries omitted). + +56170e064e2b21ce204f0817733e92f1730541ea +516fa6080481a1433c173320b1c1432868e1e38a +f36553bf6a4f69070f99badbdab5802b43e6e211 +7c6304182b9f422b782ace1cdd3efbde056aec36 +78a90c2f74a2012dd3eff302189e47ff6779a757 +1e52d8e65a58c49a48549053a1b89c06240e0c6c +55ad82e45c313454de657931898e974a7a036cad + +From 56170e064e2b21ce204f0817733e92f1730541ea Mon Sep 17 00:00:00 2001 +From: Igor Gnatenko <ignatenko@redhat.com> +Date: Wed, 7 Feb 2018 13:53:10 +0100 +Subject: [PATCH] Linux: use reserved name __key in pkey_get [BZ #22797] + +_key is not reserved name and we should avoid using that. It seems that +it was simple typo when pkey_* was implemented. + +(cherry picked from commit 388ff7bd0d57d7061fdd39a2f26f65687e8058da) + +diff --git a/sysdeps/unix/sysv/linux/bits/mman-shared.h b/sysdeps/unix/sysv/linux/bits/mman-shared.h +index 7715e680ca..d15ba95c9d 100644 +--- a/sysdeps/unix/sysv/linux/bits/mman-shared.h ++++ b/sysdeps/unix/sysv/linux/bits/mman-shared.h +@@ -61,7 +61,7 @@ int pkey_set (int __key, unsigned int __access_rights) __THROW; + + /* Return the access rights for the current thread for KEY, which must + have been allocated using pkey_alloc. */ +-int pkey_get (int _key) __THROW; ++int pkey_get (int __key) __THROW; + + /* Free an allocated protection key, which must have been allocated + using pkey_alloc. */ + +From 516fa6080481a1433c173320b1c1432868e1e38a Mon Sep 17 00:00:00 2001 +From: "Dmitry V. Levin" <ldv@altlinux.org> +Date: Fri, 29 Dec 2017 23:19:32 +0000 +Subject: [PATCH] linux/aarch64: sync sys/ptrace.h with Linux 4.15 [BZ #22433] + +Remove compat-specific constants that were never exported by kernel +headers under these names. Before linux commit v3.7-rc1~16^2~1 they +were exported with COMPAT_ prefix, and since that commit they are not +exported at all. + +* sysdeps/unix/sysv/linux/aarch64/sys/ptrace.h (__ptrace_request): +Remove arm-specific PTRACE_GET_THREAD_AREA, PTRACE_GETHBPREGS, +and PTRACE_SETHBPREGS. + +(cherry picked from commit 2fd4bbaa1446f1be700e10c526cf585a796c4991) + +diff --git a/sysdeps/unix/sysv/linux/aarch64/sys/ptrace.h b/sysdeps/unix/sysv/linux/aarch64/sys/ptrace.h +index 4be45b95ff..444edbb702 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/sys/ptrace.h ++++ b/sysdeps/unix/sysv/linux/aarch64/sys/ptrace.h +@@ -78,18 +78,10 @@ enum __ptrace_request + PTRACE_DETACH = 17, + #define PT_DETACH PTRACE_DETACH + +- PTRACE_GET_THREAD_AREA = 22, +- + /* Continue and stop at the next entry to or return from syscall. */ + PTRACE_SYSCALL = 24, + #define PT_SYSCALL PTRACE_SYSCALL + +- /* Get all hardware breakpoint registers. */ +- PTRACE_GETHBPREGS = 29, +- +- /* Set all hardware breakpoint registers. */ +- PTRACE_SETHBPREGS = 30, +- + /* Set ptrace filter options. */ + PTRACE_SETOPTIONS = 0x4200, + #define PT_SETOPTIONS PTRACE_SETOPTIONS + +From f36553bf6a4f69070f99badbdab5802b43e6e211 Mon Sep 17 00:00:00 2001 +From: Mike FABIAN <mfabian@redhat.com> +Date: Mon, 19 Feb 2018 21:59:30 +0100 +Subject: [PATCH] =?UTF-8?q?Add=20missing=20=E2=80=9Creorder-end=E2=80=9D?= + =?UTF-8?q?=20in=20LC=5FCOLLATE=20of=20et=5FEE=20[BZ=20#22517]?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + + [BZ #22517] + * localedata/locales/et_EE (LC_COLLATE): add missing “reorder-end” + +(cherry picked from commit 7ec5f9465e732e668d0dc94ac078ba68056d6d0a) + +diff --git a/localedata/locales/et_EE b/localedata/locales/et_EE +index 9cb55b568f..bab7493c98 100644 +--- a/localedata/locales/et_EE ++++ b/localedata/locales/et_EE +@@ -103,6 +103,8 @@ reorder-after <w> + <U00FC> <u-diaresis>;<BAS>;<MIN>;IGNORE % ü + <U00DC> <u-diaresis>;<BAS>;<CAP>;IGNORE % Ü + ++reorder-end ++ + END LC_COLLATE + + LC_CTYPE + +From 7c6304182b9f422b782ace1cdd3efbde056aec36 Mon Sep 17 00:00:00 2001 +From: DJ Delorie <dj@redhat.com> +Date: Thu, 1 Mar 2018 23:20:45 -0500 +Subject: [PATCH] [BZ #22342] Fix netgroup cache keys. + +Unlike other nscd caches, the netgroup cache contains two types of +records - those for "iterate through a netgroup" (i.e. setnetgrent()) +and those for "is this user in this netgroup" (i.e. innetgr()), +i.e. full and partial records. The timeout code assumes these records +have the same key for the group name, so that the collection of records +that is "this netgroup" can be expired as a unit. + +However, the keys are not the same, as the in-netgroup key is generated +by nscd rather than being passed to it from elsewhere, and is generated +without the trailing NUL. All other keys have the trailing NUL, and as +noted in the linked BZ, debug statements confirm that two keys for the +same netgroup are added to the cache with two different lengths. + +The result of this is that as records in the cache expire, the purge +code only cleans out one of the two types of entries, resulting in +stale, possibly incorrect, and possibly inconsistent cache data. + +The patch simply includes the existing NUL in the computation for the +key length ('key' points to the char after the NUL, and 'group' to the +first char of the group, so 'key-group' includes the first char to the +NUL, inclusive). + + [BZ #22342] + * nscd/netgroupcache.c (addinnetgrX): Include trailing NUL in + key value. + +Reviewed-by: Carlos O'Donell <carlos@redhat.com> +(cherry picked from commit 1c81d55fc4b07b51adf68558ba74ce975153e580) + +diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c +index b832c9315f..2f187b208c 100644 +--- a/nscd/netgroupcache.c ++++ b/nscd/netgroupcache.c +@@ -480,7 +480,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, + { + const char *group = key; + key = (char *) rawmemchr (key, '\0') + 1; +- size_t group_len = key - group - 1; ++ size_t group_len = key - group; + const char *host = *key++ ? key : NULL; + if (host != NULL) + key = (char *) rawmemchr (key, '\0') + 1; + +From 78a90c2f74a2012dd3eff302189e47ff6779a757 Mon Sep 17 00:00:00 2001 +From: Andreas Schwab <schwab@linux-m68k.org> +Date: Fri, 2 Mar 2018 23:07:14 +0100 +Subject: [PATCH] Fix multiple definitions of __nss_*_database (bug 22918) + +(cherry picked from commit eaf6753f8aac33a36deb98c1031d1bad7b593d2d) + +diff --git a/nscd/gai.c b/nscd/gai.c +index d081747797..576fd0045b 100644 +--- a/nscd/gai.c ++++ b/nscd/gai.c +@@ -45,3 +45,6 @@ + #ifdef HAVE_LIBIDN + # include <libidn/idn-stub.c> + #endif ++ ++/* Some variables normally defined in libc. */ ++service_user *__nss_hosts_database attribute_hidden; +diff --git a/nss/nsswitch.c b/nss/nsswitch.c +index d5e655974f..b0f0c11a3e 100644 +--- a/nss/nsswitch.c ++++ b/nss/nsswitch.c +@@ -62,7 +62,7 @@ static service_library *nss_new_service (name_database *database, + + /* Declare external database variables. */ + #define DEFINE_DATABASE(name) \ +- extern service_user *__nss_##name##_database attribute_hidden; \ ++ service_user *__nss_##name##_database attribute_hidden; \ + weak_extern (__nss_##name##_database) + #include "databases.def" + #undef DEFINE_DATABASE +diff --git a/nss/nsswitch.h b/nss/nsswitch.h +index eccb535ef5..63573b9ebc 100644 +--- a/nss/nsswitch.h ++++ b/nss/nsswitch.h +@@ -226,10 +226,10 @@ libc_hidden_proto (__nss_hostname_digits_dots) + #define MAX_NR_ADDRS 48 + + /* Prototypes for __nss_*_lookup2 functions. */ +-#define DEFINE_DATABASE(arg) \ +- service_user *__nss_##arg##_database attribute_hidden; \ +- int __nss_##arg##_lookup2 (service_user **, const char *, \ +- const char *, void **); \ ++#define DEFINE_DATABASE(arg) \ ++ extern service_user *__nss_##arg##_database attribute_hidden; \ ++ int __nss_##arg##_lookup2 (service_user **, const char *, \ ++ const char *, void **); \ + libc_hidden_proto (__nss_##arg##_lookup2) + #include "databases.def" + #undef DEFINE_DATABASE +diff --git a/posix/tst-rfc3484-2.c b/posix/tst-rfc3484-2.c +index f509534ca9..8c64ac59ff 100644 +--- a/posix/tst-rfc3484-2.c ++++ b/posix/tst-rfc3484-2.c +@@ -58,6 +58,7 @@ _res_hconf_init (void) + #undef USE_NSCD + #include "../sysdeps/posix/getaddrinfo.c" + ++service_user *__nss_hosts_database attribute_hidden; + + /* This is the beginning of the real test code. The above defines + (among other things) the function rfc3484_sort. */ +diff --git a/posix/tst-rfc3484-3.c b/posix/tst-rfc3484-3.c +index ae44087a10..1c61aaf844 100644 +--- a/posix/tst-rfc3484-3.c ++++ b/posix/tst-rfc3484-3.c +@@ -58,6 +58,7 @@ _res_hconf_init (void) + #undef USE_NSCD + #include "../sysdeps/posix/getaddrinfo.c" + ++service_user *__nss_hosts_database attribute_hidden; + + /* This is the beginning of the real test code. The above defines + (among other things) the function rfc3484_sort. */ +diff --git a/posix/tst-rfc3484.c b/posix/tst-rfc3484.c +index 7f191abbbc..8f45848e44 100644 +--- a/posix/tst-rfc3484.c ++++ b/posix/tst-rfc3484.c +@@ -58,6 +58,7 @@ _res_hconf_init (void) + #undef USE_NSCD + #include "../sysdeps/posix/getaddrinfo.c" + ++service_user *__nss_hosts_database attribute_hidden; + + /* This is the beginning of the real test code. The above defines + (among other things) the function rfc3484_sort. */ + +From 1e52d8e65a58c49a48549053a1b89c06240e0c6c Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella <adhemerval.zanella@linaro.org> +Date: Fri, 17 Nov 2017 16:04:29 -0200 +Subject: [PATCH] i386: Fix i386 sigaction sa_restorer initialization + (BZ#21269) + +This patch fixes the i386 sa_restorer field initialization for sigaction +syscall for kernel with vDSO. As described in bug report, i386 Linux +(and compat on x86_64) interprets SA_RESTORER clear with nonzero +sa_restorer as a request for stack switching if the SS segment is 'funny'. +This means that anything that tries to mix glibc's signal handling with +segmentation (for instance through modify_ldt syscall) is randomly broken +depending on what values lands in sa_restorer. + +The testcase added is based on Linux test tools/testing/selftests/x86/ldt_gdt.c, +more specifically in do_multicpu_tests function. The main changes are: + + - C11 atomics instead of plain access. + + - Remove x86_64 support which simplifies the syscall handling and fallbacks. + + - Replicate only the test required to trigger the issue. + +Checked on i686-linux-gnu. + + [BZ #21269] + * sysdeps/unix/sysv/linux/i386/Makefile (tests): Add tst-bz21269. + * sysdeps/unix/sysv/linux/i386/sigaction.c (SET_SA_RESTORER): Clear + sa_restorer for vDSO case. + * sysdeps/unix/sysv/linux/i386/tst-bz21269.c: New file. + +(cherry picked from commit 68448be208ee06e76665918b37b0a57e3e00c8b4) + +diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile +index 4080b8c966..da716e2c1b 100644 +--- a/sysdeps/unix/sysv/linux/i386/Makefile ++++ b/sysdeps/unix/sysv/linux/i386/Makefile +@@ -3,6 +3,9 @@ default-abi := 32 + + ifeq ($(subdir),misc) + sysdep_routines += ioperm iopl vm86 ++ ++tests += tst-bz21269 ++$(objpfx)tst-bz21269: $(shared-thread-library) + endif + + ifeq ($(subdir),elf) +diff --git a/sysdeps/unix/sysv/linux/i386/sigaction.c b/sysdeps/unix/sysv/linux/i386/sigaction.c +index a5eb9e0d3e..177ff60ee6 100644 +--- a/sysdeps/unix/sysv/linux/i386/sigaction.c ++++ b/sysdeps/unix/sysv/linux/i386/sigaction.c +@@ -42,7 +42,6 @@ extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; + #endif + extern void restore (void) asm ("__restore") attribute_hidden; + +- + /* If ACT is not NULL, change the action for SIG to *ACT. + If OACT is not NULL, put the old action for SIG in *OACT. */ + int +@@ -65,6 +64,8 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) + kact.sa_restorer = ((act->sa_flags & SA_SIGINFO) + ? &restore_rt : &restore); + } ++ else ++ kact.sa_restorer = NULL; + } + + /* XXX The size argument hopefully will have to be changed to the +diff --git a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c +new file mode 100644 +index 0000000000..353e36507d +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c +@@ -0,0 +1,233 @@ ++/* Test for i386 sigaction sa_restorer handling (BZ#21269) ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++/* This is based on Linux test tools/testing/selftests/x86/ldt_gdt.c, ++ more specifically in do_multicpu_tests function. The main changes ++ are: ++ ++ - C11 atomics instead of plain access. ++ - Remove x86_64 support which simplifies the syscall handling ++ and fallbacks. ++ - Replicate only the test required to trigger the issue for the ++ BZ#21269. */ ++ ++#include <stdatomic.h> ++ ++#include <asm/ldt.h> ++#include <linux/futex.h> ++ ++#include <setjmp.h> ++#include <signal.h> ++#include <errno.h> ++#include <sys/syscall.h> ++#include <sys/mman.h> ++ ++#include <support/xunistd.h> ++#include <support/check.h> ++#include <support/xthread.h> ++ ++static int ++xset_thread_area (struct user_desc *u_info) ++{ ++ long ret = syscall (SYS_set_thread_area, u_info); ++ TEST_VERIFY_EXIT (ret == 0); ++ return ret; ++} ++ ++static void ++xmodify_ldt (int func, const void *ptr, unsigned long bytecount) ++{ ++ TEST_VERIFY_EXIT (syscall (SYS_modify_ldt, 1, ptr, bytecount) == 0); ++} ++ ++static int ++futex (int *uaddr, int futex_op, int val, void *timeout, int *uaddr2, ++ int val3) ++{ ++ return syscall (SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3); ++} ++ ++static void ++xsethandler (int sig, void (*handler)(int, siginfo_t *, void *), int flags) ++{ ++ struct sigaction sa = { 0 }; ++ sa.sa_sigaction = handler; ++ sa.sa_flags = SA_SIGINFO | flags; ++ TEST_VERIFY_EXIT (sigemptyset (&sa.sa_mask) == 0); ++ TEST_VERIFY_EXIT (sigaction (sig, &sa, 0) == 0); ++} ++ ++static jmp_buf jmpbuf; ++ ++static void ++sigsegv_handler (int sig, siginfo_t *info, void *ctx_void) ++{ ++ siglongjmp (jmpbuf, 1); ++} ++ ++/* Points to an array of 1024 ints, each holding its own index. */ ++static const unsigned int *counter_page; ++static struct user_desc *low_user_desc; ++static struct user_desc *low_user_desc_clear; /* Used to delete GDT entry. */ ++static int gdt_entry_num; ++ ++static void ++setup_counter_page (void) ++{ ++ long page_size = sysconf (_SC_PAGE_SIZE); ++ TEST_VERIFY_EXIT (page_size > 0); ++ unsigned int *page = xmmap (NULL, page_size, PROT_READ | PROT_WRITE, ++ MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT, -1); ++ for (int i = 0; i < (page_size / sizeof (unsigned int)); i++) ++ page[i] = i; ++ counter_page = page; ++} ++ ++static void ++setup_low_user_desc (void) ++{ ++ low_user_desc = xmmap (NULL, 2 * sizeof (struct user_desc), ++ PROT_READ | PROT_WRITE, ++ MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT, -1); ++ ++ low_user_desc->entry_number = -1; ++ low_user_desc->base_addr = (unsigned long) &counter_page[1]; ++ low_user_desc->limit = 0xffff; ++ low_user_desc->seg_32bit = 1; ++ low_user_desc->contents = 0; ++ low_user_desc->read_exec_only = 0; ++ low_user_desc->limit_in_pages = 1; ++ low_user_desc->seg_not_present = 0; ++ low_user_desc->useable = 0; ++ ++ xset_thread_area (low_user_desc); ++ ++ low_user_desc_clear = low_user_desc + 1; ++ low_user_desc_clear->entry_number = gdt_entry_num; ++ low_user_desc_clear->read_exec_only = 1; ++ low_user_desc_clear->seg_not_present = 1; ++} ++ ++/* Possible values of futex: ++ 0: thread is idle. ++ 1: thread armed. ++ 2: thread should clear LDT entry 0. ++ 3: thread should exit. */ ++static atomic_uint ftx; ++ ++static void * ++threadproc (void *ctx) ++{ ++ while (1) ++ { ++ futex ((int *) &ftx, FUTEX_WAIT, 1, NULL, NULL, 0); ++ while (atomic_load (&ftx) != 2) ++ { ++ if (atomic_load (&ftx) >= 3) ++ return NULL; ++ } ++ ++ /* clear LDT entry 0. */ ++ const struct user_desc desc = { 0 }; ++ xmodify_ldt (1, &desc, sizeof (desc)); ++ ++ /* If ftx == 2, set it to zero, If ftx == 100, quit. */ ++ if (atomic_fetch_add (&ftx, -2) != 2) ++ return NULL; ++ } ++} ++ ++ ++/* As described in testcase, for historical reasons x86_32 Linux (and compat ++ on x86_64) interprets SA_RESTORER clear with nonzero sa_restorer as a ++ request for stack switching if the SS segment is 'funny' (this is default ++ scenario for vDSO system). This means that anything that tries to mix ++ signal handling with segmentation should explicit clear the sa_restorer. ++ ++ This testcase check if sigaction in fact does it by changing the local ++ descriptor table (LDT) through the modify_ldt syscall and triggering ++ a synchronous segfault on iret fault by trying to install an invalid ++ segment. With a correct zeroed sa_restorer it should not trigger an ++ 'real' SEGSEGV and allows the siglongjmp in signal handler. */ ++ ++static int ++do_test (void) ++{ ++ setup_counter_page (); ++ setup_low_user_desc (); ++ ++ pthread_t thread; ++ unsigned short orig_ss; ++ ++ xsethandler (SIGSEGV, sigsegv_handler, 0); ++ /* 32-bit kernels send SIGILL instead of SIGSEGV on IRET faults. */ ++ xsethandler (SIGILL, sigsegv_handler, 0); ++ ++ thread = xpthread_create (0, threadproc, 0); ++ ++ asm volatile ("mov %%ss, %0" : "=rm" (orig_ss)); ++ ++ for (int i = 0; i < 5; i++) ++ { ++ if (sigsetjmp (jmpbuf, 1) != 0) ++ continue; ++ ++ /* Make sure the thread is ready after the last test. */ ++ while (atomic_load (&ftx) != 0) ++ ; ++ ++ struct user_desc desc = { ++ .entry_number = 0, ++ .base_addr = 0, ++ .limit = 0xffff, ++ .seg_32bit = 1, ++ .contents = 0, ++ .read_exec_only = 0, ++ .limit_in_pages = 1, ++ .seg_not_present = 0, ++ .useable = 0 ++ }; ++ ++ xmodify_ldt (0x11, &desc, sizeof (desc)); ++ ++ /* Arm the thread. */ ++ ftx = 1; ++ futex ((int*) &ftx, FUTEX_WAKE, 0, NULL, NULL, 0); ++ ++ asm volatile ("mov %0, %%ss" : : "r" (0x7)); ++ ++ /* Fire up thread modify_ldt call. */ ++ atomic_store (&ftx, 2); ++ ++ while (atomic_load (&ftx) != 0) ++ ; ++ ++ /* On success, modify_ldt will segfault us synchronously and we will ++ escape via siglongjmp. */ ++ support_record_failure (); ++ } ++ ++ atomic_store (&ftx, 100); ++ futex ((int*) &ftx, FUTEX_WAKE, 0, NULL, NULL, 0); ++ ++ xpthread_join (thread); ++ ++ return 0; ++} ++ ++#include <support/test-driver.c> + +From 55ad82e45c313454de657931898e974a7a036cad Mon Sep 17 00:00:00 2001 +From: Andrew Senkevich <andrew.n.senkevich@gmail.com> +Date: Fri, 23 Mar 2018 16:19:45 +0100 +Subject: [PATCH] Fix i386 memmove issue (bug 22644). + + [BZ #22644] + * sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S: Fixed + branch conditions. + * string/test-memmove.c (do_test2): New testcase. + +(cherry picked from commit cd66c0e584c6d692bc8347b5e72723d02b8a8ada) + +diff --git a/string/test-memmove.c b/string/test-memmove.c +index edc7a4c3bf..64e3651ba4 100644 +--- a/string/test-memmove.c ++++ b/string/test-memmove.c +@@ -24,6 +24,7 @@ + # define TEST_NAME "memmove" + #endif + #include "test-string.h" ++#include <support/test-driver.h> + + char *simple_memmove (char *, const char *, size_t); + +@@ -245,6 +246,60 @@ do_random_tests (void) + } + } + ++static void ++do_test2 (void) ++{ ++ size_t size = 0x20000000; ++ uint32_t * large_buf; ++ ++ large_buf = mmap ((void*) 0x70000000, size, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANON, -1, 0); ++ ++ if (large_buf == MAP_FAILED) ++ error (EXIT_UNSUPPORTED, errno, "Large mmap failed"); ++ ++ if ((uintptr_t) large_buf > 0x80000000 - 128 ++ || 0x80000000 - (uintptr_t) large_buf > 0x20000000) ++ { ++ error (0, 0, "Large mmap allocated improperly"); ++ ret = EXIT_UNSUPPORTED; ++ munmap ((void *) large_buf, size); ++ return; ++ } ++ ++ size_t bytes_move = 0x80000000 - (uintptr_t) large_buf; ++ size_t arr_size = bytes_move / sizeof (uint32_t); ++ size_t i; ++ ++ FOR_EACH_IMPL (impl, 0) ++ { ++ for (i = 0; i < arr_size; i++) ++ large_buf[i] = (uint32_t) i; ++ ++ uint32_t * dst = &large_buf[33]; ++ ++#ifdef TEST_BCOPY ++ CALL (impl, (char *) large_buf, (char *) dst, bytes_move); ++#else ++ CALL (impl, (char *) dst, (char *) large_buf, bytes_move); ++#endif ++ ++ for (i = 0; i < arr_size; i++) ++ { ++ if (dst[i] != (uint32_t) i) ++ { ++ error (0, 0, ++ "Wrong result in function %s dst \"%p\" src \"%p\" offset \"%zd\"", ++ impl->name, dst, large_buf, i); ++ ret = 1; ++ break; ++ } ++ } ++ } ++ ++ munmap ((void *) large_buf, size); ++} ++ + int + test_main (void) + { +@@ -284,6 +339,9 @@ test_main (void) + } + + do_random_tests (); ++ ++ do_test2 (); ++ + return ret; + } + +diff --git a/sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S b/sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S +index 9c3bbe7e17..9aa17de99c 100644 +--- a/sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S ++++ b/sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S +@@ -72,7 +72,7 @@ ENTRY (MEMCPY) + cmp %edx, %eax + + # ifdef USE_AS_MEMMOVE +- jg L(check_forward) ++ ja L(check_forward) + + L(mm_len_0_or_more_backward): + /* Now do checks for lengths. We do [0..16], [16..32], [32..64], [64..128] +@@ -81,7 +81,7 @@ L(mm_len_0_or_more_backward): + jbe L(mm_len_0_16_bytes_backward) + + cmpl $32, %ecx +- jg L(mm_len_32_or_more_backward) ++ ja L(mm_len_32_or_more_backward) + + /* Copy [0..32] and return. */ + movdqu (%eax), %xmm0 +@@ -92,7 +92,7 @@ L(mm_len_0_or_more_backward): + + L(mm_len_32_or_more_backward): + cmpl $64, %ecx +- jg L(mm_len_64_or_more_backward) ++ ja L(mm_len_64_or_more_backward) + + /* Copy [0..64] and return. */ + movdqu (%eax), %xmm0 +@@ -107,7 +107,7 @@ L(mm_len_32_or_more_backward): + + L(mm_len_64_or_more_backward): + cmpl $128, %ecx +- jg L(mm_len_128_or_more_backward) ++ ja L(mm_len_128_or_more_backward) + + /* Copy [0..128] and return. */ + movdqu (%eax), %xmm0 +@@ -132,7 +132,7 @@ L(mm_len_128_or_more_backward): + add %ecx, %eax + cmp %edx, %eax + movl SRC(%esp), %eax +- jle L(forward) ++ jbe L(forward) + PUSH (%esi) + PUSH (%edi) + PUSH (%ebx) +@@ -269,7 +269,7 @@ L(check_forward): + add %edx, %ecx + cmp %eax, %ecx + movl LEN(%esp), %ecx +- jle L(forward) ++ jbe L(forward) + + /* Now do checks for lengths. We do [0..16], [0..32], [0..64], [0..128] + separately. */ |