commit 7f11842e7483da7aa9fa3031be122021978ef600
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Wed Aug 8 01:55:04 2018 +0200

    hurd: Add missing symbols for proper libc_get/setspecific
    
            * htl/Versions (__pthread_getspecific, __pthread_setspecific): Add
            symbols.

diff --git a/ChangeLog b/ChangeLog
index 08b42bd2f5..31abb116a5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-08-08  Samuel Thibault  <samuel.thibault@ens-lyon.org>
+
+	* htl/Versions (__pthread_getspecific, __pthread_setspecific): Add
+	symbols.
+
 2018-08-01  Carlos O'Donel  <carlos@redhat.com>
 
 	* version.h (RELEASE): Set to "stable".
diff --git a/htl/Versions b/htl/Versions
index 6a63a1b8a1..c5a616da10 100644
--- a/htl/Versions
+++ b/htl/Versions
@@ -150,6 +150,8 @@ libpthread {
     __cthread_keycreate;
     __cthread_getspecific;
     __cthread_setspecific;
+    __pthread_getspecific;
+    __pthread_setspecific;
     __pthread_getattr_np;
     __pthread_attr_getstack;
   }

commit 726e1554ce4db5e35af41cb0110c54c5e1232054
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Thu Aug 9 01:26:19 2018 +0200

    hurd: Avoid PLTs for __pthread_get/setspecific
    
    * sysdeps/htl/pthreadP.h [IS_IN (libpthread)] (__pthread_getspecific,
    __pthread_setspecific): Add hidden proto.
    * sysdeps/htl/pt-getspecific.c (__pthread_getspecific): Add hidden def.
    * sysdeps/htl/pt-setspecific.c (__pthread_setspecific): Add hidden def.

diff --git a/ChangeLog b/ChangeLog
index 31abb116a5..dbcc56667b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,10 @@
 
 	* htl/Versions (__pthread_getspecific, __pthread_setspecific): Add
 	symbols.
+	* sysdeps/htl/pthreadP.h [IS_IN (libpthread)] (__pthread_getspecific,
+	__pthread_setspecific): Add hidden proto.
+	* sysdeps/htl/pt-getspecific.c (__pthread_getspecific): Add hidden def.
+	* sysdeps/htl/pt-setspecific.c (__pthread_setspecific): Add hidden def.
 
 2018-08-01  Carlos O'Donel  <carlos@redhat.com>
 
diff --git a/sysdeps/htl/pt-getspecific.c b/sysdeps/htl/pt-getspecific.c
index a0227a67f6..64ddf9551a 100644
--- a/sysdeps/htl/pt-getspecific.c
+++ b/sysdeps/htl/pt-getspecific.c
@@ -36,3 +36,4 @@ __pthread_getspecific (pthread_key_t key)
   return self->thread_specifics[key];
 }
 strong_alias (__pthread_getspecific, pthread_getspecific);
+hidden_def (__pthread_getspecific)
diff --git a/sysdeps/htl/pt-setspecific.c b/sysdeps/htl/pt-setspecific.c
index a46a12f157..02aff417ef 100644
--- a/sysdeps/htl/pt-setspecific.c
+++ b/sysdeps/htl/pt-setspecific.c
@@ -48,3 +48,4 @@ __pthread_setspecific (pthread_key_t key, const void *value)
   return 0;
 }
 strong_alias (__pthread_setspecific, pthread_setspecific);
+hidden_def (__pthread_setspecific)
diff --git a/sysdeps/htl/pthreadP.h b/sysdeps/htl/pthreadP.h
index 132ac1718e..71c2fcd9c6 100644
--- a/sysdeps/htl/pthreadP.h
+++ b/sysdeps/htl/pthreadP.h
@@ -68,6 +68,8 @@ struct __pthread_cancelation_handler **___pthread_get_cleanup_stack (void) attri
 
 #if IS_IN (libpthread)
 hidden_proto (__pthread_key_create)
+hidden_proto (__pthread_getspecific)
+hidden_proto (__pthread_setspecific)
 hidden_proto (_pthread_mutex_init)
 #endif
 

