702 lines
		
	
	
	
		
			22 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			702 lines
		
	
	
	
		
			22 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| 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.  */
 |