commit 4b25485f03158959cff45379eecc1d73c7dcdd11
Author: Florian Weimer <fweimer@redhat.com>
Date:   Fri Aug 10 11:19:26 2018 +0200

    Linux: Rewrite __old_getdents64 [BZ #23497]
    
    Commit 298d0e3129c0b5137f4989275b13fe30d0733c4d ("Consolidate Linux
    getdents{64} implementation") broke the implementation because it does
    not take into account struct offset differences.
    
    The new implementation is close to the old one, before the
    consolidation, but has been cleaned up slightly.
    
    (cherry picked from commit 690652882b499defb3d950dfeff8fe421d13cab5)

diff --git a/ChangeLog b/ChangeLog
index dbcc56667b..f32ed3e74c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2018-08-10  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #23497]
+	* sysdeps/unix/sysv/linux/getdents64.c (handle_overflow): New
+	function.
+	(__old_getdents64): Use getdents64.  Convert entries without
+	moving them.
+	* sysdeps/unix/sysv/linux/tst-readdir64-compat.c: New file.
+	* sysdeps/unix/sysv/linux/Makefile (tests-internal): Add
+	tst-readdir64-compat.
+
 2018-08-08  Samuel Thibault  <samuel.thibault@ens-lyon.org>
 
 	* htl/Versions (__pthread_getspecific, __pthread_setspecific): Add
diff --git a/NEWS b/NEWS
index 154ab22d7c..b733755ff6 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,13 @@ See the end for copying conditions.
 Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
 using `glibc' in the "product" field.
 
+Version 2.28.1
+
+The following bugs are resolved with this release:
+
+  [23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
+
+
 Version 2.28
 
 Major new features:
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index f71cc39c7e..773aaea0e9 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -161,6 +161,7 @@ inhibit-glue = yes
 
 ifeq ($(subdir),dirent)
 sysdep_routines += getdirentries getdirentries64
+tests-internal += tst-readdir64-compat
 endif
 
 ifeq ($(subdir),nis)
diff --git a/sysdeps/unix/sysv/linux/getdents64.c b/sysdeps/unix/sysv/linux/getdents64.c
index 3bde0cf4f0..bc140b5a7f 100644
--- a/sysdeps/unix/sysv/linux/getdents64.c
+++ b/sysdeps/unix/sysv/linux/getdents64.c
@@ -33,41 +33,80 @@ strong_alias (__getdents64, __getdents)
 # include <shlib-compat.h>
 
 # if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
-# include <olddirent.h>
+#  include <olddirent.h>
+#  include <unistd.h>
 
-/* kernel definition of as of 3.2.  */
-struct compat_linux_dirent
+static ssize_t
+handle_overflow (int fd, __off64_t offset, ssize_t count)
 {
-  /* Both d_ino and d_off are compat_ulong_t which are defined in all
-     architectures as 'u32'.  */
-  uint32_t        d_ino;
-  uint32_t        d_off;
-  unsigned short  d_reclen;
-  char            d_name[1];
-};
+  /* If this is the first entry in the buffer, we can report the
+     error.  */
+  if (count == 0)
+    {
+      __set_errno (EOVERFLOW);
+      return -1;
+    }
+
+  /* Otherwise, seek to the overflowing entry, so that the next call
+     will report the error, and return the data read so far..  */
+  if (__lseek64 (fd, offset, SEEK_SET) != 0)
+    return -1;
+  return count;
+}
 
 ssize_t
 __old_getdents64 (int fd, char *buf, size_t nbytes)
 {
-  ssize_t retval = INLINE_SYSCALL_CALL (getdents, fd, buf, nbytes);
+  /* We do not move the individual directory entries.  This is only
+     possible if the target type (struct __old_dirent64) is smaller
+     than the source type.  */
+  _Static_assert (offsetof (struct __old_dirent64, d_name)
+		  <= offsetof (struct dirent64, d_name),
+		  "__old_dirent64 is larger than dirent64");
+  _Static_assert (__alignof__ (struct __old_dirent64)
+		  <= __alignof__ (struct dirent64),
+		  "alignment of __old_dirent64 is larger than dirent64");
 
-  /* The kernel added the d_type value after the name.  Change this now.  */
-  if (retval != -1)
+  ssize_t retval = INLINE_SYSCALL_CALL (getdents64, fd, buf, nbytes);
+  if (retval > 0)
     {
-      union
-      {
-	struct compat_linux_dirent k;
-	struct dirent u;
-      } *kbuf = (void *) buf;
-
-      while ((char *) kbuf < buf + retval)
+      char *p = buf;
+      char *end = buf + retval;
+      while (p < end)
 	{
-	  char d_type = *((char *) kbuf + kbuf->k.d_reclen - 1);
-	  memmove (kbuf->u.d_name, kbuf->k.d_name,
-		   strlen (kbuf->k.d_name) + 1);
-	  kbuf->u.d_type = d_type;
+	  struct dirent64 *source = (struct dirent64 *) p;
+
+	  /* Copy out the fixed-size data.  */
+	  __ino_t ino = source->d_ino;
+	  __off64_t offset = source->d_off;
+	  unsigned int reclen = source->d_reclen;
+	  unsigned char type = source->d_type;
+
+	  /* Check for ino_t overflow.  */
+	  if (__glibc_unlikely (ino != source->d_ino))
+	    return handle_overflow (fd, offset, p - buf);
+
+	  /* Convert to the target layout.  Use a separate struct and
+	     memcpy to side-step aliasing issues.  */
+	  struct __old_dirent64 result;
+	  result.d_ino = ino;
+	  result.d_off = offset;
+	  result.d_reclen = reclen;
+	  result.d_type = type;
+
+	  /* Write the fixed-sized part of the result to the
+	     buffer.  */
+	  size_t result_name_offset = offsetof (struct __old_dirent64, d_name);
+	  memcpy (p, &result, result_name_offset);
+
+	  /* Adjust the position of the name if necessary.  Copy
+	     everything until the end of the record, including the
+	     terminating NUL byte.  */
+	  if (result_name_offset != offsetof (struct dirent64, d_name))
+	    memmove (p + result_name_offset, source->d_name,
+		     reclen - offsetof (struct dirent64, d_name));
 
-	  kbuf = (void *) ((char *) kbuf + kbuf->k.d_reclen);
+	  p += reclen;
 	}
      }
   return retval;
diff --git a/sysdeps/unix/sysv/linux/tst-readdir64-compat.c b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
new file mode 100644
index 0000000000..43c4a8477c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
@@ -0,0 +1,111 @@
+/* Test readdir64 compatibility symbol.
+   Copyright (C) 2018 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/>.  */
+
+#include <dirent.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <shlib-compat.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <support/check.h>
+
+/* Copied from <olddirent.h>.  */
+struct __old_dirent64
+  {
+    __ino_t d_ino;
+    __off64_t d_off;
+    unsigned short int d_reclen;
+    unsigned char d_type;
+    char d_name[256];
+  };
+
+typedef struct __old_dirent64 *(*compat_readdir64_type) (DIR *);
+
+#if TEST_COMPAT (libc, GLIBC_2_1, GLIBC_2_2)
+struct __old_dirent64 *compat_readdir64 (DIR *);
+compat_symbol_reference (libc, compat_readdir64, readdir64, GLIBC_2_1);
+#endif
+
+static int
+do_test (void)
+{
+#if TEST_COMPAT (libc, GLIBC_2_1, GLIBC_2_2)
+
+  /* Directory stream using the non-compat readdir64 symbol.  The test
+     checks against this.  */
+  DIR *dir_reference = opendir (".");
+  TEST_VERIFY_EXIT (dir_reference != NULL);
+  DIR *dir_test = opendir (".");
+  TEST_VERIFY_EXIT (dir_test != NULL);
+
+  /* This loop assumes that the enumeration order is consistent for
+     two different handles.  Nothing should write to the current
+     directory (in the source tree) while this test runs, so there
+     should not be any difference due to races.  */
+  size_t count = 0;
+  while (true)
+    {
+      errno = 0;
+      struct dirent64 *entry_reference = readdir64 (dir_reference);
+      if (entry_reference == NULL && errno != 0)
+        FAIL_EXIT1 ("readdir64 entry %zu: %m\n", count);
+      struct __old_dirent64 *entry_test = compat_readdir64 (dir_test);
+      if (entry_reference == NULL)
+        {
+          if (errno == EOVERFLOW)
+            {
+              TEST_VERIFY (entry_reference->d_ino
+                           != (__ino_t) entry_reference->d_ino);
+              printf ("info: inode number overflow at entry %zu\n", count);
+              break;
+            }
+          if (errno != 0)
+            FAIL_EXIT1 ("compat readdir64 entry %zu: %m\n", count);
+        }
+
+      /* Check that both streams end at the same time.  */
+      if (entry_reference == NULL)
+        {
+          TEST_VERIFY (entry_test == NULL);
+          break;
+        }
+      else
+        TEST_VERIFY_EXIT (entry_test != NULL);
+
+      /* Check that the entries are the same.  */
+      TEST_COMPARE_BLOB (entry_reference->d_name,
+                         strlen (entry_reference->d_name),
+                         entry_test->d_name, strlen (entry_test->d_name));
+      TEST_COMPARE (entry_reference->d_ino, entry_test->d_ino);
+      TEST_COMPARE (entry_reference->d_off, entry_test->d_off);
+      TEST_COMPARE (entry_reference->d_type, entry_test->d_type);
+      TEST_COMPARE (entry_reference->d_reclen, entry_test->d_reclen);
+
+      ++count;
+    }
+  printf ("info: %zu directory entries found\n", count);
+  TEST_VERIFY (count >= 3);     /* ".", "..", and some source files.  */
+
+  TEST_COMPARE (closedir (dir_test), 0);
+  TEST_COMPARE (closedir (dir_reference), 0);
+#endif
+  return 0;
+}
+
+#include <support/test-driver.c>

commit d05b05d1570ba3ae354a2f5a3cfeefb373b09979
Author: Florian Weimer <fweimer@redhat.com>
Date:   Mon Aug 13 14:28:07 2018 +0200

    error, error_at_line: Add missing va_end calls
    
    (cherry picked from commit b7b52b9dec337a08a89bc67638773be652eba332)

diff --git a/ChangeLog b/ChangeLog
index f32ed3e74c..cc918e96a3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-08-13  Florian Weimer  <fweimer@redhat.com>
+
+	* misc/error.c (error): Add missing va_end call.
+	(error_at_line): Likewise.
+
 2018-08-10  Florian Weimer  <fweimer@redhat.com>
 
 	[BZ #23497]
diff --git a/misc/error.c b/misc/error.c
index b4e8b6c938..03378e2f2a 100644
--- a/misc/error.c
+++ b/misc/error.c
@@ -319,6 +319,7 @@ error (int status, int errnum, const char *message, ...)
 
   va_start (args, message);
   error_tail (status, errnum, message, args);
+  va_end (args);
 
 #ifdef _LIBC
   _IO_funlockfile (stderr);
@@ -390,6 +391,7 @@ error_at_line (int status, int errnum, const char *file_name,
 
   va_start (args, message);
   error_tail (status, errnum, message, args);
+  va_end (args);
 
 #ifdef _LIBC
   _IO_funlockfile (stderr);

commit bfcfa22589f2b4277a65e60c6b736b6bbfbd87d0
Author: Florian Weimer <fweimer@redhat.com>
Date:   Tue Aug 14 10:51:07 2018 +0200

    nscd: Deallocate existing user names in file parser
    
    This avoids a theoretical memory leak (theoretical because it depends on
    multiple server-user/stat-user directives in the configuration file).
    
    (cherry picked from commit 2d7acfac3ebf266dcbc82d0d6cc576f626953a03)

diff --git a/ChangeLog b/ChangeLog
index cc918e96a3..0cbfb504f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-08-14  Florian Weimer  <fweimer@redhat.com>
+
+	* nscd/nscd_conf.c (nscd_parse_file): Deallocate old storage for
+	server_user, stat_user.
+
 2018-08-13  Florian Weimer  <fweimer@redhat.com>
 
 	* misc/error.c (error): Add missing va_end call.
diff --git a/nscd/nscd_conf.c b/nscd/nscd_conf.c
index 265a02434d..7293b795b6 100644
--- a/nscd/nscd_conf.c
+++ b/nscd/nscd_conf.c
@@ -190,7 +190,10 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
 	  if (!arg1)
 	    error (0, 0, _("Must specify user name for server-user option"));
 	  else
-	    server_user = xstrdup (arg1);
+	    {
+	      free ((char *) server_user);
+	      server_user = xstrdup (arg1);
+	    }
 	}
       else if (strcmp (entry, "stat-user") == 0)
 	{
@@ -198,6 +201,7 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
 	    error (0, 0, _("Must specify user name for stat-user option"));
 	  else
 	    {
+	      free ((char *) stat_user);
 	      stat_user = xstrdup (arg1);
 
 	      struct passwd *pw = getpwnam (stat_user);

commit 2f498f3d140ab5152bd784df2be7af7d9c5e63ed
Author: Florian Weimer <fweimer@redhat.com>
Date:   Tue Aug 14 10:57:48 2018 +0200

    nss_files: Fix file stream leak in aliases lookup [BZ #23521]
    
    In order to get a clean test case, it was necessary to fix partially
    fixed bug 23522 as well.
    
    (cherry picked from commit e95c6f61920a0f9237cfb292fa44ad500e1df09b)

diff --git a/ChangeLog b/ChangeLog
index 0cbfb504f4..d900e1eba1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2018-08-14  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #23521]
+	[BZ #23522]
+	* nss/nss_files/files-alias.c (get_next_alias): During :include:
+	processing, bail out if no room, and close the stream before
+	returning ERANGE.
+	* nss/Makefile (tests): Add tst-nss-files-alias-leak.
+	(tst-nss-files-alias-leak): Link with libdl.
+	(tst-nss-files-alias-leak.out): Depend on nss_files.
+
+	* nss/tst-nss-files-alias-leak.c: New file.
+
 2018-08-14  Florian Weimer  <fweimer@redhat.com>
 
 	* nscd/nscd_conf.c (nscd_parse_file): Deallocate old storage for
diff --git a/NEWS b/NEWS
index b733755ff6..873cf8f64f 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ Version 2.28.1
 The following bugs are resolved with this release:
 
   [23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
+  [23521] nss_files aliases database file stream leak
 
 
 Version 2.28
diff --git a/nss/Makefile b/nss/Makefile
index 66fac7f5b8..5209fc0456 100644
--- a/nss/Makefile
+++ b/nss/Makefile
@@ -65,6 +65,7 @@ ifeq (yes,$(build-shared))
 tests += tst-nss-files-hosts-erange
 tests += tst-nss-files-hosts-multi
 tests += tst-nss-files-hosts-getent
+tests += tst-nss-files-alias-leak
 endif
 
 # If we have a thread library then we can test cancellation against
@@ -171,3 +172,5 @@ endif
 $(objpfx)tst-nss-files-hosts-erange: $(libdl)
 $(objpfx)tst-nss-files-hosts-multi: $(libdl)
 $(objpfx)tst-nss-files-hosts-getent: $(libdl)
+$(objpfx)tst-nss-files-alias-leak: $(libdl)
+$(objpfx)tst-nss-files-alias-leak.out: $(objpfx)/libnss_files.so
diff --git a/nss/nss_files/files-alias.c b/nss/nss_files/files-alias.c
index cfd34b66b9..35b0bfc5d2 100644
--- a/nss/nss_files/files-alias.c
+++ b/nss/nss_files/files-alias.c
@@ -221,6 +221,13 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result,
 			{
 			  while (! feof_unlocked (listfile))
 			    {
+			      if (room_left < 2)
+				{
+				  free (old_line);
+				  fclose (listfile);
+				  goto no_more_room;
+				}
+
 			      first_unused[room_left - 1] = '\xff';
 			      line = fgets_unlocked (first_unused, room_left,
 						     listfile);
@@ -229,6 +236,7 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result,
 			      if (first_unused[room_left - 1] != '\xff')
 				{
 				  free (old_line);
+				  fclose (listfile);
 				  goto no_more_room;
 				}
 
@@ -256,6 +264,7 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result,
 						       + __alignof__ (char *)))
 					{
 					  free (old_line);
+					  fclose (listfile);
 					  goto no_more_room;
 					}
 				      room_left -= ((first_unused - cp)
diff --git a/nss/tst-nss-files-alias-leak.c b/nss/tst-nss-files-alias-leak.c
new file mode 100644
index 0000000000..26d38e2dba
--- /dev/null
+++ b/nss/tst-nss-files-alias-leak.c
@@ -0,0 +1,237 @@
+/* Check for file descriptor leak in alias :include: processing (bug 23521).
+   Copyright (C) 2018 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/>.  */
+
+#include <aliases.h>
+#include <array_length.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <gnu/lib-names.h>
+#include <nss.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/namespace.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+
+static struct support_chroot *chroot_env;
+
+/* Number of the aliases for the "many" user.  This must be large
+   enough to trigger reallocation for the pointer array, but result in
+   answers below the maximum size tried in do_test.  */
+enum { many_aliases = 30 };
+
+static void
+prepare (int argc, char **argv)
+{
+  chroot_env = support_chroot_create
+    ((struct support_chroot_configuration) { } );
+
+  char *path = xasprintf ("%s/etc/aliases", chroot_env->path_chroot);
+  add_temp_file (path);
+  support_write_file_string
+    (path,
+     "user1: :include:/etc/aliases.user1\n"
+     "user2: :include:/etc/aliases.user2\n"
+     "comment: comment1, :include:/etc/aliases.comment\n"
+     "many: :include:/etc/aliases.many\n");
+  free (path);
+
+  path = xasprintf ("%s/etc/aliases.user1", chroot_env->path_chroot);
+  add_temp_file (path);
+  support_write_file_string (path, "alias1\n");
+  free (path);
+
+  path = xasprintf ("%s/etc/aliases.user2", chroot_env->path_chroot);
+  add_temp_file (path);
+  support_write_file_string (path, "alias1a, alias2\n");
+  free (path);
+
+  path = xasprintf ("%s/etc/aliases.comment", chroot_env->path_chroot);
+  add_temp_file (path);
+  support_write_file_string
+    (path,
+     /* The line must be longer than the line with the :include:
+        directive in /etc/aliases.  */
+     "# Long line.  ##############################################\n"
+     "comment2\n");
+  free (path);
+
+  path = xasprintf ("%s/etc/aliases.many", chroot_env->path_chroot);
+  add_temp_file (path);
+  FILE *fp = xfopen (path, "w");
+  for (int i = 0; i < many_aliases; ++i)
+    fprintf (fp, "a%d\n", i);
+  TEST_VERIFY_EXIT (! ferror (fp));
+  xfclose (fp);
+  free (path);
+}
+
+/* The names of the users to test.  */
+static const char *users[] = { "user1", "user2", "comment", "many" };
+
+static void
+check_aliases (int id, const struct aliasent *e)
+{
+  TEST_VERIFY_EXIT (id >= 0 || id < array_length (users));
+  const char *name = users[id];
+  TEST_COMPARE_BLOB (e->alias_name, strlen (e->alias_name),
+                     name, strlen (name));
+
+  switch (id)
+    {
+    case 0:
+      TEST_COMPARE (e->alias_members_len, 1);
+      TEST_COMPARE_BLOB (e->alias_members[0], strlen (e->alias_members[0]),
+                         "alias1", strlen ("alias1"));
+      break;
+
+    case 1:
+      TEST_COMPARE (e->alias_members_len, 2);
+      TEST_COMPARE_BLOB (e->alias_members[0], strlen (e->alias_members[0]),
+                         "alias1a", strlen ("alias1a"));
+      TEST_COMPARE_BLOB (e->alias_members[1], strlen (e->alias_members[1]),
+                         "alias2", strlen ("alias2"));
+      break;
+
+    case 2:
+      TEST_COMPARE (e->alias_members_len, 2);
+      TEST_COMPARE_BLOB (e->alias_members[0], strlen (e->alias_members[0]),
+                         "comment1", strlen ("comment1"));
+      TEST_COMPARE_BLOB (e->alias_members[1], strlen (e->alias_members[1]),
+                         "comment2", strlen ("comment2"));
+      break;
+
+    case 3:
+      TEST_COMPARE (e->alias_members_len, many_aliases);
+      for (int i = 0; i < e->alias_members_len; ++i)
+        {
+          char alias[30];
+          int len = snprintf (alias, sizeof (alias), "a%d", i);
+          TEST_VERIFY_EXIT (len > 0);
+          TEST_COMPARE_BLOB (e->alias_members[i], strlen (e->alias_members[i]),
+                             alias, len);
+        }
+      break;
+    }
+}
+
+static int
+do_test (void)
+{
+  /* Make sure we don't try to load the module in the chroot.  */
+  if (dlopen (LIBNSS_FILES_SO, RTLD_NOW) == NULL)
+    FAIL_EXIT1 ("could not load " LIBNSS_FILES_SO ": %s", dlerror ());
+
+  /* Some of these descriptors will become unavailable if there is a
+     file descriptor leak.  10 is chosen somewhat arbitrarily.  The
+     array must be longer than the number of files opened by nss_files
+     at the same time (currently that number is 2).  */
+  int next_descriptors[10];
+  for (size_t i = 0; i < array_length (next_descriptors); ++i)
+    {
+      next_descriptors[i] = dup (0);
+      TEST_VERIFY_EXIT (next_descriptors[i] > 0);
+    }
+  for (size_t i = 0; i < array_length (next_descriptors); ++i)
+    xclose (next_descriptors[i]);
+
+  support_become_root ();
+  if (!support_can_chroot ())
+    return EXIT_UNSUPPORTED;
+
+  __nss_configure_lookup ("aliases", "files");
+
+  xchroot (chroot_env->path_chroot);
+
+  /* Attempt various buffer sizes.  If the operation succeeds, we
+     expect correct data.  */
+  for (int id = 0; id < array_length (users); ++id)
+    {
+      bool found = false;
+      for (size_t size = 1; size <= 1000; ++size)
+        {
+          void *buffer = malloc (size);
+          struct aliasent result;
+          struct aliasent *res;
+          errno = EINVAL;
+          int ret = getaliasbyname_r (users[id], &result, buffer, size, &res);
+          if (ret == 0)
+            {
+              if (res != NULL)
+                {
+                  found = true;
+                  check_aliases (id, res);
+                }
+              else
+                {
+                  support_record_failure ();
+                  printf ("error: failed lookup for user \"%s\", size %zu\n",
+                          users[id], size);
+                }
+            }
+          else if (ret != ERANGE)
+            {
+              support_record_failure ();
+              printf ("error: invalid return code %d (user \%s\", size %zu)\n",
+                      ret, users[id], size);
+            }
+          free (buffer);
+
+          /* Make sure that we did not have a file descriptor leak.  */
+          for (size_t i = 0; i < array_length (next_descriptors); ++i)
+            {
+              int new_fd = dup (0);
+              if (new_fd != next_descriptors[i])
+                {
+                  support_record_failure ();
+                  printf ("error: descriptor %d at index %zu leaked"
+                          " (user \"%s\", size %zu)\n",
+                          next_descriptors[i], i, users[id], size);
+
+                  /* Close unexpected descriptor, the leak probing
+                     descriptors, and the leaked descriptor
+                     next_descriptors[i].  */
+                  xclose (new_fd);
+                  for (size_t j = 0; j <= i; ++j)
+                    xclose (next_descriptors[j]);
+                  goto next_size;
+                }
+            }
+          for (size_t i = 0; i < array_length (next_descriptors); ++i)
+            xclose (next_descriptors[i]);
+
+        next_size:
+          ;
+        }
+      if (!found)
+        {
+          support_record_failure ();
+          printf ("error: user %s not found\n", users[id]);
+        }
+    }
+
+  support_chroot_free (chroot_env);
+  return 0;
+}
+
+#define PREPARE prepare
+#include <support/test-driver.c>

commit b0aa03dfffc20ec7a00db73a3dedecb2130ca6ab
Author: DJ Delorie <dj@redhat.com>
Date:   Fri Aug 3 13:43:31 2018 -0400

    RISC-V: Fix rounding save/restore bug.
    
    * sysdeps/riscv/rvf/math_private.h (libc_feholdexcept_setround_riscv):
    Fix rounding save-restore bug.
    
    Fixes about a hundred off-by-ULP failures in the math testsuite.
    
    (cherry picked from commit bf4181878780be9b53e37a3b0fbabc40cdd07649)

diff --git a/ChangeLog b/ChangeLog
index d900e1eba1..b1cba70bc4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-08-03  DJ Delorie  <dj@redhat.com>
+
+	* sysdeps/riscv/rvf/math_private.h (libc_feholdexcept_setround_riscv):
+	Fix rounding save-restore bug.
+
 2018-08-14  Florian Weimer  <fweimer@redhat.com>
 
 	[BZ #23521]
diff --git a/sysdeps/riscv/rvf/math_private.h b/sysdeps/riscv/rvf/math_private.h
index cdb7858fc8..ca587620cb 100644
--- a/sysdeps/riscv/rvf/math_private.h
+++ b/sysdeps/riscv/rvf/math_private.h
@@ -72,8 +72,8 @@ libc_fesetround_riscv (int round)
 static __always_inline void
 libc_feholdexcept_setround_riscv (fenv_t *envp, int round)
 {
-  libc_fesetround_riscv (round);
   libc_feholdexcept_riscv (envp);
+  libc_fesetround_riscv (round);
 }
 
 #define libc_feholdexcept_setround  libc_feholdexcept_setround_riscv

commit 66fdfd57fe20616dc3333b0eb4f5a411e85fd8aa
Author: DJ Delorie <dj@redhat.com>
Date:   Fri Aug 3 13:52:01 2018 -0400

    Regen RISC-V rvd ULPs
    
    * sysdeps/riscv/rv64/rvd/libm-test-ulps: Update.
    
    Note: I regen'd these from scratch, but I'm only committing the
    increases, as I only tested on hardware.  There were a few 2->1
    decreases that I omitted, possibly "for now".
    
    (cherry picked from commit bb17621ab89b2135c4d8d0d250b2aab5aa3e36c4)

diff --git a/ChangeLog b/ChangeLog
index b1cba70bc4..e296da9699 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,8 @@
 	* sysdeps/riscv/rvf/math_private.h (libc_feholdexcept_setround_riscv):
 	Fix rounding save-restore bug.
 
+	* sysdeps/riscv/rv64/rvd/libm-test-ulps: Update.
+
 2018-08-14  Florian Weimer  <fweimer@redhat.com>
 
 	[BZ #23521]
diff --git a/sysdeps/riscv/rv64/rvd/libm-test-ulps b/sysdeps/riscv/rv64/rvd/libm-test-ulps
index f8feadcd0d..61be2df60d 100644
--- a/sysdeps/riscv/rv64/rvd/libm-test-ulps
+++ b/sysdeps/riscv/rv64/rvd/libm-test-ulps
@@ -1006,6 +1006,8 @@ ildouble: 2
 ldouble: 2
 
 Function: "cos":
+double: 1
+idouble: 1
 ildouble: 1
 ldouble: 1
 
@@ -1348,9 +1350,9 @@ ildouble: 4
 ldouble: 4
 
 Function: Imaginary part of "ctan_towardzero":
-double: 1
+double: 2
 float: 2
-idouble: 1
+idouble: 2
 ifloat: 2
 ildouble: 5
 ldouble: 5
@@ -1898,10 +1900,12 @@ ldouble: 2
 Function: "log_upward":
 double: 1
 idouble: 1
-ildouble: 1
-ldouble: 1
+ildouble: 2
+ldouble: 2
 
 Function: "pow":
+double: 1
+idouble: 1
 ildouble: 2
 ldouble: 2
 
@@ -1930,6 +1934,8 @@ ildouble: 2
 ldouble: 2
 
 Function: "sin":
+double: 1
+idouble: 1
 ildouble: 1
 ldouble: 1
 
@@ -1952,6 +1958,8 @@ ildouble: 3
 ldouble: 3
 
 Function: "sincos":
+double: 1
+idouble: 1
 ildouble: 1
 ldouble: 1
 

commit c87b5bab241c8d1e7709061c6b63f1b435ee3ac9
Author: DJ Delorie <dj@delorie.com>
Date:   Wed Aug 22 18:54:51 2018 +0200

    Improve ChangeLog message.
    
    (cherry picked from commit e5721f45f6377c27ccb2572001dc98f7a2e6a146)

diff --git a/ChangeLog b/ChangeLog
index e296da9699..b9e732a192 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,7 @@
 2018-08-03  DJ Delorie  <dj@redhat.com>
 
 	* sysdeps/riscv/rvf/math_private.h (libc_feholdexcept_setround_riscv):
-	Fix rounding save-restore bug.
+	Move libc_fesetround_riscv after libc_feholdexcept_riscv.
 
 	* sysdeps/riscv/rv64/rvd/libm-test-ulps: Update.
 

commit aa8a3e4cdef20c50cb20f008864fff05cbfbdf29
Author: Martin Kuchta <martin.kuchta@netapp.com>
Date:   Mon Aug 27 18:54:46 2018 +0200

    pthread_cond_broadcast: Fix waiters-after-spinning case [BZ #23538]
    
    (cherry picked from commit 99ea93ca31795469d2a1f1570f17a5c39c2eb7e2)

diff --git a/ChangeLog b/ChangeLog
index b9e732a192..ef83777833 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2018-08-27 Martin Kuchta  <martin.kuchta@netapp.com>
+	   Torvald Riegel  <triegel@redhat.com>
+
+	[BZ #23538]
+	* nptl/pthread_cond_common.c (__condvar_quiesce_and_switch_g1):
+	Update r to include the set wake-request flag if waiters are
+	remaining after spinning.
+
 2018-08-03  DJ Delorie  <dj@redhat.com>
 
 	* sysdeps/riscv/rvf/math_private.h (libc_feholdexcept_setround_riscv):
diff --git a/NEWS b/NEWS
index 873cf8f64f..3073712cba 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ The following bugs are resolved with this release:
 
   [23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
   [23521] nss_files aliases database file stream leak
+  [23538] pthread_cond_broadcast: Fix waiters-after-spinning case
 
 
 Version 2.28
diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c
index 8e425eb01e..479e54febb 100644
--- a/nptl/pthread_cond_common.c
+++ b/nptl/pthread_cond_common.c
@@ -405,8 +405,12 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
 	{
 	  /* There is still a waiter after spinning.  Set the wake-request
 	     flag and block.  Relaxed MO is fine because this is just about
-	     this futex word.  */
-	  r = atomic_fetch_or_relaxed (cond->__data.__g_refs + g1, 1);
+	     this futex word.
+
+	     Update r to include the set wake-request flag so that the upcoming
+	     futex_wait only blocks if the flag is still set (otherwise, we'd
+	     violate the basic client-side futex protocol).  */
+	  r = atomic_fetch_or_relaxed (cond->__data.__g_refs + g1, 1) | 1;
 
 	  if ((r >> 1) > 0)
 	    futex_wait_simple (cond->__data.__g_refs + g1, r, private);

commit 58559f14437d2aa71753a29fed435efa06aa4576
Author: Paul Eggert <eggert@cs.ucla.edu>
Date:   Tue Aug 28 21:54:28 2018 +0200

    regex: fix uninitialized memory access
    
    I introduced this bug into gnulib in commit
    8335a4d6c7b4448cd0bcb6d0bebf1d456bcfdb17 dated 2006-04-10;
    eventually it was merged into glibc.  The bug was found by
    project-repo <bugs@feusi.co> and reported here:
    https://lists.gnu.org/r/sed-devel/2018-08/msg00017.html
    Diagnosis and draft fix reported by Assaf Gordon here:
    https://lists.gnu.org/r/bug-gnulib/2018-08/msg00071.html
    https://lists.gnu.org/r/bug-gnulib/2018-08/msg00142.html
    * posix/regex_internal.c (build_wcs_upper_buffer):
    Fix bug when mbrtowc returns 0.
    
    (cherry picked from commit bc680b336971305cb39896b30d72dc7101b62242)

diff --git a/ChangeLog b/ChangeLog
index ef83777833..8625e6c9f5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2018-08-25  Paul Eggert  <eggert@cs.ucla.edu>
+
+	[BZ #23578]
+	regex: fix uninitialized memory access
+	I introduced this bug into gnulib in commit
+	8335a4d6c7b4448cd0bcb6d0bebf1d456bcfdb17 dated 2006-04-10;
+	eventually it was merged into glibc.  The bug was found by
+	project-repo <bugs@feusi.co> and reported here:
+	https://lists.gnu.org/r/sed-devel/2018-08/msg00017.html
+	Diagnosis and draft fix reported by Assaf Gordon here:
+	https://lists.gnu.org/r/bug-gnulib/2018-08/msg00071.html
+	https://lists.gnu.org/r/bug-gnulib/2018-08/msg00142.html
+	* posix/regex_internal.c (build_wcs_upper_buffer):
+	Fix bug when mbrtowc returns 0.
+
 2018-08-27 Martin Kuchta  <martin.kuchta@netapp.com>
 	   Torvald Riegel  <triegel@redhat.com>
 
diff --git a/NEWS b/NEWS
index 3073712cba..2855ffde58 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,7 @@ The following bugs are resolved with this release:
   [23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
   [23521] nss_files aliases database file stream leak
   [23538] pthread_cond_broadcast: Fix waiters-after-spinning case
+  [23578] regex: Fix memory overread in re_compile_pattern
 
 
 Version 2.28
diff --git a/posix/regex_internal.c b/posix/regex_internal.c
index 7f0083b918..b10588f1cc 100644
--- a/posix/regex_internal.c
+++ b/posix/regex_internal.c
@@ -317,7 +317,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
 	  mbclen = __mbrtowc (&wc,
 			      ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
 			       + byte_idx), remain_len, &pstr->cur_state);
-	  if (BE (mbclen < (size_t) -2, 1))
+	  if (BE (0 < mbclen && mbclen < (size_t) -2, 1))
 	    {
 	      wchar_t wcu = __towupper (wc);
 	      if (wcu != wc)
@@ -386,7 +386,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
 	else
 	  p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx;
 	mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
-	if (BE (mbclen < (size_t) -2, 1))
+	if (BE (0 < mbclen && mbclen < (size_t) -2, 1))
 	  {
 	    wchar_t wcu = __towupper (wc);
 	    if (wcu != wc)

commit 0b79004569e5ce1669136b8c41564c3809730f15
Author: Florian Weimer <fweimer@redhat.com>
Date:   Tue Aug 28 12:57:46 2018 +0200

    regex: Add test tst-regcomp-truncated [BZ #23578]
    
    (cherry picked from commit 761404b74d9853ce1608195e24f25b78a910591a)

diff --git a/ChangeLog b/ChangeLog
index 8625e6c9f5..94b8718365 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2018-08-28  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #23578]
+	* posix/tst-regcomp-truncated.c: New file.
+	* posix/Makefile (tests): Add it.
+	(tst-regcomp-truncated.out): Depend on generated locales.
+
 2018-08-25  Paul Eggert  <eggert@cs.ucla.edu>
 
 	[BZ #23578]
diff --git a/posix/Makefile b/posix/Makefile
index 00c62841a2..83162123f9 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -96,7 +96,7 @@ tests		:= test-errno tstgetopt testfnm runtests runptests \
 		   tst-posix_fadvise tst-posix_fadvise64 \
 		   tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \
 		   tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \
-		   bug-regex38
+		   bug-regex38 tst-regcomp-truncated
 tests-internal	:= bug-regex5 bug-regex20 bug-regex33 \
 		   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 \
 		   tst-glob_lstat_compat tst-spawn4-compat
@@ -194,6 +194,7 @@ $(objpfx)tst-regex2.out: $(gen-locales)
 $(objpfx)tst-regexloc.out: $(gen-locales)
 $(objpfx)tst-rxspencer.out: $(gen-locales)
 $(objpfx)tst-rxspencer-no-utf8.out: $(gen-locales)
+$(objpfx)tst-regcomp-truncated.out: $(gen-locales)
 endif
 
 # If we will use the generic uname implementation, we must figure out what
diff --git a/posix/tst-regcomp-truncated.c b/posix/tst-regcomp-truncated.c
new file mode 100644
index 0000000000..a4a1581bbc
--- /dev/null
+++ b/posix/tst-regcomp-truncated.c
@@ -0,0 +1,191 @@
+/* Test compilation of truncated regular expressions.
+   Copyright (C) 2018 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 test constructs various patterns in an attempt to trigger
+   over-reading the regular expression compiler, such as bug
+   23578.  */
+
+#include <array_length.h>
+#include <errno.h>
+#include <locale.h>
+#include <regex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/next_to_fault.h>
+#include <support/support.h>
+#include <support/test-driver.h>
+#include <wchar.h>
+
+/* Locales to test.  */
+static const char locales[][17] =
+  {
+    "C",
+    "en_US.UTF-8",
+    "de_DE.ISO-8859-1",
+  };
+
+/* Syntax options.  Will be combined with other flags.  */
+static const reg_syntax_t syntaxes[] =
+  {
+    RE_SYNTAX_EMACS,
+    RE_SYNTAX_AWK,
+    RE_SYNTAX_GNU_AWK,
+    RE_SYNTAX_POSIX_AWK,
+    RE_SYNTAX_GREP,
+    RE_SYNTAX_EGREP,
+    RE_SYNTAX_POSIX_EGREP,
+    RE_SYNTAX_POSIX_BASIC,
+    RE_SYNTAX_POSIX_EXTENDED,
+    RE_SYNTAX_POSIX_MINIMAL_EXTENDED,
+  };
+
+/* Trailing characters placed after the initial character.  */
+static const char trailing_strings[][4] =
+  {
+    "",
+    "[",
+    "\\",
+    "[\\",
+    "(",
+    "(\\",
+    "\\(",
+  };
+
+static int
+do_test (void)
+{
+  /* Staging buffer for the constructed regular expression.  */
+  char buffer[16];
+
+  /* Allocation used to detect over-reading by the regular expression
+     compiler.  */
+  struct support_next_to_fault ntf
+    = support_next_to_fault_allocate (sizeof (buffer));
+
+  /* Arbitrary Unicode codepoint at which we stop generating
+     characters.  We do not probe the whole range because that would
+     take too long due to combinatorical exploision as the result of
+     combination with other flags.  */
+  static const wchar_t last_character = 0xfff;
+
+  for (size_t locale_idx = 0; locale_idx < array_length (locales);
+       ++ locale_idx)
+    {
+      if (setlocale (LC_ALL, locales[locale_idx]) == NULL)
+        {
+          support_record_failure ();
+          printf ("error: setlocale (\"%s\"): %m", locales[locale_idx]);
+          continue;
+        }
+      if (test_verbose > 0)
+        printf ("info: testing locale \"%s\"\n", locales[locale_idx]);
+
+      for (wchar_t wc = 0; wc <= last_character; ++wc)
+        {
+          char *after_wc;
+          if (wc == 0)
+            {
+              /* wcrtomb treats L'\0' in a special way.  */
+              *buffer = '\0';
+              after_wc = &buffer[1];
+            }
+          else
+            {
+              mbstate_t ps = { };
+              size_t ret = wcrtomb (buffer, wc, &ps);
+              if (ret == (size_t) -1)
+                {
+                  /* EILSEQ means that the target character set
+                     cannot encode the character.  */
+                  if (errno != EILSEQ)
+                    {
+                      support_record_failure ();
+                      printf ("error: wcrtomb (0x%x) failed: %m\n",
+                              (unsigned) wc);
+                    }
+                  continue;
+                }
+              TEST_VERIFY_EXIT (ret != 0);
+              after_wc = &buffer[ret];
+            }
+
+          for (size_t trailing_idx = 0;
+               trailing_idx < array_length (trailing_strings);
+               ++trailing_idx)
+            {
+              char *after_trailing
+                = stpcpy (after_wc, trailing_strings[trailing_idx]);
+
+              for (int do_nul = 0; do_nul < 2; ++do_nul)
+                {
+                  char *after_nul;
+                  if (do_nul)
+                    {
+                      *after_trailing = '\0';
+                      after_nul = &after_trailing[1];
+                    }
+                  else
+                    after_nul = after_trailing;
+
+                  size_t length = after_nul - buffer;
+
+                  /* Make sure that the faulting region starts
+                     after the used portion of the buffer.  */
+                  char *ntf_start = ntf.buffer + sizeof (buffer) - length;
+                  memcpy (ntf_start, buffer, length);
+
+                  for (const reg_syntax_t *psyntax = syntaxes;
+                       psyntax < array_end (syntaxes); ++psyntax)
+                    for (int do_icase = 0; do_icase < 2; ++do_icase)
+                      {
+                        re_syntax_options = *psyntax;
+                        if (do_icase)
+                          re_syntax_options |= RE_ICASE;
+
+                        regex_t reg;
+                        memset (&reg, 0, sizeof (reg));
+                        const char *msg = re_compile_pattern
+                          (ntf_start, length, &reg);
+                        if (msg != NULL)
+                          {
+                            if (test_verbose > 0)
+                              {
+                                char *quoted = support_quote_blob
+                                  (buffer, length);
+                                printf ("info: compilation failed for pattern"
+                                        " \"%s\", syntax 0x%lx: %s\n",
+                                        quoted, re_syntax_options, msg);
+                                free (quoted);
+                              }
+                          }
+                        else
+                          regfree (&reg);
+                      }
+                }
+            }
+        }
+    }
+
+  support_next_to_fault_free (&ntf);
+
+  return 0;
+}
+
+#include <support/test-driver.c>

commit 1fe2b9ca8a50aaa789d72944b5a91f1d35337adc
Author: Stefan Liebler <stli@linux.ibm.com>
Date:   Thu Sep 6 14:27:03 2018 +0200

    Fix segfault in maybe_script_execute.
    
    If glibc is built with gcc 8 and -march=z900,
    the testcase posix/tst-spawn4-compat crashes with a segfault.
    
    In function maybe_script_execute, the new_argv array is dynamically
    initialized on stack with (argc + 1) elements.
    The function wants to add _PATH_BSHELL as the first argument
    and writes out of bounds of new_argv.
    There is an off-by-one because maybe_script_execute fails to count
    the terminating NULL when sizing new_argv.
    
    ChangeLog:
    
            * sysdeps/unix/sysv/linux/spawni.c (maybe_script_execute):
            Increment size of new_argv by one.
    
    (cherry picked from commit 28669f86f6780a18daca264f32d66b1428c9c6f1)

diff --git a/ChangeLog b/ChangeLog
index 94b8718365..d9e7e6f1d8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-09-06  Stefan Liebler  <stli@linux.ibm.com>
+
+	* sysdeps/unix/sysv/linux/spawni.c (maybe_script_execute):
+	Increment size of new_argv by one.
+
 2018-08-28  Florian Weimer  <fweimer@redhat.com>
 
 	[BZ #23578]
diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c
index cf0213ece5..85239cedbf 100644
--- a/sysdeps/unix/sysv/linux/spawni.c
+++ b/sysdeps/unix/sysv/linux/spawni.c
@@ -101,7 +101,7 @@ maybe_script_execute (struct posix_spawn_args *args)
       ptrdiff_t argc = args->argc;
 
       /* Construct an argument list for the shell.  */
-      char *new_argv[argc + 1];
+      char *new_argv[argc + 2];
       new_argv[0] = (char *) _PATH_BSHELL;
       new_argv[1] = (char *) args->file;
       if (argc > 1)

commit e7d22db29cfdd2f1fb97a70a76fa53d151569945
Author: Mingli Yu <Mingli.Yu@windriver.com>
Date:   Thu Sep 20 12:41:13 2018 +0200

    Linux gethostid: Check for NULL value from gethostbyname_r [BZ #23679]
    
    A NULL value can happen with certain gethostbyname_r failures.
    
    (cherry picked from commit 1214ba06e6771acb953a190091b0f6055c64fd25)

diff --git a/ChangeLog b/ChangeLog
index d9e7e6f1d8..fc1ea1e418 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-09-20  Mingli Yu  <Mingli.Yu@windriver.com>
+
+	* sysdeps/unix/sysv/linux/gethostid.c (gethostid): Check for NULL
+	value from gethostbyname_r.
+
 2018-09-06  Stefan Liebler  <stli@linux.ibm.com>
 
 	* sysdeps/unix/sysv/linux/spawni.c (maybe_script_execute):
diff --git a/NEWS b/NEWS
index 2855ffde58..502e0c19f5 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ The following bugs are resolved with this release:
   [23521] nss_files aliases database file stream leak
   [23538] pthread_cond_broadcast: Fix waiters-after-spinning case
   [23578] regex: Fix memory overread in re_compile_pattern
+  [23679] gethostid: Missing NULL check for gethostbyname_r result
 
 
 Version 2.28
diff --git a/sysdeps/unix/sysv/linux/gethostid.c b/sysdeps/unix/sysv/linux/gethostid.c
index 2e20f034dc..ee0190e7f9 100644
--- a/sysdeps/unix/sysv/linux/gethostid.c
+++ b/sysdeps/unix/sysv/linux/gethostid.c
@@ -102,12 +102,12 @@ gethostid (void)
     {
       int ret = __gethostbyname_r (hostname, &hostbuf,
 				   tmpbuf.data, tmpbuf.length, &hp, &herr);
-      if (ret == 0)
+      if (ret == 0 && hp != NULL)
 	break;
       else
 	{
 	  /* Enlarge the buffer on ERANGE.  */
-	  if (herr == NETDB_INTERNAL && errno == ERANGE)
+	  if (ret != 0 && herr == NETDB_INTERNAL && errno == ERANGE)
 	    {
 	      if (!scratch_buffer_grow (&tmpbuf))
 		return 0;

commit 307d04334d516bb180f484a2b283f97310bfee66
Author: Florian Weimer <fweimer@redhat.com>
Date:   Thu Sep 20 12:03:01 2018 +0200

    misc: New test misc/tst-gethostid
    
    The empty /etc/hosts file used to trigger bug 23679.
    
    (cherry picked from commit db9a8ad4ff3fc58e3773a9a4d0cabe3c1bc9c94c)

diff --git a/ChangeLog b/ChangeLog
index fc1ea1e418..b380048e1e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-09-20  Florian Weimer  <fweimer@redhat.com>
+
+	* misc/tst-gethostid.c: New file.
+	* misc/Makefile [$(build-shared)] (tests): Add tst-gethostid.
+	(tst-gethostid): Link with -ldl.
+
 2018-09-20  Mingli Yu  <Mingli.Yu@windriver.com>
 
 	* sysdeps/unix/sysv/linux/gethostid.c (gethostid): Check for NULL
diff --git a/misc/Makefile b/misc/Makefile
index b7be2bc19a..c9f81515ac 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -86,6 +86,11 @@ tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \
 	 tst-preadvwritev tst-preadvwritev64 tst-makedev tst-empty \
 	 tst-preadvwritev2 tst-preadvwritev64v2
 
+# Tests which need libdl.
+ifeq (yes,$(build-shared))
+tests += tst-gethostid
+endif
+
 tests-internal := tst-atomic tst-atomic-long tst-allocate_once
 tests-static := tst-empty
 
@@ -145,3 +150,5 @@ tst-allocate_once-ENV = MALLOC_TRACE=$(objpfx)tst-allocate_once.mtrace
 $(objpfx)tst-allocate_once-mem.out: $(objpfx)tst-allocate_once.out
 	$(common-objpfx)malloc/mtrace $(objpfx)tst-allocate_once.mtrace > $@; \
 	$(evaluate-test)
+
+$(objpfx)tst-gethostid: $(libdl)
diff --git a/misc/tst-gethostid.c b/misc/tst-gethostid.c
new file mode 100644
index 0000000000..1490aaf3f5
--- /dev/null
+++ b/misc/tst-gethostid.c
@@ -0,0 +1,108 @@
+/* Basic test for gethostid.
+   Copyright (C) 2018 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/>.  */
+
+#include <gnu/lib-names.h>
+#include <nss.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/namespace.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xdlfcn.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+#include <unistd.h>
+
+/* Initial test is run outside a chroot, to increase the likelihood of
+   success.  */
+static void
+outside_chroot (void *closure)
+{
+  long id = gethostid ();
+  printf ("info: host ID outside chroot: 0x%lx\n", id);
+}
+
+/* The same, but this time perform a chroot operation.  */
+static void
+in_chroot (void *closure)
+{
+  const char *chroot_path = closure;
+  xchroot (chroot_path);
+  long id = gethostid ();
+  printf ("info: host ID in chroot: 0x%lx\n", id);
+}
+
+static int
+do_test (void)
+{
+  support_isolate_in_subprocess (outside_chroot, NULL);
+
+  /* Now run the test inside a chroot.  */
+  support_become_root ();
+  if (!support_can_chroot ())
+    /* Cannot perform further tests.  */
+    return 0;
+
+  /* Only use nss_files.  */
+  __nss_configure_lookup ("hosts", "files");
+
+  /* Load the DSO outside of the chroot.  */
+  xdlopen (LIBNSS_FILES_SO, RTLD_LAZY);
+
+  char *chroot_dir = support_create_temp_directory ("tst-gethostid-");
+  support_isolate_in_subprocess (in_chroot, chroot_dir);
+
+  /* Tests with /etc/hosts in the chroot.  */
+  {
+    char *path = xasprintf ("%s/etc", chroot_dir);
+    add_temp_file (path);
+    xmkdir (path, 0777);
+    free (path);
+    path = xasprintf ("%s/etc/hosts", chroot_dir);
+    add_temp_file (path);
+
+    FILE *fp = xfopen (path, "w");
+    xfclose (fp);
+    printf ("info: chroot test with an empty /etc/hosts file\n");
+    support_isolate_in_subprocess (in_chroot, chroot_dir);
+
+    char hostname[1024];
+    int ret = gethostname (hostname, sizeof (hostname));
+    if (ret < 0)
+      printf ("warning: invalid result from gethostname: %d\n", ret);
+    else if (strlen (hostname) == 0)
+      puts ("warning: gethostname returned empty string");
+    else
+      {
+        printf ("info: chroot test with IPv6 address in /etc/hosts for: %s\n",
+                hostname);
+        fp = xfopen (path, "w");
+        /* Use an IPv6 address to induce another lookup failure.  */
+        fprintf (fp, "2001:db8::1 %s\n", hostname);
+        xfclose (fp);
+        support_isolate_in_subprocess (in_chroot, chroot_dir);
+      }
+    free (path);
+  }
+  free (chroot_dir);
+
+  return 0;
+}
+
+#include <support/test-driver.c>

commit a55e109709af55e6ed67d3f9536cac5d929c982e
Author: Carlos O'Donell <carlos@redhat.com>
Date:   Wed Sep 5 01:16:42 2018 -0400

    Fix tst-setcontext9 for optimized small stacks.
    
    If the compiler reduces the stack usage in function f1 before calling
    into function f2, then when we swapcontext back to f1 and continue
    execution we may overwrite registers that were spilled to the stack
    while f2 was executing.  Later when we return to f2 the corrupt
    registers will be reloaded from the stack and the test will crash.  This
    was most commonly observed on i686 with __x86.get_pc_thunk.dx and
    needing to save and restore $edx.  Overall i686 has few registers and
    the spilling to the stack is bound to happen, therefore the solution to
    making this test robust is to split function f1 into two parts f1a and
    f1b, and allocate f1b it's own stack such that subsequent execution does
    not overwrite the stack in use by function f2.
    
    Tested on i686 and x86_64.
    
    Signed-off-by: Carlos O'Donell <carlos@redhat.com>
    (cherry picked from commit 791b350dc725545e3f9b5db0f97ebdbc60c9735f)

diff --git a/ChangeLog b/ChangeLog
index b380048e1e..bda963483f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-09-19  Carlos O'Donell  <carlos@redhat.com>
+
+	* stdlib/tst-setcontext9.c (f1): Rename to...
+	(f1a): ... this.
+	(f1b): New function implementing lower half of f1 in alternate stack.
+
 2018-09-20  Florian Weimer  <fweimer@redhat.com>
 
 	* misc/tst-gethostid.c: New file.
diff --git a/stdlib/tst-setcontext9.c b/stdlib/tst-setcontext9.c
index 4636ce9030..db8355766c 100644
--- a/stdlib/tst-setcontext9.c
+++ b/stdlib/tst-setcontext9.c
@@ -41,26 +41,55 @@ f2 (void)
 }
 
 static void
-f1 (void)
+f1b (void)
 {
-  puts ("start f1");
-  if (getcontext (&ctx[2]) != 0)
-    {
-      printf ("%s: getcontext: %m\n", __FUNCTION__);
-      exit (EXIT_FAILURE);
-    }
   if (done)
     {
-      puts ("set context in f1");
+      puts ("set context in f1b");
       if (setcontext (&ctx[3]) != 0)
 	{
 	  printf ("%s: setcontext: %m\n", __FUNCTION__);
 	  exit (EXIT_FAILURE);
 	}
     }
+  exit (EXIT_FAILURE);
+}
+
+static void
+f1a (void)
+{
+  char st2[32768];
+  puts ("start f1a");
+  if (getcontext (&ctx[2]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  ctx[2].uc_stack.ss_sp = st2;
+  ctx[2].uc_stack.ss_size = sizeof st2;
+  ctx[2].uc_link = &ctx[0];
+  makecontext (&ctx[2], (void (*) (void)) f1b, 0);
   f2 ();
 }
 
+/* The execution path through the test looks like this:
+   do_test (call)
+   -> "making contexts"
+   -> "swap contexts"
+   f1a (via swapcontext to ctx[1], with alternate stack)
+   -> "start f1a"
+   f2 (call)
+   -> "swap contexts in f2"
+   f1b (via swapcontext to ctx[2], with alternate stack)
+   -> "set context in f1b"
+   do_test (via setcontext to ctx[3], main stack)
+   -> "setcontext"
+   f2 (via setcontext to ctx[4], with alternate stack)
+   -> "end f2"
+
+   We must use an alternate stack for f1b, because if we don't then the
+   result of executing an earlier caller may overwrite registers
+   spilled to the stack in f2.  */
 static int
 do_test (void)
 {
@@ -79,7 +108,7 @@ do_test (void)
   ctx[1].uc_stack.ss_sp = st1;
   ctx[1].uc_stack.ss_size = sizeof st1;
   ctx[1].uc_link = &ctx[0];
-  makecontext (&ctx[1], (void (*) (void)) f1, 0);
+  makecontext (&ctx[1], (void (*) (void)) f1a, 0);
   puts ("swap contexts");
   if (swapcontext (&ctx[3], &ctx[1]) != 0)
     {

commit 0ef2f4400c06927af34c515555f68840a70ba409
Author: Wilco Dijkstra <wdijkstr@arm.com>
Date:   Wed Sep 19 16:50:18 2018 +0100

    Fix strstr bug with huge needles (bug 23637)
    
    The generic strstr in GLIBC 2.28 fails to match huge needles.  The optimized
    AVAILABLE macro reads ahead a large fixed amount to reduce the overhead of
    repeatedly checking for the end of the string.  However if the needle length
    is larger than this, two_way_long_needle may confuse this as meaning the end
    of the string and return NULL.  This is fixed by adding the needle length to
    the amount to read ahead.
    
            [BZ #23637]
            * string/test-strstr.c (pr23637): New function.
            (test_main): Add tests with longer needles.
            * string/strcasestr.c (AVAILABLE): Fix readahead distance.
            * string/strstr.c (AVAILABLE): Likewise.
    
        (cherry picked from commit 83a552b0bb9fc2a5e80a0ab3723c0a80ce1db9f2)

diff --git a/ChangeLog b/ChangeLog
index bda963483f..a111f0131b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2018-09-19  Wilco Dijkstra  <wdijkstr@arm.com>
+
+	[BZ #23637]
+	* string/test-strstr.c (pr23637): New function.
+	(test_main): Add tests with longer needles.
+	* string/strcasestr.c (AVAILABLE): Fix readahead distance.
+	* string/strstr.c (AVAILABLE): Likewise.
+
 2018-09-19  Carlos O'Donell  <carlos@redhat.com>
 
 	* stdlib/tst-setcontext9.c (f1): Rename to...
diff --git a/string/strcasestr.c b/string/strcasestr.c
index 5909fe3cdb..421764bd1b 100644
--- a/string/strcasestr.c
+++ b/string/strcasestr.c
@@ -37,8 +37,9 @@
 /* Two-Way algorithm.  */
 #define RETURN_TYPE char *
 #define AVAILABLE(h, h_l, j, n_l)			\
-  (((j) + (n_l) <= (h_l)) || ((h_l) += __strnlen ((void*)((h) + (h_l)), 512), \
-			      (j) + (n_l) <= (h_l)))
+  (((j) + (n_l) <= (h_l)) \
+   || ((h_l) += __strnlen ((void*)((h) + (h_l)), (n_l) + 512), \
+       (j) + (n_l) <= (h_l)))
 #define CHECK_EOL (1)
 #define RET0_IF_0(a) if (!a) goto ret0
 #define CANON_ELEMENT(c) TOLOWER (c)
diff --git a/string/strstr.c b/string/strstr.c
index 265e9f310c..79ebcc7532 100644
--- a/string/strstr.c
+++ b/string/strstr.c
@@ -33,8 +33,9 @@
 
 #define RETURN_TYPE char *
 #define AVAILABLE(h, h_l, j, n_l)			\
-  (((j) + (n_l) <= (h_l)) || ((h_l) += __strnlen ((void*)((h) + (h_l)), 512), \
-			      (j) + (n_l) <= (h_l)))
+  (((j) + (n_l) <= (h_l)) \
+   || ((h_l) += __strnlen ((void*)((h) + (h_l)), (n_l) + 512), \
+       (j) + (n_l) <= (h_l)))
 #define CHECK_EOL (1)
 #define RET0_IF_0(a) if (!a) goto ret0
 #define FASTSEARCH(S,C,N) (void*) strchr ((void*)(S), (C))
diff --git a/string/test-strstr.c b/string/test-strstr.c
index 8d99716ff3..5861b01b73 100644
--- a/string/test-strstr.c
+++ b/string/test-strstr.c
@@ -151,6 +151,32 @@ check2 (void)
     }
 }
 
+#define N 1024
+
+static void
+pr23637 (void)
+{
+  char *h = (char*) buf1;
+  char *n = (char*) buf2;
+
+  for (int i = 0; i < N; i++)
+    {
+      n[i] = 'x';
+      h[i] = ' ';
+      h[i + N] = 'x';
+    }
+
+  n[N] = '\0';
+  h[N * 2] = '\0';
+
+  /* Ensure we don't match at the first 'x'.  */
+  h[0] = 'x';
+
+  char *exp_result = stupid_strstr (h, n);
+  FOR_EACH_IMPL (impl, 0)
+    check_result (impl, h, n, exp_result);
+}
+
 static int
 test_main (void)
 {
@@ -158,6 +184,7 @@ test_main (void)
 
   check1 ();
   check2 ();
+  pr23637 ();
 
   printf ("%23s", "");
   FOR_EACH_IMPL (impl, 0)
@@ -202,6 +229,9 @@ test_main (void)
 	do_test (15, 9, hlen, klen, 1);
 	do_test (15, 15, hlen, klen, 0);
 	do_test (15, 15, hlen, klen, 1);
+
+	do_test (15, 15, hlen + klen * 4, klen * 4, 0);
+	do_test (15, 15, hlen + klen * 4, klen * 4, 1);
       }
 
   do_test (0, 0, page_size - 1, 16, 0);

commit 2339d6a55eb7a7e040ae888e906adc49eeb59eab
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Sep 12 08:40:59 2018 -0700

    i386: Use ENTRY and END in start.S [BZ #23606]
    
    Wrapping the _start function with ENTRY and END to insert ENDBR32 at
    function entry when CET is enabled.  Since _start now includes CFI,
    without "cfi_undefined (eip)", unwinder may not terminate at _start
    and we will get
    
    Program received signal SIGSEGV, Segmentation fault.
    0xf7dc661e in ?? () from /lib/libgcc_s.so.1
    Missing separate debuginfos, use: dnf debuginfo-install libgcc-8.2.1-3.0.fc28.i686
    (gdb) bt
     #0  0xf7dc661e in ?? () from /lib/libgcc_s.so.1
     #1  0xf7dc7c18 in _Unwind_Backtrace () from /lib/libgcc_s.so.1
     #2  0xf7f0d809 in __GI___backtrace (array=array@entry=0xffffc7d0,
        size=size@entry=20) at ../sysdeps/i386/backtrace.c:127
     #3  0x08049254 in compare (p1=p1@entry=0xffffcad0, p2=p2@entry=0xffffcad4)
        at backtrace-tst.c:12
     #4  0xf7e2a28c in msort_with_tmp (p=p@entry=0xffffca5c, b=b@entry=0xffffcad0,
        n=n@entry=2) at msort.c:65
     #5  0xf7e29f64 in msort_with_tmp (n=2, b=0xffffcad0, p=0xffffca5c)
        at msort.c:53
     #6  msort_with_tmp (p=p@entry=0xffffca5c, b=b@entry=0xffffcad0, n=n@entry=5)
        at msort.c:53
     #7  0xf7e29f64 in msort_with_tmp (n=5, b=0xffffcad0, p=0xffffca5c)
        at msort.c:53
     #8  msort_with_tmp (p=p@entry=0xffffca5c, b=b@entry=0xffffcad0, n=n@entry=10)
        at msort.c:53
     #9  0xf7e29f64 in msort_with_tmp (n=10, b=0xffffcad0, p=0xffffca5c)
        at msort.c:53
     #10 msort_with_tmp (p=p@entry=0xffffca5c, b=b@entry=0xffffcad0, n=n@entry=20)
        at msort.c:53
     #11 0xf7e2a5b6 in msort_with_tmp (n=20, b=0xffffcad0, p=0xffffca5c)
        at msort.c:297
     #12 __GI___qsort_r (b=b@entry=0xffffcad0, n=n@entry=20, s=s@entry=4,
        cmp=cmp@entry=0x8049230 <compare>, arg=arg@entry=0x0) at msort.c:297
     #13 0xf7e2a84d in __GI_qsort (b=b@entry=0xffffcad0, n=n@entry=20, s=s@entry=4,
        cmp=cmp@entry=0x8049230 <compare>) at msort.c:308
     #14 0x080490f6 in main (argc=2, argv=0xffffcbd4) at backtrace-tst.c:39
    
    FAIL: debug/backtrace-tst
    
            [BZ #23606]
            * sysdeps/i386/start.S: Include <sysdep.h>
            (_start): Use ENTRY/END to insert ENDBR32 at entry when CET is
            enabled.  Add cfi_undefined (eip).
    
    Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
    
    (cherry picked from commit 5a274db4ea363d6b0b92933f085a92daaf1be2f2)

diff --git a/ChangeLog b/ChangeLog
index a111f0131b..84503e3a0c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2018-09-21  H.J. Lu  <hongjiu.lu@intel.com>
+	    Xuepeng Guo  <xuepeng.guo@intel.com>
+
+	[BZ #23606]
+	* sysdeps/i386/start.S: Include <sysdep.h>
+	(_start): Use ENTRY/END to insert ENDBR32 at entry when CET is
+	enabled.  Add cfi_undefined (eip).
+
 2018-09-19  Wilco Dijkstra  <wdijkstr@arm.com>
 
 	[BZ #23637]
diff --git a/NEWS b/NEWS
index 502e0c19f5..d1f1dd4b22 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ The following bugs are resolved with this release:
   [23521] nss_files aliases database file stream leak
   [23538] pthread_cond_broadcast: Fix waiters-after-spinning case
   [23578] regex: Fix memory overread in re_compile_pattern
+  [23606] Missing ENDBR32 in sysdeps/i386/start.S
   [23679] gethostid: Missing NULL check for gethostbyname_r result
 
 
diff --git a/sysdeps/i386/start.S b/sysdeps/i386/start.S
index 91035fa83f..e35e9bd31b 100644
--- a/sysdeps/i386/start.S
+++ b/sysdeps/i386/start.S
@@ -52,10 +52,11 @@
 					NULL
 */
 
-	.text
-	.globl _start
-	.type _start,@function
-_start:
+#include <sysdep.h>
+
+ENTRY (_start)
+	/* Clearing frame pointer is insufficient, use CFI.  */
+	cfi_undefined (eip)
 	/* Clear the frame pointer.  The ABI suggests this be done, to mark
 	   the outermost frame obviously.  */
 	xorl %ebp, %ebp
@@ -131,6 +132,7 @@ _start:
 1:	movl	(%esp), %ebx
 	ret
 #endif
+END (_start)
 
 /* To fulfill the System V/i386 ABI we need this symbol.  Yuck, it's so
    meaningless since we don't support machines < 80386.  */

commit 3a67c72c1512f778304a5644dea2fcf5bdece274
Author: Andreas Schwab <schwab@suse.de>
Date:   Thu Sep 27 12:37:06 2018 +0200

    Fix stack overflow in tst-setcontext9 (bug 23717)
    
    The function f1a, executed on a stack of size 32k, allocates an object of
    size 32k on the stack.  Make the stack variables static to reduce
    excessive stack usage.
    
    (cherry picked from commit f841c97e515a1673485a2b12b3c280073d737890)

diff --git a/ChangeLog b/ChangeLog
index 84503e3a0c..4fbb9e2ad8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-09-27  Andreas Schwab  <schwab@suse.de>
+
+	[BZ #23717]
+	* stdlib/tst-setcontext9.c (f1a): Make st2 static.
+	(do_test): Make st1 static.
+
 2018-09-21  H.J. Lu  <hongjiu.lu@intel.com>
 	    Xuepeng Guo  <xuepeng.guo@intel.com>
 
diff --git a/NEWS b/NEWS
index d1f1dd4b22..bc568bcec0 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ The following bugs are resolved with this release:
   [23578] regex: Fix memory overread in re_compile_pattern
   [23606] Missing ENDBR32 in sysdeps/i386/start.S
   [23679] gethostid: Missing NULL check for gethostbyname_r result
+  [23717] Fix stack overflow in stdlib/tst-setcontext9
 
 
 Version 2.28
diff --git a/stdlib/tst-setcontext9.c b/stdlib/tst-setcontext9.c
index db8355766c..009928235d 100644
--- a/stdlib/tst-setcontext9.c
+++ b/stdlib/tst-setcontext9.c
@@ -58,7 +58,7 @@ f1b (void)
 static void
 f1a (void)
 {
-  char st2[32768];
+  static char st2[32768];
   puts ("start f1a");
   if (getcontext (&ctx[2]) != 0)
     {
@@ -93,7 +93,7 @@ f1a (void)
 static int
 do_test (void)
 {
-  char st1[32768];
+  static char st1[32768];
   puts ("making contexts");
   if (getcontext (&ctx[0]) != 0)
     {

commit 044c96f0d5595aeb0bb4e79355081c5a7f4faca5
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Wed Aug 29 16:36:44 2018 -0300

    Fix misreported errno on preadv2/pwritev2 (BZ#23579)
    
    The fallback code of Linux wrapper for preadv2/pwritev2 executes
    regardless of the errno code for preadv2, instead of the case where
    the syscall is not supported.
    
    This fixes it by calling the fallback code iff errno is ENOSYS. The
    patch also adds tests for both invalid file descriptor and invalid
    iov_len and vector count.
    
    The only discrepancy between preadv2 and fallback code regarding
    error reporting is when an invalid flags are used.  The fallback code
    bails out earlier with ENOTSUP instead of EINVAL/EBADF when the syscall
    is used.
    
    Checked on x86_64-linux-gnu on a 4.4.0 and 4.15.0 kernel.
    
            [BZ #23579]
            * misc/tst-preadvwritev2-common.c (do_test_with_invalid_fd): New
            test.
            * misc/tst-preadvwritev2.c, misc/tst-preadvwritev64v2.c (do_test):
            Call do_test_with_invalid_fd.
            * sysdeps/unix/sysv/linux/preadv2.c (preadv2): Use fallback code iff
            errno is ENOSYS.
            * sysdeps/unix/sysv/linux/preadv64v2.c (preadv64v2): Likewise.
            * sysdeps/unix/sysv/linux/pwritev2.c (pwritev2): Likewise.
            * sysdeps/unix/sysv/linux/pwritev64v2.c (pwritev64v2): Likewise.
    
    (cherry picked from commit 7a16bdbb9ff4122af0a28dc20996c95352011fdd)

diff --git a/ChangeLog b/ChangeLog
index 4fbb9e2ad8..11a9b8d98e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2018-09-28  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+	[BZ #23579]
+	* misc/tst-preadvwritev2-common.c (do_test_with_invalid_fd,
+	do_test_with_invalid_iov): New tests.
+	* misc/tst-preadvwritev2.c, misc/tst-preadvwritev64v2.c (do_test):
+	Call do_test_with_invalid_fd and do_test_with_invalid_iov.
+	* sysdeps/unix/sysv/linux/preadv2.c (preadv2): Use fallback code iff
+	errno is ENOSYS.
+	* sysdeps/unix/sysv/linux/preadv64v2.c (preadv64v2): Likewise.
+	* sysdeps/unix/sysv/linux/pwritev2.c (pwritev2): Likewise.
+	* sysdeps/unix/sysv/linux/pwritev64v2.c (pwritev64v2): Likewise.
+	* NEWS: Add bug fixed.
+
 2018-09-27  Andreas Schwab  <schwab@suse.de>
 
 	[BZ #23717]
diff --git a/NEWS b/NEWS
index bc568bcec0..fd14941128 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ The following bugs are resolved with this release:
   [23521] nss_files aliases database file stream leak
   [23538] pthread_cond_broadcast: Fix waiters-after-spinning case
   [23578] regex: Fix memory overread in re_compile_pattern
+  [23579] libc: Errors misreported in preadv2
   [23606] Missing ENDBR32 in sysdeps/i386/start.S
   [23679] gethostid: Missing NULL check for gethostbyname_r result
   [23717] Fix stack overflow in stdlib/tst-setcontext9
diff --git a/misc/tst-preadvwritev2-common.c b/misc/tst-preadvwritev2-common.c
index f889a21544..50b9da3fea 100644
--- a/misc/tst-preadvwritev2-common.c
+++ b/misc/tst-preadvwritev2-common.c
@@ -19,9 +19,6 @@
 #include <limits.h>
 #include <support/check.h>
 
-static void
-do_test_with_invalid_flags (void)
-{
 #ifndef RWF_HIPRI
 # define RWF_HIPRI 0
 #endif
@@ -39,6 +36,68 @@ do_test_with_invalid_flags (void)
 #endif
 #define RWF_SUPPORTED	(RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT \
 			 | RWF_APPEND)
+
+static void
+do_test_with_invalid_fd (void)
+{
+  char buf[256];
+  struct iovec iov = { buf, sizeof buf };
+
+  /* Check with flag being 0 to use the fallback code which calls pwritev
+     or writev.  */
+  TEST_VERIFY (preadv2 (-1, &iov, 1, -1, 0) == -1);
+  TEST_COMPARE (errno, EBADF);
+  TEST_VERIFY (pwritev2 (-1, &iov, 1, -1, 0) == -1);
+  TEST_COMPARE (errno, EBADF);
+
+  /* Same tests as before but with flags being different than 0.  Since
+     there is no emulation for any flag value, fallback code returns
+     ENOTSUP.  This is different running on a kernel with preadv2/pwritev2
+     support, where EBADF is returned).  */
+  TEST_VERIFY (preadv2 (-1, &iov, 1, 0, RWF_HIPRI) == -1);
+  TEST_VERIFY (errno == EBADF || errno == ENOTSUP);
+  TEST_VERIFY (pwritev2 (-1, &iov, 1, 0, RWF_HIPRI) == -1);
+  TEST_VERIFY (errno == EBADF || errno == ENOTSUP);
+}
+
+static void
+do_test_with_invalid_iov (void)
+{
+  {
+    char buf[256];
+    struct iovec iov;
+
+    iov.iov_base = buf;
+    iov.iov_len = (size_t)SSIZE_MAX + 1;
+
+    TEST_VERIFY (preadv2 (temp_fd, &iov, 1, 0, 0) == -1);
+    TEST_COMPARE (errno, EINVAL);
+    TEST_VERIFY (pwritev2 (temp_fd, &iov, 1, 0, 0) == -1);
+    TEST_COMPARE (errno, EINVAL);
+
+    /* Same as for invalid file descriptor tests, emulation fallback
+       first checks for flag value and return ENOTSUP.  */
+    TEST_VERIFY (preadv2 (temp_fd, &iov, 1, 0, RWF_HIPRI) == -1);
+    TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
+    TEST_VERIFY (pwritev2 (temp_fd, &iov, 1, 0, RWF_HIPRI) == -1);
+    TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
+  }
+
+  {
+    /* An invalid iovec buffer should trigger an invalid memory access
+       or an error (Linux for instance returns EFAULT).  */
+    struct iovec iov[IOV_MAX+1] = { 0 };
+
+    TEST_VERIFY (preadv2 (temp_fd, iov, IOV_MAX + 1, 0, RWF_HIPRI) == -1);
+    TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
+    TEST_VERIFY (pwritev2 (temp_fd, iov, IOV_MAX + 1, 0, RWF_HIPRI) == -1);
+    TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
+  }
+}
+
+static void
+do_test_with_invalid_flags (void)
+{
   /* Set the next bit from the mask of all supported flags.  */
   int invalid_flag = RWF_SUPPORTED != 0 ? __builtin_clz (RWF_SUPPORTED) : 2;
   invalid_flag = 0x1 << ((sizeof (int) * CHAR_BIT) - invalid_flag);
diff --git a/misc/tst-preadvwritev2.c b/misc/tst-preadvwritev2.c
index be22802dbe..cb58cbe41e 100644
--- a/misc/tst-preadvwritev2.c
+++ b/misc/tst-preadvwritev2.c
@@ -30,6 +30,8 @@ do_test (void)
 {
   do_test_with_invalid_flags ();
   do_test_without_offset ();
+  do_test_with_invalid_fd ();
+  do_test_with_invalid_iov ();
 
   return do_test_with_offset (0);
 }
diff --git a/misc/tst-preadvwritev64v2.c b/misc/tst-preadvwritev64v2.c
index 8d3cc32b28..6a9de54c78 100644
--- a/misc/tst-preadvwritev64v2.c
+++ b/misc/tst-preadvwritev64v2.c
@@ -32,6 +32,8 @@ do_test (void)
 {
   do_test_with_invalid_flags ();
   do_test_without_offset ();
+  do_test_with_invalid_fd ();
+  do_test_with_invalid_iov ();
 
   return do_test_with_offset (0);
 }
diff --git a/sysdeps/unix/sysv/linux/preadv2.c b/sysdeps/unix/sysv/linux/preadv2.c
index c8bf0764ef..bb08cbc5fd 100644
--- a/sysdeps/unix/sysv/linux/preadv2.c
+++ b/sysdeps/unix/sysv/linux/preadv2.c
@@ -32,7 +32,7 @@ preadv2 (int fd, const struct iovec *vector, int count, off_t offset,
 # ifdef __NR_preadv2
   ssize_t result = SYSCALL_CANCEL (preadv2, fd, vector, count,
 				   LO_HI_LONG (offset), flags);
-  if (result >= 0)
+  if (result >= 0 || errno != ENOSYS)
     return result;
 # endif
   /* Trying to emulate the preadv2 syscall flags is troublesome:
diff --git a/sysdeps/unix/sysv/linux/preadv64v2.c b/sysdeps/unix/sysv/linux/preadv64v2.c
index d7400a0252..b72a047347 100644
--- a/sysdeps/unix/sysv/linux/preadv64v2.c
+++ b/sysdeps/unix/sysv/linux/preadv64v2.c
@@ -30,7 +30,7 @@ preadv64v2 (int fd, const struct iovec *vector, int count, off64_t offset,
 #ifdef __NR_preadv64v2
   ssize_t result = SYSCALL_CANCEL (preadv64v2, fd, vector, count,
 				   LO_HI_LONG (offset), flags);
-  if (result >= 0)
+  if (result >= 0 || errno != ENOSYS)
     return result;
 #endif
   /* Trying to emulate the preadv2 syscall flags is troublesome:
diff --git a/sysdeps/unix/sysv/linux/pwritev2.c b/sysdeps/unix/sysv/linux/pwritev2.c
index 29c2264c8f..26333ebd43 100644
--- a/sysdeps/unix/sysv/linux/pwritev2.c
+++ b/sysdeps/unix/sysv/linux/pwritev2.c
@@ -28,7 +28,7 @@ pwritev2 (int fd, const struct iovec *vector, int count, off_t offset,
 # ifdef __NR_pwritev2
   ssize_t result = SYSCALL_CANCEL (pwritev2, fd, vector, count,
 				   LO_HI_LONG (offset), flags);
-  if (result >= 0)
+  if (result >= 0 || errno != ENOSYS)
     return result;
 # endif
   /* Trying to emulate the pwritev2 syscall flags is troublesome:
diff --git a/sysdeps/unix/sysv/linux/pwritev64v2.c b/sysdeps/unix/sysv/linux/pwritev64v2.c
index 42da321149..17ea905aa6 100644
--- a/sysdeps/unix/sysv/linux/pwritev64v2.c
+++ b/sysdeps/unix/sysv/linux/pwritev64v2.c
@@ -30,7 +30,7 @@ pwritev64v2 (int fd, const struct iovec *vector, int count, off64_t offset,
 #ifdef __NR_pwritev64v2
   ssize_t result = SYSCALL_CANCEL (pwritev64v2, fd, vector, count,
 				   LO_HI_LONG (offset), flags);
-  if (result >= 0)
+  if (result >= 0 || errno != ENOSYS)
     return result;
 #endif
   /* Trying to emulate the pwritev2 syscall flags is troublesome:
