diff --git a/SOURCES/glibc-rh1065574-1.patch b/SOURCES/glibc-rh1065574-1.patch
new file mode 100644
index 0000000..99b157e
--- /dev/null
+++ b/SOURCES/glibc-rh1065574-1.patch
@@ -0,0 +1,38 @@
+commit 8b35e35d0f4eae28a47c23e2aa15ddf570fa86ef
+Author: Ondřej Bílka <neleai@seznam.cz>
+Date:   Fri Nov 1 15:39:26 2013 +0100
+
+    Fix malloc_info statistic. Fixes bug 16112
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index b47d99ac65344c82..c98b3f79ed38b4f0 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -5068,23 +5068,11 @@ malloc_info (int options, FILE *fp)
+ 	sizes[i].total = sizes[i].count * sizes[i].to;
+       }
+ 
+-    mbinptr bin = bin_at (ar_ptr, 1);
+-    struct malloc_chunk *r = bin->fd;
+-    if (r != NULL)
+-      {
+-	while (r != bin)
+-	  {
+-	    ++sizes[NFASTBINS].count;
+-	    sizes[NFASTBINS].total += r->size;
+-	    sizes[NFASTBINS].from = MIN (sizes[NFASTBINS].from, r->size);
+-	    sizes[NFASTBINS].to = MAX (sizes[NFASTBINS].to, r->size);
+-	    r = r->fd;
+-	  }
+-	nblocks += sizes[NFASTBINS].count;
+-	avail += sizes[NFASTBINS].total;
+-      }
+ 
+-    for (size_t i = 2; i < NBINS; ++i)
++    mbinptr bin;
++    struct malloc_chunk *r;
++
++    for (size_t i = 1; i < NBINS; ++i)
+       {
+ 	bin = bin_at (ar_ptr, i);
+ 	r = bin->fd;
diff --git a/SOURCES/glibc-rh1065574-2.patch b/SOURCES/glibc-rh1065574-2.patch
new file mode 100644
index 0000000..77d6b50
--- /dev/null
+++ b/SOURCES/glibc-rh1065574-2.patch
@@ -0,0 +1,236 @@
+This is a partial recreation of this upstream commit, restricted to
+the malloc_info function:
+
+commit 6c8dbf00f536d78b1937b5af6f57be47fd376344
+Author: Ondřej Bílka <neleai@seznam.cz>
+Date:   Thu Jan 2 09:38:18 2014 +0100
+
+    Reformat malloc to gnu style.
+
+It is not an exact copy because glibc-rh1103856.patch backported
+commit 4d653a59ffeae0f46f76a40230e2cfa9587b7e7e ("Add mmap usage in
+malloc_info output"), which came after the reformatting upstream.
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index c98b3f79ed38b4f0..5c7a27129d66e06a 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -5023,7 +5023,8 @@ malloc_info (int options, FILE *fp)
+   size_t total_aspace = 0;
+   size_t total_aspace_mprotect = 0;
+ 
+-  void mi_arena (mstate ar_ptr)
++  void
++  mi_arena (mstate ar_ptr)
+   {
+     fprintf (fp, "<heap nr=\"%d\">\n<sizes>\n", n++);
+ 
+@@ -5044,28 +5045,28 @@ malloc_info (int options, FILE *fp)
+ 
+     for (size_t i = 0; i < NFASTBINS; ++i)
+       {
+-	mchunkptr p = fastbin (ar_ptr, i);
+-	if (p != NULL)
+-	  {
+-	    size_t nthissize = 0;
+-	    size_t thissize = chunksize (p);
+-
+-	    while (p != NULL)
+-	      {
+-		++nthissize;
+-		p = p->fd;
+-	      }
+-
+-	    fastavail += nthissize * thissize;
+-	    nfastblocks += nthissize;
+-	    sizes[i].from = thissize - (MALLOC_ALIGNMENT - 1);
+-	    sizes[i].to = thissize;
+-	    sizes[i].count = nthissize;
+-	  }
+-	else
+-	  sizes[i].from = sizes[i].to = sizes[i].count = 0;
+-
+-	sizes[i].total = sizes[i].count * sizes[i].to;
++        mchunkptr p = fastbin (ar_ptr, i);
++        if (p != NULL)
++          {
++            size_t nthissize = 0;
++            size_t thissize = chunksize (p);
++
++            while (p != NULL)
++              {
++                ++nthissize;
++                p = p->fd;
++              }
++
++            fastavail += nthissize * thissize;
++            nfastblocks += nthissize;
++            sizes[i].from = thissize - (MALLOC_ALIGNMENT - 1);
++            sizes[i].to = thissize;
++            sizes[i].count = nthissize;
++          }
++        else
++          sizes[i].from = sizes[i].to = sizes[i].count = 0;
++
++        sizes[i].total = sizes[i].count * sizes[i].to;
+       }
+ 
+ 
+@@ -5074,29 +5075,29 @@ malloc_info (int options, FILE *fp)
+ 
+     for (size_t i = 1; i < NBINS; ++i)
+       {
+-	bin = bin_at (ar_ptr, i);
+-	r = bin->fd;
+-	sizes[NFASTBINS - 1 + i].from = ~((size_t) 0);
+-	sizes[NFASTBINS - 1 + i].to = sizes[NFASTBINS - 1 + i].total
+-	  = sizes[NFASTBINS - 1 + i].count = 0;
+-
+-	if (r != NULL)
+-	  while (r != bin)
+-	    {
+-	      ++sizes[NFASTBINS - 1 + i].count;
+-	      sizes[NFASTBINS - 1 + i].total += r->size;
+-	      sizes[NFASTBINS - 1 + i].from
+-		= MIN (sizes[NFASTBINS - 1 + i].from, r->size);
+-	      sizes[NFASTBINS - 1 + i].to = MAX (sizes[NFASTBINS - 1 + i].to,
+-						 r->size);
+-
+-	      r = r->fd;
+-	    }
+-
+-	if (sizes[NFASTBINS - 1 + i].count == 0)
+-	  sizes[NFASTBINS - 1 + i].from = 0;
+-	nblocks += sizes[NFASTBINS - 1 + i].count;
+-	avail += sizes[NFASTBINS - 1 + i].total;
++        bin = bin_at (ar_ptr, i);
++        r = bin->fd;
++        sizes[NFASTBINS - 1 + i].from = ~((size_t) 0);
++        sizes[NFASTBINS - 1 + i].to = sizes[NFASTBINS - 1 + i].total
++                                        = sizes[NFASTBINS - 1 + i].count = 0;
++
++        if (r != NULL)
++          while (r != bin)
++            {
++              ++sizes[NFASTBINS - 1 + i].count;
++              sizes[NFASTBINS - 1 + i].total += r->size;
++              sizes[NFASTBINS - 1 + i].from
++                = MIN (sizes[NFASTBINS - 1 + i].from, r->size);
++              sizes[NFASTBINS - 1 + i].to = MAX (sizes[NFASTBINS - 1 + i].to,
++                                                 r->size);
++
++              r = r->fd;
++            }
++
++        if (sizes[NFASTBINS - 1 + i].count == 0)
++          sizes[NFASTBINS - 1 + i].from = 0;
++        nblocks += sizes[NFASTBINS - 1 + i].count;
++        avail += sizes[NFASTBINS - 1 + i].total;
+       }
+ 
+     mutex_unlock (&ar_ptr->mutex);
+@@ -5109,51 +5110,51 @@ malloc_info (int options, FILE *fp)
+ 
+     for (size_t i = 0; i < nsizes; ++i)
+       if (sizes[i].count != 0 && i != NFASTBINS)
+-	fprintf (fp, "\
++        fprintf (fp, "							      \
+ <size from=\"%zu\" to=\"%zu\" total=\"%zu\" count=\"%zu\"/>\n",
+-		 sizes[i].from, sizes[i].to, sizes[i].total, sizes[i].count);
++                 sizes[i].from, sizes[i].to, sizes[i].total, sizes[i].count);
+ 
+     if (sizes[NFASTBINS].count != 0)
+       fprintf (fp, "\
+ <unsorted from=\"%zu\" to=\"%zu\" total=\"%zu\" count=\"%zu\"/>\n",
+-	       sizes[NFASTBINS].from, sizes[NFASTBINS].to,
+-	       sizes[NFASTBINS].total, sizes[NFASTBINS].count);
++               sizes[NFASTBINS].from, sizes[NFASTBINS].to,
++               sizes[NFASTBINS].total, sizes[NFASTBINS].count);
+ 
+     total_system += ar_ptr->system_mem;
+     total_max_system += ar_ptr->max_system_mem;
+ 
+     fprintf (fp,
+-	     "</sizes>\n<total type=\"fast\" count=\"%zu\" size=\"%zu\"/>\n"
+-	     "<total type=\"rest\" count=\"%zu\" size=\"%zu\"/>\n"
+-	     "<system type=\"current\" size=\"%zu\"/>\n"
+-	     "<system type=\"max\" size=\"%zu\"/>\n",
+-	     nfastblocks, fastavail, nblocks, avail,
+-	     ar_ptr->system_mem, ar_ptr->max_system_mem);
++             "</sizes>\n<total type=\"fast\" count=\"%zu\" size=\"%zu\"/>\n"
++             "<total type=\"rest\" count=\"%zu\" size=\"%zu\"/>\n"
++             "<system type=\"current\" size=\"%zu\"/>\n"
++             "<system type=\"max\" size=\"%zu\"/>\n",
++             nfastblocks, fastavail, nblocks, avail,
++             ar_ptr->system_mem, ar_ptr->max_system_mem);
+ 
+     if (ar_ptr != &main_arena)
+       {
+-	heap_info *heap = heap_for_ptr(top(ar_ptr));
+-	fprintf (fp,
+-		 "<aspace type=\"total\" size=\"%zu\"/>\n"
+-		 "<aspace type=\"mprotect\" size=\"%zu\"/>\n",
+-		 heap->size, heap->mprotect_size);
+-	total_aspace += heap->size;
+-	total_aspace_mprotect += heap->mprotect_size;
++        heap_info *heap = heap_for_ptr (top (ar_ptr));
++        fprintf (fp,
++                 "<aspace type=\"total\" size=\"%zu\"/>\n"
++                 "<aspace type=\"mprotect\" size=\"%zu\"/>\n",
++                 heap->size, heap->mprotect_size);
++        total_aspace += heap->size;
++        total_aspace_mprotect += heap->mprotect_size;
+       }
+     else
+       {
+-	fprintf (fp,
+-		 "<aspace type=\"total\" size=\"%zu\"/>\n"
+-		 "<aspace type=\"mprotect\" size=\"%zu\"/>\n",
+-		 ar_ptr->system_mem, ar_ptr->system_mem);
+-	total_aspace += ar_ptr->system_mem;
+-	total_aspace_mprotect += ar_ptr->system_mem;
++        fprintf (fp,
++                 "<aspace type=\"total\" size=\"%zu\"/>\n"
++                 "<aspace type=\"mprotect\" size=\"%zu\"/>\n",
++                 ar_ptr->system_mem, ar_ptr->system_mem);
++        total_aspace += ar_ptr->system_mem;
++        total_aspace_mprotect += ar_ptr->system_mem;
+       }
+ 
+     fputs ("</heap>\n", fp);
+   }
+ 
+-  if(__malloc_initialized < 0)
++  if (__malloc_initialized < 0)
+     ptmalloc_init ();
+ 
+   fputs ("<malloc version=\"1\">\n", fp);
+@@ -5168,18 +5169,18 @@ malloc_info (int options, FILE *fp)
+   while (ar_ptr != &main_arena);
+ 
+   fprintf (fp,
+-	   "<total type=\"fast\" count=\"%zu\" size=\"%zu\"/>\n"
+-	   "<total type=\"rest\" count=\"%zu\" size=\"%zu\"/>\n"
++           "<total type=\"fast\" count=\"%zu\" size=\"%zu\"/>\n"
++           "<total type=\"rest\" count=\"%zu\" size=\"%zu\"/>\n"
+ 	   "<total type=\"mmap\" count=\"%d\" size=\"%zu\"/>\n"
+-	   "<system type=\"current\" size=\"%zu\"/>\n"
+-	   "<system type=\"max\" size=\"%zu\"/>\n"
+-	   "<aspace type=\"total\" size=\"%zu\"/>\n"
+-	   "<aspace type=\"mprotect\" size=\"%zu\"/>\n"
+-	   "</malloc>\n",
+-	   total_nfastblocks, total_fastavail, total_nblocks, total_avail,
++           "<system type=\"current\" size=\"%zu\"/>\n"
++           "<system type=\"max\" size=\"%zu\"/>\n"
++           "<aspace type=\"total\" size=\"%zu\"/>\n"
++           "<aspace type=\"mprotect\" size=\"%zu\"/>\n"
++           "</malloc>\n",
++           total_nfastblocks, total_fastavail, total_nblocks, total_avail,
+ 	   mp_.n_mmaps, mp_.mmapped_mem,
+-	   total_system, total_max_system,
+-	   total_aspace, total_aspace_mprotect);
++           total_system, total_max_system,
++           total_aspace, total_aspace_mprotect);
+ 
+   return 0;
+ }
diff --git a/SOURCES/glibc-rh1065574-3.patch b/SOURCES/glibc-rh1065574-3.patch
new file mode 100644
index 0000000..aff8bf3
--- /dev/null
+++ b/SOURCES/glibc-rh1065574-3.patch
@@ -0,0 +1,276 @@
+commit 987c02692a88b8c9024cb99187434aad02c3c047
+Author: Ondřej Bílka <neleai@seznam.cz>
+Date:   Fri May 30 13:24:56 2014 +0200
+
+    Remove mi_arena nested function.
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index 5c7a27129d66e06a..c99b26d4a85e1b22 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -5023,147 +5023,143 @@ malloc_info (int options, FILE *fp)
+   size_t total_aspace = 0;
+   size_t total_aspace_mprotect = 0;
+ 
+-  void
+-  mi_arena (mstate ar_ptr)
+-  {
+-    fprintf (fp, "<heap nr=\"%d\">\n<sizes>\n", n++);
+ 
+-    size_t nblocks = 0;
+-    size_t nfastblocks = 0;
+-    size_t avail = 0;
+-    size_t fastavail = 0;
+-    struct
+-    {
+-      size_t from;
+-      size_t to;
+-      size_t total;
+-      size_t count;
+-    } sizes[NFASTBINS + NBINS - 1];
+-#define nsizes (sizeof (sizes) / sizeof (sizes[0]))
+ 
+-    mutex_lock (&ar_ptr->mutex);
++  if (__malloc_initialized < 0)
++    ptmalloc_init ();
++
++  fputs ("<malloc version=\"1\">\n", fp);
++
++  /* Iterate over all arenas currently in use.  */
++  mstate ar_ptr = &main_arena;
++  do
++    {
++      fprintf (fp, "<heap nr=\"%d\">\n<sizes>\n", n++);
+ 
+-    for (size_t i = 0; i < NFASTBINS; ++i)
++      size_t nblocks = 0;
++      size_t nfastblocks = 0;
++      size_t avail = 0;
++      size_t fastavail = 0;
++      struct
+       {
+-        mchunkptr p = fastbin (ar_ptr, i);
+-        if (p != NULL)
+-          {
+-            size_t nthissize = 0;
+-            size_t thissize = chunksize (p);
+-
+-            while (p != NULL)
+-              {
+-                ++nthissize;
+-                p = p->fd;
+-              }
+-
+-            fastavail += nthissize * thissize;
+-            nfastblocks += nthissize;
+-            sizes[i].from = thissize - (MALLOC_ALIGNMENT - 1);
+-            sizes[i].to = thissize;
+-            sizes[i].count = nthissize;
+-          }
+-        else
+-          sizes[i].from = sizes[i].to = sizes[i].count = 0;
+-
+-        sizes[i].total = sizes[i].count * sizes[i].to;
+-      }
++	size_t from;
++	size_t to;
++	size_t total;
++	size_t count;
++      } sizes[NFASTBINS + NBINS - 1];
++#define nsizes (sizeof (sizes) / sizeof (sizes[0]))
+ 
++      mutex_lock (&ar_ptr->mutex);
+ 
+-    mbinptr bin;
+-    struct malloc_chunk *r;
++      for (size_t i = 0; i < NFASTBINS; ++i)
++	{
++	  mchunkptr p = fastbin (ar_ptr, i);
++	  if (p != NULL)
++	    {
++	      size_t nthissize = 0;
++	      size_t thissize = chunksize (p);
++
++	      while (p != NULL)
++		{
++		  ++nthissize;
++		  p = p->fd;
++		}
++
++	      fastavail += nthissize * thissize;
++	      nfastblocks += nthissize;
++	      sizes[i].from = thissize - (MALLOC_ALIGNMENT - 1);
++	      sizes[i].to = thissize;
++	      sizes[i].count = nthissize;
++	    }
++	  else
++	    sizes[i].from = sizes[i].to = sizes[i].count = 0;
+ 
+-    for (size_t i = 1; i < NBINS; ++i)
+-      {
+-        bin = bin_at (ar_ptr, i);
+-        r = bin->fd;
+-        sizes[NFASTBINS - 1 + i].from = ~((size_t) 0);
+-        sizes[NFASTBINS - 1 + i].to = sizes[NFASTBINS - 1 + i].total
+-                                        = sizes[NFASTBINS - 1 + i].count = 0;
+-
+-        if (r != NULL)
+-          while (r != bin)
+-            {
+-              ++sizes[NFASTBINS - 1 + i].count;
+-              sizes[NFASTBINS - 1 + i].total += r->size;
+-              sizes[NFASTBINS - 1 + i].from
+-                = MIN (sizes[NFASTBINS - 1 + i].from, r->size);
+-              sizes[NFASTBINS - 1 + i].to = MAX (sizes[NFASTBINS - 1 + i].to,
+-                                                 r->size);
+-
+-              r = r->fd;
+-            }
+-
+-        if (sizes[NFASTBINS - 1 + i].count == 0)
+-          sizes[NFASTBINS - 1 + i].from = 0;
+-        nblocks += sizes[NFASTBINS - 1 + i].count;
+-        avail += sizes[NFASTBINS - 1 + i].total;
+-      }
++	  sizes[i].total = sizes[i].count * sizes[i].to;
++	}
+ 
+-    mutex_unlock (&ar_ptr->mutex);
+ 
+-    total_nfastblocks += nfastblocks;
+-    total_fastavail += fastavail;
++      mbinptr bin;
++      struct malloc_chunk *r;
+ 
+-    total_nblocks += nblocks;
+-    total_avail += avail;
++      for (size_t i = 1; i < NBINS; ++i)
++	{
++	  bin = bin_at (ar_ptr, i);
++	  r = bin->fd;
++	  sizes[NFASTBINS - 1 + i].from = ~((size_t) 0);
++	  sizes[NFASTBINS - 1 + i].to = sizes[NFASTBINS - 1 + i].total
++					  = sizes[NFASTBINS - 1 + i].count = 0;
++
++	  if (r != NULL)
++	    while (r != bin)
++	      {
++		++sizes[NFASTBINS - 1 + i].count;
++		sizes[NFASTBINS - 1 + i].total += r->size;
++		sizes[NFASTBINS - 1 + i].from
++		  = MIN (sizes[NFASTBINS - 1 + i].from, r->size);
++		sizes[NFASTBINS - 1 + i].to = MAX (sizes[NFASTBINS - 1 + i].to,
++						   r->size);
++
++		r = r->fd;
++	      }
+ 
+-    for (size_t i = 0; i < nsizes; ++i)
+-      if (sizes[i].count != 0 && i != NFASTBINS)
+-        fprintf (fp, "							      \
+-<size from=\"%zu\" to=\"%zu\" total=\"%zu\" count=\"%zu\"/>\n",
+-                 sizes[i].from, sizes[i].to, sizes[i].total, sizes[i].count);
++	  if (sizes[NFASTBINS - 1 + i].count == 0)
++	    sizes[NFASTBINS - 1 + i].from = 0;
++	  nblocks += sizes[NFASTBINS - 1 + i].count;
++	  avail += sizes[NFASTBINS - 1 + i].total;
++	}
+ 
+-    if (sizes[NFASTBINS].count != 0)
+-      fprintf (fp, "\
+-<unsorted from=\"%zu\" to=\"%zu\" total=\"%zu\" count=\"%zu\"/>\n",
+-               sizes[NFASTBINS].from, sizes[NFASTBINS].to,
+-               sizes[NFASTBINS].total, sizes[NFASTBINS].count);
++      mutex_unlock (&ar_ptr->mutex);
+ 
+-    total_system += ar_ptr->system_mem;
+-    total_max_system += ar_ptr->max_system_mem;
++      total_nfastblocks += nfastblocks;
++      total_fastavail += fastavail;
+ 
+-    fprintf (fp,
+-             "</sizes>\n<total type=\"fast\" count=\"%zu\" size=\"%zu\"/>\n"
+-             "<total type=\"rest\" count=\"%zu\" size=\"%zu\"/>\n"
+-             "<system type=\"current\" size=\"%zu\"/>\n"
+-             "<system type=\"max\" size=\"%zu\"/>\n",
+-             nfastblocks, fastavail, nblocks, avail,
+-             ar_ptr->system_mem, ar_ptr->max_system_mem);
++      total_nblocks += nblocks;
++      total_avail += avail;
+ 
+-    if (ar_ptr != &main_arena)
+-      {
+-        heap_info *heap = heap_for_ptr (top (ar_ptr));
+-        fprintf (fp,
+-                 "<aspace type=\"total\" size=\"%zu\"/>\n"
+-                 "<aspace type=\"mprotect\" size=\"%zu\"/>\n",
+-                 heap->size, heap->mprotect_size);
+-        total_aspace += heap->size;
+-        total_aspace_mprotect += heap->mprotect_size;
+-      }
+-    else
+-      {
+-        fprintf (fp,
+-                 "<aspace type=\"total\" size=\"%zu\"/>\n"
+-                 "<aspace type=\"mprotect\" size=\"%zu\"/>\n",
+-                 ar_ptr->system_mem, ar_ptr->system_mem);
+-        total_aspace += ar_ptr->system_mem;
+-        total_aspace_mprotect += ar_ptr->system_mem;
+-      }
++      for (size_t i = 0; i < nsizes; ++i)
++	if (sizes[i].count != 0 && i != NFASTBINS)
++	  fprintf (fp, "							      \
++  <size from=\"%zu\" to=\"%zu\" total=\"%zu\" count=\"%zu\"/>\n",
++		   sizes[i].from, sizes[i].to, sizes[i].total, sizes[i].count);
+ 
+-    fputs ("</heap>\n", fp);
+-  }
++      if (sizes[NFASTBINS].count != 0)
++	fprintf (fp, "\
++  <unsorted from=\"%zu\" to=\"%zu\" total=\"%zu\" count=\"%zu\"/>\n",
++		 sizes[NFASTBINS].from, sizes[NFASTBINS].to,
++		 sizes[NFASTBINS].total, sizes[NFASTBINS].count);
+ 
+-  if (__malloc_initialized < 0)
+-    ptmalloc_init ();
++      total_system += ar_ptr->system_mem;
++      total_max_system += ar_ptr->max_system_mem;
+ 
+-  fputs ("<malloc version=\"1\">\n", fp);
++      fprintf (fp,
++	       "</sizes>\n<total type=\"fast\" count=\"%zu\" size=\"%zu\"/>\n"
++	       "<total type=\"rest\" count=\"%zu\" size=\"%zu\"/>\n"
++	       "<system type=\"current\" size=\"%zu\"/>\n"
++	       "<system type=\"max\" size=\"%zu\"/>\n",
++	       nfastblocks, fastavail, nblocks, avail,
++	       ar_ptr->system_mem, ar_ptr->max_system_mem);
+ 
+-  /* Iterate over all arenas currently in use.  */
+-  mstate ar_ptr = &main_arena;
+-  do
+-    {
+-      mi_arena (ar_ptr);
++      if (ar_ptr != &main_arena)
++	{
++	  heap_info *heap = heap_for_ptr (top (ar_ptr));
++	  fprintf (fp,
++		   "<aspace type=\"total\" size=\"%zu\"/>\n"
++		   "<aspace type=\"mprotect\" size=\"%zu\"/>\n",
++		   heap->size, heap->mprotect_size);
++	  total_aspace += heap->size;
++	  total_aspace_mprotect += heap->mprotect_size;
++	}
++      else
++	{
++	  fprintf (fp,
++		   "<aspace type=\"total\" size=\"%zu\"/>\n"
++		   "<aspace type=\"mprotect\" size=\"%zu\"/>\n",
++		   ar_ptr->system_mem, ar_ptr->system_mem);
++	  total_aspace += ar_ptr->system_mem;
++	  total_aspace_mprotect += ar_ptr->system_mem;
++	}
++
++      fputs ("</heap>\n", fp);
+       ar_ptr = ar_ptr->next;
+     }
+   while (ar_ptr != &main_arena);
diff --git a/SOURCES/glibc-rh1065574-4.patch b/SOURCES/glibc-rh1065574-4.patch
new file mode 100644
index 0000000..c50a3c7
--- /dev/null
+++ b/SOURCES/glibc-rh1065574-4.patch
@@ -0,0 +1,38 @@
+commit c52ff39e8ee052e4a57676d65a27f09bd0a859ad
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Wed Nov 12 22:31:38 2014 +0000
+
+    Fix malloc_info namespace (bug 17570).
+    
+    malloc_info is defined in the same file as malloc and free, but is not
+    an ISO C function, so should be a weak symbol.  This patch makes it
+    so.
+    
+    Tested for x86_64 (testsuite, and that disassembly of installed shared
+    libraries is unchanged by the patch).
+    
+            [BZ #17570]
+            * malloc/malloc.c (malloc_info): Rename to __malloc_info and
+            define as weak alias of __malloc_info.
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index c99b26d4a85e1b22..18e00315c6edba4d 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -5007,7 +5007,7 @@ weak_alias (__posix_memalign, posix_memalign)
+ 
+ 
+ int
+-malloc_info (int options, FILE *fp)
++__malloc_info (int options, FILE *fp)
+ {
+   /* For now, at least.  */
+   if (options != 0)
+@@ -5180,6 +5180,7 @@ malloc_info (int options, FILE *fp)
+ 
+   return 0;
+ }
++weak_alias (__malloc_info, malloc_info)
+ 
+ 
+ strong_alias (__libc_calloc, __calloc) weak_alias (__libc_calloc, calloc)
diff --git a/SOURCES/glibc-rh1065574-5.patch b/SOURCES/glibc-rh1065574-5.patch
new file mode 100644
index 0000000..133d422
--- /dev/null
+++ b/SOURCES/glibc-rh1065574-5.patch
@@ -0,0 +1,31 @@
+This is a partial recreation of this upstream commit, restricted to
+the __malloc_info function:
+
+commit 4bf5f2224baa1590f92f7a26930928fe9f7e4b57
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Sep 6 12:49:54 2016 +0200
+
+    malloc: Automated part of conversion to __libc_lock
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index 18e00315c6edba4d..d2a5e251da4f1191 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -5049,7 +5049,7 @@ __malloc_info (int options, FILE *fp)
+       } sizes[NFASTBINS + NBINS - 1];
+ #define nsizes (sizeof (sizes) / sizeof (sizes[0]))
+ 
+-      mutex_lock (&ar_ptr->mutex);
++      __libc_lock_lock (ar_ptr->mutex);
+ 
+       for (size_t i = 0; i < NFASTBINS; ++i)
+ 	{
+@@ -5108,7 +5108,7 @@ __malloc_info (int options, FILE *fp)
+ 	  avail += sizes[NFASTBINS - 1 + i].total;
+ 	}
+ 
+-      mutex_unlock (&ar_ptr->mutex);
++      __libc_lock_unlock (ar_ptr->mutex);
+ 
+       total_nfastblocks += nfastblocks;
+       total_fastavail += fastavail;
diff --git a/SOURCES/glibc-rh1065574-6.patch b/SOURCES/glibc-rh1065574-6.patch
new file mode 100644
index 0000000..6ca5491
--- /dev/null
+++ b/SOURCES/glibc-rh1065574-6.patch
@@ -0,0 +1,175 @@
+commit 7a9368a1174cb15b9f1d6342e0e10dd90dae238d
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Wed Nov 15 11:39:01 2017 +0100
+
+    malloc: Add missing arena lock in malloc_info [BZ #22408]
+    
+    Obtain the size information while the arena lock is acquired, and only
+    print it later.
+
+Conflicts:
+	malloc/Makefile
+	  (Differences in available tests.)
+
+diff --git a/malloc/Makefile b/malloc/Makefile
+index 992cec6b03115a76..6f216f423293dc6c 100644
+--- a/malloc/Makefile
++++ b/malloc/Makefile
+@@ -31,6 +31,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
+ 	 tst-malloc-thread-fail tst-malloc-fork-deadlock \
+ 	 tst-interpose-nothread \
+ 	 tst-interpose-thread \
++	 tst-malloc_info \
+ 	 tst-interpose-static-nothread \
+ 	 tst-interpose-static-thread \
+ 	 tst-scratch_buffer \
+@@ -214,3 +215,5 @@ $(objpfx)tst-dynarray-mem: $(objpfx)tst-dynarray.out
+ tst-dynarray-fail-ENV = MALLOC_TRACE=$(objpfx)tst-dynarray-fail.mtrace
+ $(objpfx)tst-dynarray-fail-mem: $(objpfx)tst-dynarray-fail.out
+ 	$(common-objpfx)malloc/mtrace $(objpfx)tst-dynarray-fail.mtrace > $@
++
++$(objpfx)tst-malloc_info: $(shared-thread-library)
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index d2a5e251da4f1191..035f2167be7019d8 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -5108,6 +5108,15 @@ __malloc_info (int options, FILE *fp)
+ 	  avail += sizes[NFASTBINS - 1 + i].total;
+ 	}
+ 
++      size_t heap_size = 0;
++      size_t heap_mprotect_size = 0;
++      if (ar_ptr != &main_arena)
++	{
++	  heap_info *heap = heap_for_ptr (top (ar_ptr));
++	  heap_size = heap->size;
++	  heap_mprotect_size = heap->mprotect_size;
++	}
++
+       __libc_lock_unlock (ar_ptr->mutex);
+ 
+       total_nfastblocks += nfastblocks;
+@@ -5141,13 +5150,12 @@ __malloc_info (int options, FILE *fp)
+ 
+       if (ar_ptr != &main_arena)
+ 	{
+-	  heap_info *heap = heap_for_ptr (top (ar_ptr));
+ 	  fprintf (fp,
+ 		   "<aspace type=\"total\" size=\"%zu\"/>\n"
+ 		   "<aspace type=\"mprotect\" size=\"%zu\"/>\n",
+-		   heap->size, heap->mprotect_size);
+-	  total_aspace += heap->size;
+-	  total_aspace_mprotect += heap->mprotect_size;
++		   heap_size, heap_mprotect_size);
++	  total_aspace += heap_size;
++	  total_aspace_mprotect += heap_mprotect_size;
+ 	}
+       else
+ 	{
+diff --git a/malloc/tst-malloc_info.c b/malloc/tst-malloc_info.c
+new file mode 100644
+index 0000000000000000..a25b8cbeae78e710
+--- /dev/null
++++ b/malloc/tst-malloc_info.c
+@@ -0,0 +1,101 @@
++/* Smoke test for malloc_info.
++   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/>.  */
++
++/* The purpose of this test is to provide a quick way to run
++   malloc_info in a multi-threaded process.  */
++
++#include <array_length.h>
++#include <malloc.h>
++#include <stdlib.h>
++#include <support/support.h>
++#include <support/xthread.h>
++
++/* This barrier is used to have the main thread wait until the helper
++   threads have performed their allocations.  */
++static pthread_barrier_t barrier;
++
++enum
++  {
++    /* Number of threads performing allocations.  */
++    thread_count  = 4,
++
++    /* Amount of memory allocation per thread.  This should be large
++       enough to cause the allocation of multiple heaps per arena.  */
++    per_thread_allocations
++      = sizeof (void *) == 4 ? 16 * 1024 * 1024 : 128 * 1024 * 1024,
++  };
++
++static void *
++allocation_thread_function (void *closure)
++{
++  struct list
++  {
++    struct list *next;
++    long dummy[4];
++  };
++
++  struct list *head = NULL;
++  size_t allocated = 0;
++  while (allocated < per_thread_allocations)
++    {
++      struct list *new_head = xmalloc (sizeof (*new_head));
++      allocated += sizeof (*new_head);
++      new_head->next = head;
++      head = new_head;
++    }
++
++  xpthread_barrier_wait (&barrier);
++
++  /* Main thread prints first statistics here.  */
++
++  xpthread_barrier_wait (&barrier);
++
++  while (head != NULL)
++    {
++      struct list *next_head = head->next;
++      free (head);
++      head = next_head;
++    }
++
++  return NULL;
++}
++
++static int
++do_test (void)
++{
++  xpthread_barrier_init (&barrier, NULL, thread_count + 1);
++
++  pthread_t threads[thread_count];
++  for (size_t i = 0; i < array_length (threads); ++i)
++    threads[i] = xpthread_create (NULL, allocation_thread_function, NULL);
++
++  xpthread_barrier_wait (&barrier);
++  puts ("info: After allocation:");
++  malloc_info (0, stdout);
++
++  xpthread_barrier_wait (&barrier);
++  for (size_t i = 0; i < array_length (threads); ++i)
++    xpthread_join (threads[i]);
++
++  puts ("\ninfo: After deallocation:");
++  malloc_info (0, stdout);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1065574-7.patch b/SOURCES/glibc-rh1065574-7.patch
new file mode 100644
index 0000000..b3340c0
--- /dev/null
+++ b/SOURCES/glibc-rh1065574-7.patch
@@ -0,0 +1,24 @@
+commit b0f6679bcd738ea244a14acd879d974901e56c8e
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Aug 1 14:06:24 2019 +0200
+
+    malloc: Remove unwanted leading whitespace in malloc_info [BZ #24867]
+    
+    It was introduced in commit 6c8dbf00f536d78b1937b5af6f57be47fd376344
+    ("Reformat malloc to gnu style.").
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index 035f2167be7019d8..ffa0f7f00152f339 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -5127,7 +5127,7 @@ __malloc_info (int options, FILE *fp)
+ 
+       for (size_t i = 0; i < nsizes; ++i)
+ 	if (sizes[i].count != 0 && i != NFASTBINS)
+-	  fprintf (fp, "							      \
++	  fprintf (fp, "\
+   <size from=\"%zu\" to=\"%zu\" total=\"%zu\" count=\"%zu\"/>\n",
+ 		   sizes[i].from, sizes[i].to, sizes[i].total, sizes[i].count);
+ 
diff --git a/SOURCES/glibc-rh1406732-1.patch b/SOURCES/glibc-rh1406732-1.patch
new file mode 100644
index 0000000..ec449a2
--- /dev/null
+++ b/SOURCES/glibc-rh1406732-1.patch
@@ -0,0 +1,98 @@
+This patch is based on the following upstream commit:
+
+commit 2d6ab5df3b675e96ee587ae6a8c2ce004c6b1ba9
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Mar 2 14:44:28 2017 +0100
+
+    Document and fix --enable-bind-now [BZ #21015]
+
+diff --git a/INSTALL b/INSTALL
+index 82b29f5d8746f929..230be71b9d0821c2 100644
+--- a/INSTALL
++++ b/INSTALL
+@@ -143,6 +143,12 @@ will be used, and CFLAGS sets optimization options for the compiler.
+ `--enable-lock-elision=yes'
+      Enable lock elision for pthread mutexes by default.
+ 
++'--enable-bind-now'
++     Disable lazy binding for installed shared objects.  This provides
++     additional security hardening because it enables full RELRO and a
++     read-only global offset table (GOT), at the cost of slightly
++     increased program load times.
++
+ `--disable-werror'
+      By default, the GNU C Library is built with `-Werror'.  If you wish
+      to build without this option (for example, if building with a newer
+diff --git a/Makeconfig b/Makeconfig
+index f8313c9774d47522..1ad9b6f0d494c027 100644
+--- a/Makeconfig
++++ b/Makeconfig
+@@ -384,6 +384,13 @@ LDFLAGS.so += $(hashstyle-LDFLAGS)
+ LDFLAGS-rtld += $(hashstyle-LDFLAGS)
+ endif
+ 
++# If lazy relocations are disabled, add the -z now flag.  Use
++# LDFLAGS-lib.so instead of LDFLAGS.so, to avoid adding the flag to
++# test modules.
++ifeq ($(bind-now),yes)
++LDFLAGS-lib.so += -Wl,-z,now
++endif
++
+ # Additional libraries to link into every test.
+ link-extra-libs-tests = $(libsupport)
+ 
+diff --git a/Makerules b/Makerules
+index 9bd7d603fc28a4de..50fe7e48187f0e68 100644
+--- a/Makerules
++++ b/Makerules
+@@ -477,7 +477,7 @@ $(LINK.o) -shared $(static-libgcc) -Wl,-O1 $(sysdep-LDFLAGS) \
+ 	  $(extra-B-$(@F:lib%.so=%).so) -B$(csu-objpfx) \
+ 	  $(extra-B-$(@F:lib%.so=%).so) $(load-map-file) \
+ 	  -Wl,-soname=lib$(libprefix)$(@F:lib%.so=%).so$($(@F)-version) \
+-	  $(LDFLAGS.so) $(LDFLAGS-$(@F:lib%.so=%).so) \
++	  $(LDFLAGS.so) $(LDFLAGS-lib.so) $(LDFLAGS-$(@F:lib%.so=%).so) \
+ 	  -L$(subst :, -L,$(rpath-link)) -Wl,-rpath-link=$(rpath-link)
+ endef
+ 
+@@ -938,7 +938,8 @@ $(common-objpfx)format.lds: $(..)scripts/output-format.sed \
+ ifneq (unknown,$(output-format))
+ 	echo > $@.new 'OUTPUT_FORMAT($(output-format))'
+ else
+-	$(LINK.o) -shared $(sysdep-LDFLAGS) $(config-LDFLAGS) $(LDFLAGS.so) \
++	$(LINK.o) -shared $(sysdep-LDFLAGS) $(config-LDFLAGS) \
++		  $(LDFLAGS.so) $(LDFLAGS-lib.so) \
+ 		  -x c /dev/null -o $@.so -Wl,--verbose -v 2>&1 \
+ 	| sed -n -f $< > $@.new
+ 	test -s $@.new
+diff --git a/iconvdata/Makefile b/iconvdata/Makefile
+index 7930dcd49d77c818..ddb2dc6a3c6500c8 100644
+--- a/iconvdata/Makefile
++++ b/iconvdata/Makefile
+@@ -65,6 +65,10 @@ modules.so := $(addsuffix .so, $(modules))
+ 
+ include ../Makeconfig
+ 
++ifeq ($(bind-now),yes)
++LDFLAGS.so += -Wl,-z,now
++endif
++
+ ifeq (yes,$(build-shared))
+ tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
+ 	tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \
+diff --git a/manual/install.texi b/manual/install.texi
+index 3799cee621ddc4f9..47d832cc59bc695e 100644
+--- a/manual/install.texi
++++ b/manual/install.texi
+@@ -160,6 +160,12 @@ so that they can be invoked directly.
+ @item --enable-lock-elision=yes
+ Enable lock elision for pthread mutexes by default.
+ 
++@item --enable-bind-now
++Disable lazy binding for installed shared objects.  This provides
++additional security hardening because it enables full RELRO and a
++read-only global offset table (GOT), at the cost of slightly increased
++program load times.
++
+ @pindex pt_chown
+ @findex grantpt
+ @item --enable-pt_chown
diff --git a/SOURCES/glibc-rh1406732-2.patch b/SOURCES/glibc-rh1406732-2.patch
new file mode 100644
index 0000000..534195b
--- /dev/null
+++ b/SOURCES/glibc-rh1406732-2.patch
@@ -0,0 +1,96 @@
+This patch is based on the following upstream commit:
+
+commit 94a4e9e4f401ffe829a992820439977ead0a0ce7
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Apr 25 10:41:43 2019 +0200
+
+    Extend BIND_NOW to installed programs with --enable-bind-now
+    
+    Commit 2d6ab5df3b675e96ee587ae6a8c2ce004c6b1ba9 ("Document and fix
+    --enable-bind-now [BZ #21015]") extended BIND_NOW to all installed
+    shared objects.  This change also covers installed programs.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+diff --git a/INSTALL b/INSTALL
+index 230be71b9d0821c2..277ea46d9c25a9ae 100644
+--- a/INSTALL
++++ b/INSTALL
+@@ -144,10 +144,10 @@ will be used, and CFLAGS sets optimization options for the compiler.
+      Enable lock elision for pthread mutexes by default.
+ 
+ '--enable-bind-now'
+-     Disable lazy binding for installed shared objects.  This provides
+-     additional security hardening because it enables full RELRO and a
+-     read-only global offset table (GOT), at the cost of slightly
+-     increased program load times.
++     Disable lazy binding for installed shared objects and programs.
++     This provides additional security hardening because it enables full
++     RELRO and a read-only global offset table (GOT), at the cost of
++     slightly increased program load times.
+ 
+ `--disable-werror'
+      By default, the GNU C Library is built with `-Werror'.  If you wish
+diff --git a/Makeconfig b/Makeconfig
+index 1ad9b6f0d494c027..bc13b39c2ea5708a 100644
+--- a/Makeconfig
++++ b/Makeconfig
+@@ -389,6 +389,8 @@ endif
+ # test modules.
+ ifeq ($(bind-now),yes)
+ LDFLAGS-lib.so += -Wl,-z,now
++# Extra flags for dynamically linked non-test main programs.
++link-extra-flags += -Wl,-z,now
+ endif
+ 
+ # Additional libraries to link into every test.
+@@ -405,7 +407,8 @@ ifndef +link-pie
+ 						    S$(start-installed-name))\
+ 			  $(+preinit) $(link-extra-libs) \
+ 			  $(common-objpfx)libc% $(+postinit),$^) \
+-	     $(link-extra-libs) $(link-libc) $(+postctorS) $(+postinit)
++	     $(link-extra-libs) $(link-extra-flags) $(link-libc) \
++	     $(+postctorS) $(+postinit)
+ endif
+ # Command for statically linking programs with the C library.
+ ifndef +link-static
+@@ -419,8 +422,8 @@ ifndef +link-static
+ 			   $(common-objpfx)libc% $(+postinit),$^) \
+ 	      $(link-extra-libs-static)
+ +link-static-after-libc = $(+postctorT) $(+postinit)
+-+link-static = $(+link-static-before-libc) $(link-libc-static) \
+-	       $(+link-static-after-libc)
+++link-static = $(+link-static-before-libc) $(link-extra-flags) \
++	       $(link-libc-static) $(+link-static-after-libc)
+ +link-static-tests = $(+link-static-before-libc) $(link-libc-static-tests) \
+ 		     $(+link-static-after-libc)
+ endif
+@@ -438,7 +441,8 @@ ifeq (yes,$(build-shared))
+ 			   $(common-objpfx)libc% $(+postinit),$^) \
+ 	      $(link-extra-libs)
+ +link-after-libc = $(+postctor) $(+postinit)
+-+link = $(+link-before-libc) $(link-libc) $(+link-after-libc)
+++link = $(+link-before-libc) $(link-extra-flags) $(link-libc) \
++	$(+link-after-libc)
+ +link-tests = $(+link-before-libc) $(link-libc-tests) $(+link-after-libc)
+ else
+ +link = $(+link-static)
+diff --git a/manual/install.texi b/manual/install.texi
+index 47d832cc59bc695e..5cacd974ce093ce9 100644
+--- a/manual/install.texi
++++ b/manual/install.texi
+@@ -161,10 +161,10 @@ so that they can be invoked directly.
+ Enable lock elision for pthread mutexes by default.
+ 
+ @item --enable-bind-now
+-Disable lazy binding for installed shared objects.  This provides
+-additional security hardening because it enables full RELRO and a
+-read-only global offset table (GOT), at the cost of slightly increased
+-program load times.
++Disable lazy binding for installed shared objects and programs.  This
++provides additional security hardening because it enables full RELRO
++and a read-only global offset table (GOT), at the cost of slightly
++increased program load times.
+ 
+ @pindex pt_chown
+ @findex grantpt
diff --git a/SOURCES/glibc-rh1406732-3.patch b/SOURCES/glibc-rh1406732-3.patch
new file mode 100644
index 0000000..5084bd2
--- /dev/null
+++ b/SOURCES/glibc-rh1406732-3.patch
@@ -0,0 +1,44 @@
+This patch is based on the following upstream commit:
+
+commit b5ffdc48c20ae865b197b67e5a9068a528fbc198
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Apr 25 10:41:52 2019 +0200
+
+    benchtests: Enable BIND_NOW if configured with --enable-bind-now
+    
+    Benchmarks should reflect distribution build policies, so it makes
+    sense to honor the BIND_NOW configuration for them.
+    
+    This commit keeps using $(+link-tests), so that the benchmarks are
+    linked according to the --enable-hardcoded-path-in-tests configure
+    option.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+diff --git a/benchtests/Makefile b/benchtests/Makefile
+index 911b6df04cc323ac..bb02d26e1847d424 100644
+--- a/benchtests/Makefile
++++ b/benchtests/Makefile
+@@ -153,12 +153,20 @@ bench-func: $(binaries-bench)
+ 	$(PYTHON) scripts/validate_benchout.py $(objpfx)bench.out \
+ 		scripts/benchout.schema.json
+ 
+-$(timing-type) $(binaries-bench) $(binaries-benchset) \
+-	$(binaries-bench-malloc): %: %.o $(objpfx)json-lib.o \
++ifeq ($(bind-now),yes)
++link-bench-bind-now = -Wl,-z,now
++endif
++
++bench-link-targets = $(timing-type) $(binaries-bench) $(binaries-benchset) \
++	$(binaries-bench-malloc)
++
++$(bench-link-targets): %: %.o $(objpfx)json-lib.o \
+   $(sort $(filter $(common-objpfx)lib%,$(link-libc))) \
+   $(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit)
+ 	$(+link)
+ 
++$(bench-link-targets): LDFLAGS += $(link-bench-bind-now)
++
+ $(objpfx)bench-%.c: %-inputs $(bench-deps)
+ 	{ if [ -n "$($*-INCLUDE)" ]; then \
+ 	  cat $($*-INCLUDE); \
diff --git a/SOURCES/glibc-rh1406732-4.patch b/SOURCES/glibc-rh1406732-4.patch
new file mode 100644
index 0000000..83dedcd
--- /dev/null
+++ b/SOURCES/glibc-rh1406732-4.patch
@@ -0,0 +1,25 @@
+commit c57afec0a9b318bb691e0f5fa4e9681cf30df7a4
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Apr 26 07:16:56 2019 +0200
+
+    elf: Link sotruss-lib.so with BIND_NOW for --enable-bind-now
+    
+    The audit module itself can be linked with BIND_NOW; it does not
+    affect its functionality.
+    
+    This should complete the leftovers from commit
+    2d6ab5df3b675e96ee587ae6a8c2ce004c6b1ba9 ("Document and fix
+    --enable-bind-now [BZ #21015]").
+
+diff --git a/elf/Makefile b/elf/Makefile
+index 2b2662d5cf96c437..cfd039fc9dfb0be7 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -103,6 +103,7 @@ install-others += $(inst_auditdir)/sotruss-lib.so
+ install-bin-script += sotruss
+ generated += sotruss
+ libof-sotruss-lib = extramodules
++LDFLAGS-sotruss-lib.so += $(z-now-$(bind-now))
+ $(objpfx)sotruss-lib.so: $(objpfx)sotruss-lib.os
+ 	$(build-module-asneeded)
+ $(objpfx)sotruss-lib.so: $(common-objpfx)libc.so $(objpfx)ld.so \
diff --git a/SOURCES/glibc-rh1406732-5.patch b/SOURCES/glibc-rh1406732-5.patch
new file mode 100644
index 0000000..e917c00
--- /dev/null
+++ b/SOURCES/glibc-rh1406732-5.patch
@@ -0,0 +1,26 @@
+This patch enables building memusagestat with BIND_NOW enabled.
+
+Upstream, this change was part of the following commit...
+
+commit f9b645b4b0a10c43753296ce3fa40053fa44606a
+Author: Mike Frysinger <vapier@gentoo.org>
+Date:   Wed Apr 24 13:32:22 2019 +0200
+
+    memusagestat: use local glibc when linking [BZ #18465]
+
+...but since that commit cannot be backported to RHEL-7, this patch
+adds only the BIND_NOW linker flag at the appropriate place instead.
+
+diff --git a/malloc/Makefile b/malloc/Makefile
+index 476208cf43d211c9..992cec6b03115a76 100644
+--- a/malloc/Makefile
++++ b/malloc/Makefile
+@@ -142,7 +142,7 @@ lib := memusagestat
+ include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left))
+ 
+ $(objpfx)memusagestat: $(memusagestat-modules:%=$(objpfx)%.o)
+-	$(LINK.o) -o $@ $^ $(libgd-LDFLAGS) -lgd -lpng -lz -lm
++	$(LINK.o) -Wl,-z,now -o $@ $^ $(libgd-LDFLAGS) -lgd -lpng -lz -lm
+ 
+ include ../Rules
+ 
diff --git a/SOURCES/glibc-rh1406732-6.patch b/SOURCES/glibc-rh1406732-6.patch
new file mode 100644
index 0000000..e6a9369
--- /dev/null
+++ b/SOURCES/glibc-rh1406732-6.patch
@@ -0,0 +1,43 @@
+This is a downstream only patch for RHEL 7.
+
+See bug 1790475 for the history behind --disable-bind-now for ppc64.
+In summary: COPY relocations and BIND_NOW are incompatible on ppc64.
+The solution is to globally disable BIND_NOW hardening on ppc64 with
+--disable-bind-now and then use a downstream-only patch to partially
+enable BIND_NOW hardening for ppc64 to the level of hardening that
+works given the toolchain.
+
+diff --git a/sysdeps/powerpc/Makefile b/sysdeps/powerpc/Makefile
+index b11edd77bd2c22d4..47a9e7bcf66a8531 100644
+--- a/sysdeps/powerpc/Makefile
++++ b/sysdeps/powerpc/Makefile
+@@ -1,3 +1,29 @@
++################################################################################
++# Only enabled if we are not building for ppc64le.
++ifeq (,$(filter %le,$(config-machine)))
++# Enable bind-now behaviour by default for POWER. This is a downstream specific
++# change that is required due to a toolchain limitation in handling COPY
++# relocations and BIND_NOW (see rhbz#1790475).
++LDCFLAGS-c.so += -Wl,-z,now
++# Likewise. Take care that this is carefully selected to turn BIND_NOW back on
++# for ld.so without turning it back on for libpthread.so which has the
++# problematic OPD that generates a COPY relocation. Enable these only for the
++# elf subdir which is also used to build libc.so.6. This avoids enabling
++# BIND_NOW for libpthread.
++ifeq ($(subdir),elf)
++z-now-no = -Wl,-z,now
++LDFLAGS-lib.so += -Wl,-z,now
++link-extra-flags += -Wl,-z,now
++endif
++# Likewise. Take care that this is carefully selected to turn BIND_NOW
++# back on for iconv modules to ensure the data-only DSOs have consistently the
++# correct expected flags for DSOs (even if they don't really need them).
++ifeq ($(subdir),iconvdata)
++LDFLAGS.so += -Wl,-z,now
++endif
++endif
++################################################################################
++
+ ifeq ($(subdir),string)
+ CFLAGS-memcmp.c += -Wno-uninitialized
+ endif
diff --git a/SOURCES/glibc-rh1414263.patch b/SOURCES/glibc-rh1414263.patch
new file mode 100644
index 0000000..a121956
--- /dev/null
+++ b/SOURCES/glibc-rh1414263.patch
@@ -0,0 +1,423 @@
+commit 799c8d6905433ad56f26ccab4855b36f1d1ddbfc
+Author: Mike FABIAN <mfabian@redhat.com>
+Date:   Thu Sep 7 15:28:28 2017 +0200
+
+    Add new codepage charmaps/IBM858 [BZ #21084]
+    
+    This code page is identical to code page 850 except that X'D5'
+    has been changed from LI61 (dotless i) to SC20 (euro symbol).
+    
+    The code points from /x01 to /x1f in the /localedata/charmaps/IBM858
+    file have the same mapping as those in localedata/charmaps/ANSI_X3.4-1968.
+    That means they disagree with with
+    
+    ftp://ftp.software.ibm.com/software/globalization/gcoc/attachments/CP00858.txt
+    
+    in that range.
+    For example, localedata/charmaps/IBM858 and localedata/charmaps/ANSI_X3.4-1968 have:
+    
+       “<U0001>     /x01         START OF HEADING (SOH)”
+    
+    whereas CP00858.txt has:
+    
+       “01 SS000000        Smiling Face”
+    
+    That means that CP00858.txt is not really ASCII-compatible and to make
+    it ASCII-compatible we deviate fro CP00858.txt in the code points from /x01
+    to /x1f.
+    
+            [BZ #21084]
+            * benchtests/strcoll-inputs/filelist#en_US.UTF-8: Add IBM858 and ibm858.c.
+            * iconvdata/Makefile: Add IBM858.
+            * iconvdata/gconv-modules: Add IBM858.
+            * iconvdata/ibm858.c: New file.
+            * iconvdata/tst-tables.sh: Add IBM858
+            * localedata/charmaps/IBM858: New file.
+
+# Conflicts:
+#	benchtests/strcoll-inputs/filelist#en_US.UTF-8
+
+diff --git a/iconvdata/Makefile b/iconvdata/Makefile
+index c4e6c510d7abc055..7930dcd49d77c818 100644
+--- a/iconvdata/Makefile
++++ b/iconvdata/Makefile
+@@ -34,9 +34,9 @@ modules	:= ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5		 \
+ 	   IBM874 CP737 CP775 ISO-2022-KR HP-TURKISH8 HP-THAI8 HP-GREEK8 \
+ 	   KOI8-R LATIN-GREEK LATIN-GREEK-1 IBM256 IBM273 IBM277 IBM278	 \
+ 	   IBM280 IBM281 IBM284 IBM285 IBM290 IBM297 IBM420 IBM424	 \
+-	   IBM437 IBM850 IBM851 IBM852 IBM855 IBM857 IBM860 IBM861	 \
+-	   IBM862 IBM863 IBM864 IBM865 IBM868 IBM869 IBM875 IBM880	 \
+-	   IBM866 CP1258 IBM922 IBM1124 IBM1129 IBM932 IBM943		 \
++	   IBM437 IBM850 IBM851 IBM852 IBM855 IBM857 IBM858 IBM860	 \
++	   IBM861 IBM862 IBM863 IBM864 IBM865 IBM868 IBM869 IBM875	 \
++	   IBM880 IBM866 CP1258 IBM922 IBM1124 IBM1129 IBM932 IBM943	 \
+ 	   IBM856 IBM930 IBM933 IBM935 IBM937 IBM939 IBM1046		 \
+ 	   IBM1132 IBM1133 IBM1160 IBM1161 IBM1162 IBM1163 IBM1164	 \
+ 	   IBM918 IBM1004 IBM1026 CP1125 CP1250 CP1251 CP1252 CP1253	 \
+@@ -148,11 +148,11 @@ gen-8bit-modules := iso8859-2 iso8859-3 iso8859-4 iso8859-6 iso8859-9 koi-8 \
+ gen-8bit-gap-modules := koi8-r latin-greek latin-greek-1 ibm256 ibm273	   \
+ 			ibm277 ibm278 ibm280 ibm281 ibm284 ibm285 ibm290   \
+ 			ibm297 ibm420 ibm424 ibm437 ibm850 ibm851 ibm852   \
+-			ibm855 ibm857 ibm860 ibm861 ibm862 ibm863 ibm864   \
+-			ibm865 ibm868 ibm869 ibm875 ibm880 ibm918 ibm1004  \
+-			ibm1026 cp1125 cp1250 cp1251 cp1252 cp1253 cp1254  \
+-			cp1256 cp1257 ibm866 iso8859-5 iso8859-7 iso8859-8 \
+-			iso8859-10 macintosh iec_p27-1 asmo_449		   \
++			ibm855 ibm857 ibm858 ibm860 ibm861 ibm862 ibm863   \
++			ibm864 ibm865 ibm868 ibm869 ibm875 ibm880 ibm918   \
++			ibm1004 ibm1026 cp1125 cp1250 cp1251 cp1252 cp1253 \
++			cp1254 cp1256 cp1257 ibm866 iso8859-5 iso8859-7    \
++			iso8859-8 iso8859-10 macintosh iec_p27-1 asmo_449  \
+ 			csn_369103 cwi dec-mcs ecma-cyrillic gost_19768-74 \
+ 			greek-ccitt greek7 greek7-old inis inis-8	   \
+ 			inis-cyrillic iso_2033 iso_5427 iso_5427-ext	   \
+diff --git a/iconvdata/gconv-modules b/iconvdata/gconv-modules
+index d640ea4eadab2382..039b1b5b385619a8 100644
+--- a/iconvdata/gconv-modules
++++ b/iconvdata/gconv-modules
+@@ -743,6 +743,13 @@ alias	OSF10020352//		IBM850//
+ module	IBM850//		INTERNAL		IBM850		1
+ module	INTERNAL		IBM850//		IBM850		1
+ 
++#	from			to			module		cost
++alias	CP858//			IBM858//
++alias	858//			IBM858//
++alias	CSPC858MULTILINGUAL//	IBM858//
++module	IBM858//		INTERNAL		IBM858		1
++module	INTERNAL		IBM858//		IBM858		1
++
+ #	from			to			module		cost
+ alias	CP851//			IBM851//
+ alias	851//			IBM851//
+diff --git a/iconvdata/ibm858.c b/iconvdata/ibm858.c
+new file mode 100644
+index 0000000000000000..ed2a48e3cf79e2b9
+--- /dev/null
++++ b/iconvdata/ibm858.c
+@@ -0,0 +1,27 @@
++/* Conversion from and to IBM858.
++   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/>.  */
++
++#include <stdint.h>
++
++/* Get the conversion table.  */
++#define TABLES <ibm858.h>
++
++#define CHARSET_NAME	"IBM858//"
++#define HAS_HOLES	1	/* Not all 256 character are defined.  */
++
++#include <8bit-gap.c>
+diff --git a/iconvdata/tst-tables.sh b/iconvdata/tst-tables.sh
+index 77d9d182c7dc2205..2ee6cf0d0b25961b 100755
+--- a/iconvdata/tst-tables.sh
++++ b/iconvdata/tst-tables.sh
+@@ -125,6 +125,7 @@ cat <<EOF |
+   IBM855
+   IBM856
+   IBM857
++  IBM858
+   IBM860
+   IBM861
+   IBM862
+diff --git a/localedata/charmaps/IBM858 b/localedata/charmaps/IBM858
+new file mode 100644
+index 0000000000000000..d8600e2456c87b48
+--- /dev/null
++++ b/localedata/charmaps/IBM858
+@@ -0,0 +1,281 @@
++<code_set_name> IBM858
++<comment_char> %
++<escape_char> /
++% version: 1.0
++%  source: ftp://ftp.software.ibm.com/software/globalization/gcoc/attachments/CP00858.txt, 1998
++
++%  source: UNICODE 1.0
++
++% This code page is identical to code page 850 except that X'D5'
++% has been changed from LI61 (dotless i) to SC20 (euro symbol).
++
++% The code points from /x01 to /x1f in this file have the same mapping
++% as those  in ANSI_X3.4-1968. That means they disagree with with CP00858.txt
++% in that range. For example, this file and ANSI_X3.4-1968 have:
++%    “<U0001>     /x01         START OF HEADING (SOH)”
++% whereas CP00858.txt has:
++%    “01 SS000000        Smiling Face”
++% That means that CP00858.txt is not really ASCII-compatible and to make
++% it ASCII-compatible we deviate fro CP00858.txt in the code points from /x01
++% to /x1f.
++
++% alias CP858
++% alias 858
++CHARMAP
++<U0000>     /x00         NULL (NUL)
++<U0001>     /x01         START OF HEADING (SOH)
++<U0002>     /x02         START OF TEXT (STX)
++<U0003>     /x03         END OF TEXT (ETX)
++<U0004>     /x04         END OF TRANSMISSION (EOT)
++<U0005>     /x05         ENQUIRY (ENQ)
++<U0006>     /x06         ACKNOWLEDGE (ACK)
++<U0007>     /x07         BELL (BEL)
++<U0008>     /x08         BACKSPACE (BS)
++<U0009>     /x09         CHARACTER TABULATION (HT)
++<U000A>     /x0a         LINE FEED (LF)
++<U000B>     /x0b         LINE TABULATION (VT)
++<U000C>     /x0c         FORM FEED (FF)
++<U000D>     /x0d         CARRIAGE RETURN (CR)
++<U000E>     /x0e         SHIFT OUT (SO)
++<U000F>     /x0f         SHIFT IN (SI)
++<U0010>     /x10         DATALINK ESCAPE (DLE)
++<U0011>     /x11         DEVICE CONTROL ONE (DC1)
++<U0012>     /x12         DEVICE CONTROL TWO (DC2)
++<U0013>     /x13         DEVICE CONTROL THREE (DC3)
++<U0014>     /x14         DEVICE CONTROL FOUR (DC4)
++<U0015>     /x15         NEGATIVE ACKNOWLEDGE (NAK)
++<U0016>     /x16         SYNCHRONOUS IDLE (SYN)
++<U0017>     /x17         END OF TRANSMISSION BLOCK (ETB)
++<U0018>     /x18         CANCEL (CAN)
++<U0019>     /x19         END OF MEDIUM (EM)
++<U001A>     /x1a         SUBSTITUTE (SUB)
++<U001B>     /x1b         ESCAPE (ESC)
++<U001C>     /x1c         FILE SEPARATOR (IS4)
++<U001D>     /x1d         GROUP SEPARATOR (IS3)
++<U001E>     /x1e         RECORD SEPARATOR (IS2)
++<U001F>     /x1f         UNIT SEPARATOR (IS1)
++<U0020>     /x20         SPACE
++<U0021>     /x21         EXCLAMATION MARK
++<U0022>     /x22         QUOTATION MARK
++<U0023>     /x23         NUMBER SIGN
++<U0024>     /x24         DOLLAR SIGN
++<U0025>     /x25         PERCENT SIGN
++<U0026>     /x26         AMPERSAND
++<U0027>     /x27         APOSTROPHE
++<U0028>     /x28         LEFT PARENTHESIS
++<U0029>     /x29         RIGHT PARENTHESIS
++<U002A>     /x2a         ASTERISK
++<U002B>     /x2b         PLUS SIGN
++<U002C>     /x2c         COMMA
++<U002D>     /x2d         HYPHEN-MINUS
++<U002E>     /x2e         FULL STOP
++<U002F>     /x2f         SOLIDUS
++<U0030>     /x30         DIGIT ZERO
++<U0031>     /x31         DIGIT ONE
++<U0032>     /x32         DIGIT TWO
++<U0033>     /x33         DIGIT THREE
++<U0034>     /x34         DIGIT FOUR
++<U0035>     /x35         DIGIT FIVE
++<U0036>     /x36         DIGIT SIX
++<U0037>     /x37         DIGIT SEVEN
++<U0038>     /x38         DIGIT EIGHT
++<U0039>     /x39         DIGIT NINE
++<U003A>     /x3a         COLON
++<U003B>     /x3b         SEMICOLON
++<U003C>     /x3c         LESS-THAN SIGN
++<U003D>     /x3d         EQUALS SIGN
++<U003E>     /x3e         GREATER-THAN SIGN
++<U003F>     /x3f         QUESTION MARK
++<U0040>     /x40         COMMERCIAL AT
++<U0041>     /x41         LATIN CAPITAL LETTER A
++<U0042>     /x42         LATIN CAPITAL LETTER B
++<U0043>     /x43         LATIN CAPITAL LETTER C
++<U0044>     /x44         LATIN CAPITAL LETTER D
++<U0045>     /x45         LATIN CAPITAL LETTER E
++<U0046>     /x46         LATIN CAPITAL LETTER F
++<U0047>     /x47         LATIN CAPITAL LETTER G
++<U0048>     /x48         LATIN CAPITAL LETTER H
++<U0049>     /x49         LATIN CAPITAL LETTER I
++<U004A>     /x4a         LATIN CAPITAL LETTER J
++<U004B>     /x4b         LATIN CAPITAL LETTER K
++<U004C>     /x4c         LATIN CAPITAL LETTER L
++<U004D>     /x4d         LATIN CAPITAL LETTER M
++<U004E>     /x4e         LATIN CAPITAL LETTER N
++<U004F>     /x4f         LATIN CAPITAL LETTER O
++<U0050>     /x50         LATIN CAPITAL LETTER P
++<U0051>     /x51         LATIN CAPITAL LETTER Q
++<U0052>     /x52         LATIN CAPITAL LETTER R
++<U0053>     /x53         LATIN CAPITAL LETTER S
++<U0054>     /x54         LATIN CAPITAL LETTER T
++<U0055>     /x55         LATIN CAPITAL LETTER U
++<U0056>     /x56         LATIN CAPITAL LETTER V
++<U0057>     /x57         LATIN CAPITAL LETTER W
++<U0058>     /x58         LATIN CAPITAL LETTER X
++<U0059>     /x59         LATIN CAPITAL LETTER Y
++<U005A>     /x5a         LATIN CAPITAL LETTER Z
++<U005B>     /x5b         LEFT SQUARE BRACKET
++<U005C>     /x5c         REVERSE SOLIDUS
++<U005D>     /x5d         RIGHT SQUARE BRACKET
++<U005E>     /x5e         CIRCUMFLEX ACCENT
++<U005F>     /x5f         LOW LINE
++<U0060>     /x60         GRAVE ACCENT
++<U0061>     /x61         LATIN SMALL LETTER A
++<U0062>     /x62         LATIN SMALL LETTER B
++<U0063>     /x63         LATIN SMALL LETTER C
++<U0064>     /x64         LATIN SMALL LETTER D
++<U0065>     /x65         LATIN SMALL LETTER E
++<U0066>     /x66         LATIN SMALL LETTER F
++<U0067>     /x67         LATIN SMALL LETTER G
++<U0068>     /x68         LATIN SMALL LETTER H
++<U0069>     /x69         LATIN SMALL LETTER I
++<U006A>     /x6a         LATIN SMALL LETTER J
++<U006B>     /x6b         LATIN SMALL LETTER K
++<U006C>     /x6c         LATIN SMALL LETTER L
++<U006D>     /x6d         LATIN SMALL LETTER M
++<U006E>     /x6e         LATIN SMALL LETTER N
++<U006F>     /x6f         LATIN SMALL LETTER O
++<U0070>     /x70         LATIN SMALL LETTER P
++<U0071>     /x71         LATIN SMALL LETTER Q
++<U0072>     /x72         LATIN SMALL LETTER R
++<U0073>     /x73         LATIN SMALL LETTER S
++<U0074>     /x74         LATIN SMALL LETTER T
++<U0075>     /x75         LATIN SMALL LETTER U
++<U0076>     /x76         LATIN SMALL LETTER V
++<U0077>     /x77         LATIN SMALL LETTER W
++<U0078>     /x78         LATIN SMALL LETTER X
++<U0079>     /x79         LATIN SMALL LETTER Y
++<U007A>     /x7a         LATIN SMALL LETTER Z
++<U007B>     /x7b         LEFT CURLY BRACKET
++<U007C>     /x7c         VERTICAL LINE
++<U007D>     /x7d         RIGHT CURLY BRACKET
++<U007E>     /x7e         TILDE
++<U007F>     /x7f         DELETE (DEL)
++<U00C7>     /x80         LATIN CAPITAL LETTER C WITH CEDILLA
++<U00FC>     /x81         LATIN SMALL LETTER U WITH DIAERESIS
++<U00E9>     /x82         LATIN SMALL LETTER E WITH ACUTE
++<U00E2>     /x83         LATIN SMALL LETTER A WITH CIRCUMFLEX
++<U00E4>     /x84         LATIN SMALL LETTER A WITH DIAERESIS
++<U00E0>     /x85         LATIN SMALL LETTER A WITH GRAVE
++<U00E5>     /x86         LATIN SMALL LETTER A WITH RING ABOVE
++<U00E7>     /x87         LATIN SMALL LETTER C WITH CEDILLA
++<U00EA>     /x88         LATIN SMALL LETTER E WITH CIRCUMFLEX
++<U00EB>     /x89         LATIN SMALL LETTER E WITH DIAERESIS
++<U00E8>     /x8a         LATIN SMALL LETTER E WITH GRAVE
++<U00EF>     /x8b         LATIN SMALL LETTER I WITH DIAERESIS
++<U00EE>     /x8c         LATIN SMALL LETTER I WITH CIRCUMFLEX
++<U00EC>     /x8d         LATIN SMALL LETTER I WITH GRAVE
++<U00C4>     /x8e         LATIN CAPITAL LETTER A WITH DIAERESIS
++<U00C5>     /x8f         LATIN CAPITAL LETTER A WITH RING ABOVE
++<U00C9>     /x90         LATIN CAPITAL LETTER E WITH ACUTE
++<U00E6>     /x91         LATIN SMALL LETTER AE
++<U00C6>     /x92         LATIN CAPITAL LETTER AE
++<U00F4>     /x93         LATIN SMALL LETTER O WITH CIRCUMFLEX
++<U00F6>     /x94         LATIN SMALL LETTER O WITH DIAERESIS
++<U00F2>     /x95         LATIN SMALL LETTER O WITH GRAVE
++<U00FB>     /x96         LATIN SMALL LETTER U WITH CIRCUMFLEX
++<U00F9>     /x97         LATIN SMALL LETTER U WITH GRAVE
++<U00FF>     /x98         LATIN SMALL LETTER Y WITH DIAERESIS
++<U00D6>     /x99         LATIN CAPITAL LETTER O WITH DIAERESIS
++<U00DC>     /x9a         LATIN CAPITAL LETTER U WITH DIAERESIS
++<U00F8>     /x9b         LATIN SMALL LETTER O WITH STROKE
++<U00A3>     /x9c         POUND SIGN
++<U00D8>     /x9d         LATIN CAPITAL LETTER O WITH STROKE
++<U00D7>     /x9e         MULTIPLICATION SIGN
++<U0192>     /x9f         LATIN SMALL LETTER F WITH HOOK
++<U00E1>     /xa0         LATIN SMALL LETTER A WITH ACUTE
++<U00ED>     /xa1         LATIN SMALL LETTER I WITH ACUTE
++<U00F3>     /xa2         LATIN SMALL LETTER O WITH ACUTE
++<U00FA>     /xa3         LATIN SMALL LETTER U WITH ACUTE
++<U00F1>     /xa4         LATIN SMALL LETTER N WITH TILDE
++<U00D1>     /xa5         LATIN CAPITAL LETTER N WITH TILDE
++<U00AA>     /xa6         FEMININE ORDINAL INDICATOR
++<U00BA>     /xa7         MASCULINE ORDINAL INDICATOR
++<U00BF>     /xa8         INVERTED QUESTION MARK
++<U00AE>     /xa9         REGISTERED SIGN
++<U00AC>     /xaa         NOT SIGN
++<U00BD>     /xab         VULGAR FRACTION ONE HALF
++<U00BC>     /xac         VULGAR FRACTION ONE QUARTER
++<U00A1>     /xad         INVERTED EXCLAMATION MARK
++<U00AB>     /xae         LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
++<U00BB>     /xaf         RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
++<U2591>     /xb0         LIGHT SHADE
++<U2592>     /xb1         MEDIUM SHADE
++<U2593>     /xb2         DARK SHADE
++<U2502>     /xb3         BOX DRAWINGS LIGHT VERTICAL
++<U2524>     /xb4         BOX DRAWINGS LIGHT VERTICAL AND LEFT
++<U00C1>     /xb5         LATIN CAPITAL LETTER A WITH ACUTE
++<U00C2>     /xb6         LATIN CAPITAL LETTER A WITH CIRCUMFLEX
++<U00C0>     /xb7         LATIN CAPITAL LETTER A WITH GRAVE
++<U00A9>     /xb8         COPYRIGHT SIGN
++<U2563>     /xb9         BOX DRAWINGS DOUBLE VERTICAL AND LEFT
++<U2551>     /xba         BOX DRAWINGS DOUBLE VERTICAL
++<U2557>     /xbb         BOX DRAWINGS DOUBLE DOWN AND LEFT
++<U255D>     /xbc         BOX DRAWINGS DOUBLE UP AND LEFT
++<U00A2>     /xbd         CENT SIGN
++<U00A5>     /xbe         YEN SIGN
++<U2510>     /xbf         BOX DRAWINGS LIGHT DOWN AND LEFT
++<U2514>     /xc0         BOX DRAWINGS LIGHT UP AND RIGHT
++<U2534>     /xc1         BOX DRAWINGS LIGHT UP AND HORIZONTAL
++<U252C>     /xc2         BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
++<U251C>     /xc3         BOX DRAWINGS LIGHT VERTICAL AND RIGHT
++<U2500>     /xc4         BOX DRAWINGS LIGHT HORIZONTAL
++<U253C>     /xc5         BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
++<U00E3>     /xc6         LATIN SMALL LETTER A WITH TILDE
++<U00C3>     /xc7         LATIN CAPITAL LETTER A WITH TILDE
++<U255A>     /xc8         BOX DRAWINGS DOUBLE UP AND RIGHT
++<U2554>     /xc9         BOX DRAWINGS DOUBLE DOWN AND RIGHT
++<U2569>     /xca         BOX DRAWINGS DOUBLE UP AND HORIZONTAL
++<U2566>     /xcb         BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
++<U2560>     /xcc         BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
++<U2550>     /xcd         BOX DRAWINGS DOUBLE HORIZONTAL
++<U256C>     /xce         BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
++<U00A4>     /xcf         CURRENCY SIGN
++<U00F0>     /xd0         LATIN SMALL LETTER ETH (Icelandic)
++<U00D0>     /xd1         LATIN CAPITAL LETTER ETH (Icelandic)
++<U00CA>     /xd2         LATIN CAPITAL LETTER E WITH CIRCUMFLEX
++<U00CB>     /xd3         LATIN CAPITAL LETTER E WITH DIAERESIS
++<U00C8>     /xd4         LATIN CAPITAL LETTER E WITH GRAVE
++<U20AC>     /xd5         EURO SIGN
++<U00CD>     /xd6         LATIN CAPITAL LETTER I WITH ACUTE
++<U00CE>     /xd7         LATIN CAPITAL LETTER I WITH CIRCUMFLEX
++<U00CF>     /xd8         LATIN CAPITAL LETTER I WITH DIAERESIS
++<U2518>     /xd9         BOX DRAWINGS LIGHT UP AND LEFT
++<U250C>     /xda         BOX DRAWINGS LIGHT DOWN AND RIGHT
++<U2588>     /xdb         FULL BLOCK
++<U2584>     /xdc         LOWER HALF BLOCK
++<U00A6>     /xdd         BROKEN BAR
++<U00CC>     /xde         LATIN CAPITAL LETTER I WITH GRAVE
++<U2580>     /xdf         UPPER HALF BLOCK
++<U00D3>     /xe0         LATIN CAPITAL LETTER O WITH ACUTE
++<U00DF>     /xe1         LATIN SMALL LETTER SHARP S (German)
++<U00D4>     /xe2         LATIN CAPITAL LETTER O WITH CIRCUMFLEX
++<U00D2>     /xe3         LATIN CAPITAL LETTER O WITH GRAVE
++<U00F5>     /xe4         LATIN SMALL LETTER O WITH TILDE
++<U00D5>     /xe5         LATIN CAPITAL LETTER O WITH TILDE
++<U00B5>     /xe6         MICRO SIGN
++<U00FE>     /xe7         LATIN SMALL LETTER THORN (Icelandic)
++<U00DE>     /xe8         LATIN CAPITAL LETTER THORN (Icelandic)
++<U00DA>     /xe9         LATIN CAPITAL LETTER U WITH ACUTE
++<U00DB>     /xea         LATIN CAPITAL LETTER U WITH CIRCUMFLEX
++<U00D9>     /xeb         LATIN CAPITAL LETTER U WITH GRAVE
++<U00FD>     /xec         LATIN SMALL LETTER Y WITH ACUTE
++<U00DD>     /xed         LATIN CAPITAL LETTER Y WITH ACUTE
++<U00AF>     /xee         MACRON
++<U00B4>     /xef         ACUTE ACCENT
++<U00AD>     /xf0         SOFT HYPHEN
++<U00B1>     /xf1         PLUS-MINUS SIGN
++<U2017>     /xf2         DOUBLE LOW LINE
++<U00BE>     /xf3         VULGAR FRACTION THREE QUARTERS
++<U00B6>     /xf4         PILCROW SIGN
++<U00A7>     /xf5         SECTION SIGN
++<U00F7>     /xf6         DIVISION SIGN
++<U00B8>     /xf7         CEDILLA
++<U00B0>     /xf8         DEGREE SIGN
++<U00A8>     /xf9         DIAERESIS
++<U00B7>     /xfa         MIDDLE DOT
++<U00B9>     /xfb         SUPERSCRIPT ONE
++<U00B3>     /xfc         SUPERSCRIPT THREE
++<U00B2>     /xfd         SUPERSCRIPT TWO
++<U25A0>     /xfe         BLACK SQUARE
++<U00A0>     /xff         NO-BREAK SPACE
++END CHARMAP
diff --git a/SOURCES/glibc-rh1451308.patch b/SOURCES/glibc-rh1451308.patch
new file mode 100644
index 0000000..3bbbe95
--- /dev/null
+++ b/SOURCES/glibc-rh1451308.patch
@@ -0,0 +1,41 @@
+commit d62aa75af1941fca6f07e107afc447b7b248e340
+Author: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date:   Thu Jul 10 14:15:16 2014 +0530
+
+    Fix crash when system has no ipv6 address [BZ #17125]
+    
+    Here's an updated patch to fix the crash in bug-ga2 when the system
+    has no configured ipv6 address.  I have taken a different approach of
+    using libc_freeres_fn instead of the libc_freeres_ptr since the former
+    gives better control over what is freed; we need that since cache may
+    or may not be allocated using malloc.
+    
+    Verified that bug-ga2 works correctly in both cases and does not have
+    memory leaks in either of them.
+
+diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c
+index 6b28a735a14f1498..757853342d2af5f4 100644
+--- a/sysdeps/unix/sysv/linux/check_pf.c
++++ b/sysdeps/unix/sysv/linux/check_pf.c
+@@ -62,7 +62,7 @@ static struct cached_data noai6ai_cached =
+     .in6ailen = 0
+   };
+ 
+-libc_freeres_ptr (static struct cached_data *cache);
++static struct cached_data *cache;
+ __libc_lock_define_initialized (static, lock);
+ 
+ 
+@@ -378,6 +378,12 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6,
+   *seen_ipv6 = true;
+ }
+ 
++/* Free the cache if it has been allocated.  */
++libc_freeres_fn (freecache)
++{
++  if (cache)
++    __free_in6ai (cache->in6ai);
++}
+ 
+ void
+ __free_in6ai (struct in6addrinfo *ai)
diff --git a/SOURCES/glibc-rh1484832.patch b/SOURCES/glibc-rh1484832.patch
new file mode 100644
index 0000000..7157dcd
--- /dev/null
+++ b/SOURCES/glibc-rh1484832.patch
@@ -0,0 +1,30 @@
+commit 273cdee86d86e107c0eecef5614f57e37567b54e
+Author: Andreas Schwab <schwab@suse.de>
+Date:   Tue Jan 15 16:39:07 2013 +0100
+
+    Fix invalid free of memory allocated during rtld init
+
+diff --git a/elf/dl-load.c b/elf/dl-load.c
+index 013efdb3814700d3..6a0005da502c8f37 100644
+--- a/elf/dl-load.c
++++ b/elf/dl-load.c
+@@ -822,6 +822,9 @@ _dl_init_paths (const char *llp)
+ 			   (const void *) (D_PTR (l, l_info[DT_STRTAB])
+ 					   + l->l_info[DT_RUNPATH]->d_un.d_val),
+ 			   l, "RUNPATH");
++	  /* During rtld init the memory is allocated by the stub malloc,
++	     prevent any attempt to free it by the normal malloc.  */
++	  l->l_runpath_dirs.malloced = 0;
+ 
+ 	  /* The RPATH is ignored.  */
+ 	  l->l_rpath_dirs.dirs = (void *) -1;
+@@ -838,6 +841,9 @@ _dl_init_paths (const char *llp)
+ 			       (const void *) (D_PTR (l, l_info[DT_STRTAB])
+ 					       + l->l_info[DT_RPATH]->d_un.d_val),
+ 			       l, "RPATH");
++	      /* During rtld init the memory is allocated by the stub
++		 malloc, prevent any attempt to free it by the normal
++		 malloc.  */
+ 	      l->l_rpath_dirs.malloced = 0;
+ 	    }
+ 	  else
diff --git a/SOURCES/glibc-rh1579451.patch b/SOURCES/glibc-rh1579451.patch
new file mode 100644
index 0000000..ccf048f
--- /dev/null
+++ b/SOURCES/glibc-rh1579451.patch
@@ -0,0 +1,112 @@
+[RHBZ #1579451]
+This is a backport of the following two upstream patches:
+
+commit 31545c23277cd54a1edd41c85d8255fb589158e3
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Mon Jun 29 14:38:46 2015 +0000
+
+    Update headers for Linux 4.0, 4.1 definitions.
+
+    This patch updates installed glibc headers for new definitions from
+    Linux 4.0 and 4.1 that seem relevant to glibc headers.  In addition, I
+    noticed that PF_IB / AF_IB, added in Linux 3.11, were missing for no
+    obvious reason, so added those as well.
+
+    Tested for x86_64 (testsuite, and that installed stripped shared
+    libraries are unchanged by the patch).
+
+        * sysdeps/unix/sysv/linux/bits/in.h (IP_CHECKSUM): New macro.
+        * sysdeps/unix/sysv/linux/bits/socket.h (PF_IB): Likewise.
+        (PF_MPLS): Likewise.
+        (AF_IB): Likewise.
+        (AF_MPLS): Likewise.
+        * sysdeps/unix/sysv/linux/sys/mount.h (MS_LAZYTIME): New enum
+        value and macro.
+        (MS_RMT_MASK): Include MS_LAZYTIME.
+
+commit 04d9a38bafddb92ab79bc0015533689e15848522
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Tue Sep 1 13:47:25 2015 +0000
+
+    Add netinet/in.h values from Linux 4.2.
+
+    This patch adds new constants from Linux 4.2 to netinet/in.h:
+    IPPROTO_MPLS and IP_BIND_ADDRESS_NO_PORT (both in
+    include/uapi/linux/in.h in Linux; one directly in netinet/in.h, one in
+    bits/in.h in glibc).
+
+    Tested for x86_64 (testsuite, and that installed stripped shared
+    libraries are unchanged by the patch).
+
+        * inet/netinet/in.h (IPPROTO_MPLS): New enum value and macro.
+        * sysdeps/unix/sysv/linux/bits/in.h (IP_BIND_ADDRESS_NO_PORT): New
+        macro.
+
+
+diff -Nrup a/inet/netinet/in.h b/inet/netinet/in.h
+--- a/inet/netinet/in.h	2019-07-30 12:03:33.082066705 -0400
++++ b/inet/netinet/in.h	2019-07-30 12:22:54.461572719 -0400
+@@ -86,6 +86,8 @@ enum
+ #define IPPROTO_SCTP		IPPROTO_SCTP
+     IPPROTO_UDPLITE = 136, /* UDP-Lite protocol.  */
+ #define IPPROTO_UDPLITE		IPPROTO_UDPLITE
++    IPPROTO_MPLS = 137,    /* MPLS in IP.  */
++#define IPPROTO_MPLS           IPPROTO_MPLS
+     IPPROTO_RAW = 255,	   /* Raw IP packets.  */
+ #define IPPROTO_RAW		IPPROTO_RAW
+     IPPROTO_MAX
+diff -Nrup a/sysdeps/unix/sysv/linux/bits/in.h b/sysdeps/unix/sysv/linux/bits/in.h
+--- a/sysdeps/unix/sysv/linux/bits/in.h	2019-07-30 12:03:35.863052019 -0400
++++ b/sysdeps/unix/sysv/linux/bits/in.h	2019-07-30 12:51:15.293703728 -0400
+@@ -99,6 +99,8 @@
+ 
+ #define IP_MINTTL       21
+ #define IP_NODEFRAG     22
++#define IP_CHECKSUM     23
++#define IP_BIND_ADDRESS_NO_PORT 24
+ 
+ /* IP_MTU_DISCOVER arguments.  */
+ #define IP_PMTUDISC_DONT   0	/* Never send DF frames.  */
+diff -Nrup a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h
+--- a/sysdeps/unix/sysv/linux/bits/socket.h	2019-07-30 12:03:33.757063141 -0400
++++ b/sysdeps/unix/sysv/linux/bits/socket.h	2019-07-30 12:54:02.612870856 -0400
+@@ -69,6 +69,8 @@ typedef __socklen_t socklen_t;
+ #define	PF_PPPOX	24	/* PPPoX sockets.  */
+ #define	PF_WANPIPE	25	/* Wanpipe API sockets.  */
+ #define PF_LLC		26	/* Linux LLC.  */
++#define PF_IB		27      /* Native InfiniBand address.  */
++#define PF_MPLS		28      /* MPLS.  */
+ #define PF_CAN		29	/* Controller Area Network.  */
+ #define PF_TIPC		30	/* TIPC sockets.  */
+ #define	PF_BLUETOOTH	31	/* Bluetooth sockets.  */
+@@ -114,6 +116,8 @@ typedef __socklen_t socklen_t;
+ #define	AF_PPPOX	PF_PPPOX
+ #define	AF_WANPIPE	PF_WANPIPE
+ #define AF_LLC		PF_LLC
++#define AF_IB		PF_IB
++#define AF_MPLS		PF_MPLS
+ #define AF_CAN		PF_CAN
+ #define AF_TIPC		PF_TIPC
+ #define	AF_BLUETOOTH	PF_BLUETOOTH
+diff -Nrup a/sysdeps/unix/sysv/linux/sys/mount.h b/sysdeps/unix/sysv/linux/sys/mount.h
+--- a/sysdeps/unix/sysv/linux/sys/mount.h	2012-12-24 22:02:13.000000000 -0500
++++ b/sysdeps/unix/sysv/linux/sys/mount.h	2019-07-30 12:58:23.595571750 -0400
+@@ -78,6 +78,8 @@ enum
+ #define MS_I_VERSION	MS_I_VERSION
+   MS_STRICTATIME = 1 << 24,	/* Always perform atime updates.  */
+ #define MS_STRICTATIME	MS_STRICTATIME
++  MS_LAZYTIME = 1 << 25,       /* Update the on-disk [acm]times lazily.  */
++#define MS_LAZYTIME    MS_LAZYTIME
+   MS_ACTIVE = 1 << 30,
+ #define MS_ACTIVE	MS_ACTIVE
+   MS_NOUSER = 1 << 31
+@@ -85,7 +87,8 @@ enum
+ };
+ 
+ /* Flags that can be altered by MS_REMOUNT  */
+-#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION)
++#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION \
++		    |MS_LAZYTIME)
+ 
+ 
+ /* Magic mount flag number. Has to be or-ed to the flag values.  */
diff --git a/SOURCES/glibc-rh1595191-1.patch b/SOURCES/glibc-rh1595191-1.patch
index 62a85d7..ed57567 100644
--- a/SOURCES/glibc-rh1595191-1.patch
+++ b/SOURCES/glibc-rh1595191-1.patch
@@ -17,7 +17,7 @@ Date:   Fri Jun 1 10:43:06 2018 +0200
     
     (cherry picked from commit 4e8a6346cd3da2d88bbad745a1769260d36f2783)
 
-Backported from the upstream release/2.26/master branch.
+Backported from the upstream release/2.27/master branch.
 
 diff --git a/debug/vasprintf_chk.c b/debug/vasprintf_chk.c
 index a8ca32bad57b4d13..113354749ccf8d9a 100644
diff --git a/SOURCES/glibc-rh1595191-2.patch b/SOURCES/glibc-rh1595191-2.patch
index 17b6030..9fe4cd4 100644
--- a/SOURCES/glibc-rh1595191-2.patch
+++ b/SOURCES/glibc-rh1595191-2.patch
@@ -6,7 +6,7 @@ Date:   Tue Jul 3 15:54:49 2018 +0200
     
     (cherry picked from commit c402355dfa7807b8e0adb27c009135a7e2b9f1b0)
 
-Backported from the upstream release/2.26/master branch.
+Backported from the upstream release/2.27/master branch.
 
 diff --git a/libio/vtables.c b/libio/vtables.c
 index e364ea03edbfa75b..d6478e4bab9050ce 100644
diff --git a/SOURCES/glibc-rh1595191-3.patch b/SOURCES/glibc-rh1595191-3.patch
index ab88533..51db5a2 100644
--- a/SOURCES/glibc-rh1595191-3.patch
+++ b/SOURCES/glibc-rh1595191-3.patch
@@ -9,7 +9,7 @@ Date:   Tue Jul 3 17:57:14 2018 +0200
     Some adjustments were needed for a tricky multi-inclusion issue related
     to libioP.h.
 
-Backported from the upsteam release/2.26/master branch, adjusted for
+Backported from the upsteam release/2.27/master branch, adjusted for
 lack of tests-internal support downstream.
 
 diff --git a/libio/Makefile b/libio/Makefile
diff --git a/SOURCES/glibc-rh1634021.patch b/SOURCES/glibc-rh1634021.patch
new file mode 100644
index 0000000..a1e401f
--- /dev/null
+++ b/SOURCES/glibc-rh1634021.patch
@@ -0,0 +1,19 @@
+commit 8ec3f656d6edf6f16216105131fc8b0542216a5b
+Author: Andreas Schwab <schwab@suse.de>
+Date:   Mon Nov 11 12:24:42 2013 +0100
+
+    Fix off-by-one in nscd getservbyport call
+
+diff --git a/nscd/nscd_getserv_r.c b/nscd/nscd_getserv_r.c
+index c9c890c..7728258 100644
+--- a/nscd/nscd_getserv_r.c
++++ b/nscd/nscd_getserv_r.c
+@@ -54,7 +54,7 @@ __nscd_getservbyport_r (int port, const char *proto,
+   portstr[sizeof (portstr) - 1] = '\0';
+   char *cp = _itoa_word (port, portstr + sizeof (portstr) - 1, 10, 0);
+ 
+-  return nscd_getserv_r (cp, portstr + sizeof (portstr) - cp, proto,
++  return nscd_getserv_r (cp, portstr + sizeof (portstr) - 1 - cp, proto,
+ 			 GETSERVBYPORT, result_buf, buf, buflen, result);
+ }
+ 
diff --git a/SOURCES/glibc-rh1636229-1.patch b/SOURCES/glibc-rh1636229-1.patch
new file mode 100644
index 0000000..e832909
--- /dev/null
+++ b/SOURCES/glibc-rh1636229-1.patch
@@ -0,0 +1,1316 @@
+commit ae5c498d93d049d9574d3f8f18e62cac64cbdf5c
+Author: DJ Delorie <dj@delorie.com>
+Date:   Mon Jul 17 15:50:43 2017 -0400
+
+    Extend NSS test suite
+    
+    * nss/nss_test.h: New.
+    * nss/nss_test1.h: Rewrite to use test-provided data.  Add group
+    tests.  Parameterize to allow multiple instances.
+    * nss/nss_test2.h: New.  Second instance.
+    * nss/nss_test.ver: New.
+    * nss/nss_test1.c: Update to use new framework.
+    * nss/nss_test2.c: New.
+    * nss/nss_test3.c: New.
+    * nss/nss_test4.c: New.
+    * nss/nss_test5.c: New.
+    * nss/Makefile: Build new tests.
+    * shlib-versions: Add libnss_test2.
+
+Moved nss/Makefile to separate patch to resolve conflicts. 
+
+diff --git a/nss/nss_test.h b/nss/nss_test.h
+new file mode 100644
+index 0000000000..0a0e00b4e6
+--- /dev/null
++++ b/nss/nss_test.h
+@@ -0,0 +1,308 @@
++/* Common code for NSS test cases.
++   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/>.  */
++
++
++/* There are two (or more) NSS test modules named nss_test1,
++   nss_test2, etc.  Each one will call a function IN THE TEST CASE
++   called _nss_test1_init_hook(test_tables *) (or _nss_test2_*, etc).
++
++   In your copy of the hook function, you may change the *_table
++   pointers in the passed struct to point to static tables in your
++   test case, and the test modules will use that table instead.
++
++   Your tables MUST end with an entry that has a *_LAST() macro.
++   Use the *_ISLAST() macro to test for end of list.
++
++   Use __nss_configure_lookup("passwd", "test1 test2") (for example) to
++   configure NSS to use the test modules.  */
++
++#include <pwd.h>
++#include <grp.h>
++
++typedef struct test_tables {
++  struct passwd *pwd_table;
++  struct group *grp_table;
++} test_tables;
++
++extern void _nss_test1_init_hook (test_tables *) __attribute__((weak));
++extern void _nss_test2_init_hook (test_tables *) __attribute__((weak));
++
++#define PWD_LAST()    { .pw_name = NULL, .pw_uid = 0 }
++#define GRP_LAST()    { .gr_name = NULL, .gr_gid = 0 }
++
++#define PWD_ISLAST(p)    ((p)->pw_name == NULL && (p)->pw_uid == 0)
++#define GRP_ISLAST(g)    ((g)->gr_name == NULL && (g)->gr_gid == 0)
++
++/* Macros to fill in the tables easily.  */
++
++/* Note that the "unparameterized" fields are not magic; they're just
++   arbitrary values.  Tests which need to verify those fields should
++   fill them in explicitly.  */
++
++#define PWD(u) \
++    { .pw_name = (char *) "name" #u, .pw_passwd = (char *) "*", .pw_uid = u,  \
++      .pw_gid = 100, .pw_gecos = (char *) "*", .pw_dir = (char *) "*",	      \
++      .pw_shell = (char *) "*" }
++
++#define PWD_N(u,n)								\
++    { .pw_name = (char *) n, .pw_passwd = (char *) "*", .pw_uid = u,  \
++      .pw_gid = 100, .pw_gecos = (char *) "*", .pw_dir = (char *) "*",	      \
++      .pw_shell = (char *) "*" }
++
++#define GRP(u) \
++    { .gr_name = (char *) "name" #u, .gr_passwd = (char *) "*", .gr_gid = u, \
++      .gr_mem = (char **) group_##u }
++
++#define GRP_N(u,n,m)						     \
++    { .gr_name = (char *) n, .gr_passwd = (char *) "*", .gr_gid = u, \
++      .gr_mem = (char **) m }
++
++/*------------------------------------------------------------*/
++
++/* Helper functions for testing passwd entries.  Call
++   compare_passwds() passing a test index, the passwd entry you got,
++   and the expected passwd entry.  The function will return the number
++   of mismatches, or zero of the two records are the same.  */
++
++static void __attribute__((used))
++print_passwd (struct passwd *p)
++{
++  printf ("    passwd %u.%s (%s) :", p->pw_uid, p->pw_name, p->pw_passwd);
++  printf (" %u, %s, %s, %s\n", p->pw_gid, p->pw_gecos, p->pw_dir, p->pw_shell);
++  printf ("\n");
++}
++
++static int  __attribute__((used))
++compare_passwd_field (int i, struct passwd *p, const char *got,
++		      const char *exp, const char *name)
++{
++  /* Does the entry have a value?  */
++  if (got == NULL)
++    {
++      printf ("[%d] passwd %s for %u.%s was (null)\n",
++	      i, name,
++	      p->pw_uid, p->pw_name);
++      return 1;
++    }
++  /* Does the entry have an unexpected name?  */
++  else if (exp == NULL)
++    {
++      printf ("[%d] passwd %s for %u.(null) was %s\n",
++	      i, name,
++	      p->pw_uid, got);
++      return 1;
++    }
++  /* And is it correct?  */
++  else if (got && strcmp (got, exp) != 0)
++    {
++      printf("[%d] passwd entry %u.%s had %s \"%s\" (expected \"%s\") \n",
++	     i,
++	     p->pw_uid, p->pw_name, name,
++	     got, exp);
++      return 1;
++    }
++  return 0;
++}
++
++#define COMPARE_PWD_FIELD(f) \
++  retval += compare_passwd_field (i, e, p->f, e->f, #f)
++
++/* Compare passwd to expected passwd, return number of "problems".
++   "I" is the index into the testcase data.  */
++static int  __attribute__((used))
++compare_passwds (int i, struct passwd *p, struct passwd *e)
++{
++  int retval = 0;
++
++  /* Did we get the expected uid?  */
++  if (p->pw_uid != e->pw_uid)
++    {
++      printf("[%d] passwd entry %u.%s had uid %u\n", i,
++	     e->pw_uid, e->pw_name,
++	     p->pw_uid);
++      ++retval;
++    }
++
++  /* Did we get the expected gid?  */
++  if (p->pw_gid != e->pw_gid)
++    {
++      printf("[%d] passwd entry %u.%s had gid %u (expected %u)\n", i,
++	     e->pw_uid, e->pw_name,
++	     p->pw_gid, e->pw_gid);
++      ++retval;
++    }
++
++  COMPARE_PWD_FIELD (pw_name);
++  COMPARE_PWD_FIELD (pw_passwd);
++  COMPARE_PWD_FIELD (pw_gecos);
++  COMPARE_PWD_FIELD (pw_dir);
++  COMPARE_PWD_FIELD (pw_shell);
++
++  if (retval > 0)
++    {
++      /* Left in for debugging later, if needed.  */
++      print_passwd (p);
++      print_passwd (e);
++    }
++
++  return retval;
++}
++
++/*------------------------------------------------------------*/
++
++/* Helpers for checking group entries.  See passwd helper comment
++   above for details.  */
++
++static void __attribute__((used))
++print_group (struct group *g)
++{
++  int j;
++
++  printf ("    group %u.%s (%s) :", g->gr_gid, g->gr_name, g->gr_passwd);
++  if (g->gr_mem)
++    for (j=0; g->gr_mem[j]; j++)
++      printf ("%s%s", j==0 ? " " : ", ", g->gr_mem[j]);
++  printf ("\n");
++}
++
++/* Compare group to expected group, return number of "problems".  "I"
++   is the index into the testcase data.  */
++static int  __attribute__((used))
++compare_groups (int i, struct group *g, struct group *e)
++{
++  int j;
++  int retval = 0;
++
++  /* Did we get the expected gid?  */
++  if (g->gr_gid != e->gr_gid)
++    {
++      printf("[%d] group entry %u.%s had gid %u\n", i,
++	     e->gr_gid, e->gr_name,
++	     g->gr_gid);
++      ++retval;
++    }
++
++  /* Does the entry have a name?  */
++  if (g->gr_name == NULL)
++    {
++      printf ("[%d] group name for %u.%s was (null)\n", i,
++	      e->gr_gid, e->gr_name);
++      ++retval;
++    }
++  /* Does the entry have an unexpected name?  */
++  else if (e->gr_name == NULL)
++    {
++      printf ("[%d] group name for %u.(null) was %s\n", i,
++	      e->gr_gid, g->gr_name);
++      ++retval;
++    }
++  /* And is it correct?  */
++  else if (strcmp (g->gr_name, e->gr_name) != 0)
++    {
++      printf("[%d] group entry %u.%s had name \"%s\"\n", i,
++	     e->gr_gid, e->gr_name,
++	     g->gr_name);
++      ++retval;
++    }
++
++  /* Does the entry have a password?  */
++  if (g->gr_passwd == NULL && e->gr_passwd != NULL)
++    {
++      printf ("[%d] group password for %u.%s was NULL\n", i,
++	      e->gr_gid, e->gr_name);
++      ++retval;
++    }
++  else if (g->gr_passwd != NULL && e->gr_passwd == NULL)
++    {
++      printf ("[%d] group password for %u.%s was not NULL\n", i,
++	      e->gr_gid, e->gr_name);
++      ++retval;
++    }
++  /* And is it correct?  */
++  else if (g->gr_passwd && strcmp (g->gr_passwd, e->gr_passwd) != 0)
++    {
++      printf("[%d] group entry %u.%s had password \"%s\" (not \"%s\")\n", i,
++	     e->gr_gid, e->gr_name,
++	     g->gr_passwd, e->gr_passwd);
++      ++retval;
++    }
++
++  /* Now compare group members... */
++
++  if (e->gr_mem != NULL && g->gr_mem == NULL)
++    {
++      printf("[%d] group entry %u.%s missing member list\n", i,
++	     e->gr_gid, e->gr_name);
++      ++retval;
++    }
++  else if (e->gr_mem == NULL && g->gr_mem != NULL)
++    {
++      printf("[%d] group entry %u.%s has unexpected member list\n", i,
++	     e->gr_gid, e->gr_name);
++      ++retval;
++    }
++  else if (e->gr_mem == NULL && g->gr_mem == NULL)
++    {
++      /* This case is OK.  */
++    }
++  else
++    {
++      /* Compare two existing lists.  */
++      j = 0;
++      for (;;)
++	{
++	  if (g->gr_mem[j] == NULL && e->gr_mem[j] == NULL)
++	    {
++	      /* Matching end-of-lists.  */
++	      break;
++	    }
++	  if (g->gr_mem[j] == NULL)
++	    {
++	      printf ("[%d] group member list for %u.%s is too short.\n", i,
++		      e->gr_gid, e->gr_name);
++	      ++retval;
++	      break;
++	    }
++	  if (e->gr_mem[j] == NULL)
++	    {
++	      printf ("[%d] group member list for %u.%s is too long.\n", i,
++		      e->gr_gid, e->gr_name);
++	      ++retval;
++	      break;
++	    }
++	  if (strcmp (g->gr_mem[j], e->gr_mem[j]) != 0)
++	    {
++	      printf ("[%d] group member list for %u.%s differs: %s vs %s.\n", i,
++		      e->gr_gid, e->gr_name,
++		      e->gr_mem[j], g->gr_mem[j]);
++	      ++retval;
++	    }
++
++	  j++;
++	}
++    }
++
++  if (retval > 0)
++    {
++      /* Left in for debugging later, if needed.  */
++      print_group (g);
++      print_group (e);
++    }
++
++  return retval;
++}
+diff --git a/nss/nss_test.ver b/nss/nss_test.ver
+new file mode 100644
+index 0000000000..2e21176b40
+--- /dev/null
++++ b/nss/nss_test.ver
+@@ -0,0 +1,4 @@
++{
++  _nss_test1_init_hook;
++  _nss_test2_init_hook;
++};
+diff --git a/nss/nss_test1.c b/nss/nss_test1.c
+index 3beb488fcf..b728e418a3 100644
+--- a/nss/nss_test1.c
++++ b/nss/nss_test1.c
+@@ -1,84 +1,168 @@
++/* Template generic NSS service provider.  See nss_test.h for usage.
++   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/>.  */
++
+ #include <errno.h>
+ #include <nss.h>
+ #include <pthread.h>
+ #include <string.h>
++#include <stdio.h>
++#include <alloc_buffer.h>
+ 
+ 
+-#define COPY_IF_ROOM(s) \
+-  ({ size_t len_ = strlen (s) + 1;		\
+-     char *start_ = cp;				\
+-     buflen - (cp - buffer) < len_		\
+-     ? NULL					\
+-     : (cp = mempcpy (cp, s, len_), start_); })
++/* We need to be able to handle NULLs "properly" within the testsuite,
++   to test known bad data.  */
++#define alloc_buffer_maybe_copy_string(b,s) s ? alloc_buffer_copy_string (b, s) : NULL;
+ 
++/* This file is the master template.  Other instances of this test
++   module should define NAME(x) to have their name instead of "test1",
++   then include this file.
++*/
++#define NAME_(x,n) _nss_##n##_##x
++#ifndef NAME
++#define NAME(x) NAME_(x,test1)
++#endif
++#define NAMESTR__(x) #x
++#define NAMESTR_(x) NAMESTR__(x)
++#define NAMESTR(x) NAMESTR_(NAME(x))
+ 
+-/* Password handling.  */
+-#include <pwd.h>
++#include "nss_test.h"
++
++/* -------------------------------------------------- */
++/* Default Data.  */
+ 
+-static struct passwd pwd_data[] =
++static struct passwd default_pwd_data[] =
+   {
+ #define PWD(u) \
+     { .pw_name = (char *) "name" #u, .pw_passwd = (char *) "*", .pw_uid = u,  \
+       .pw_gid = 100, .pw_gecos = (char *) "*", .pw_dir = (char *) "*",	      \
+       .pw_shell = (char *) "*" }
+-    PWD (100),
+     PWD (30),
++    PWD (100),
+     PWD (200),
+     PWD (60),
+     PWD (20000)
+   };
+-#define npwd_data (sizeof (pwd_data) / sizeof (pwd_data[0]))
++#define default_npwd_data (sizeof (pwd_data) / sizeof (pwd_data[0]))
++
++static struct passwd *pwd_data = default_pwd_data;
++static int npwd_data = default_npwd_data;
++
++static struct group *grp_data = NULL;
++static int ngrp_data = 0;
++
++/* This function will get called, and once per session, look back into
++   the test case's executable for an init hook function, and call
++   it.  */
++
++static int initted = 0;
++static void
++init(void)
++{
++  test_tables t;
++  int i;
++
++  if (initted)
++    return;
++  if (NAME(init_hook))
++    {
++      memset (&t, 0, sizeof(t));
++      NAME(init_hook)(&t);
++
++      if (t.pwd_table)
++	{
++	  pwd_data = t.pwd_table;
++	  for (i=0; ! PWD_ISLAST(& pwd_data[i]); i++)
++	    ;
++	  npwd_data = i;
++	}
++
++      if (t.grp_table)
++	{
++	  grp_data = t.grp_table;
++	  for (i=0; ! GRP_ISLAST(& grp_data[i]); i++)
++	    ;
++	  ngrp_data = i;
++	}
++    }
++  initted = 1;
++}
++
++/* -------------------------------------------------- */
++/* Password handling.  */
+ 
+ static size_t pwd_iter;
+ #define CURPWD pwd_data[pwd_iter]
+ 
+ static pthread_mutex_t pwd_lock = PTHREAD_MUTEX_INITIALIZER;
+ 
+-
+ enum nss_status
+-_nss_test1_setpwent (int stayopen)
++NAME(setpwent) (int stayopen)
+ {
++  init();
+   pwd_iter = 0;
+   return NSS_STATUS_SUCCESS;
+ }
+ 
+ 
+ enum nss_status
+-_nss_test1_endpwent (void)
++NAME(endpwent) (void)
+ {
++  init();
+   return NSS_STATUS_SUCCESS;
+ }
+ 
++static enum nss_status
++copy_passwd (struct passwd *result, struct passwd *local,
++	    char *buffer, size_t buflen, int *errnop)
++{
++  struct alloc_buffer buf = alloc_buffer_create (buffer, buflen);
++
++  result->pw_name = alloc_buffer_maybe_copy_string (&buf, local->pw_name);
++  result->pw_passwd = alloc_buffer_maybe_copy_string (&buf, local->pw_passwd);
++  result->pw_uid = local->pw_uid;
++  result->pw_gid = local->pw_gid;
++  result->pw_gecos = alloc_buffer_maybe_copy_string (&buf, local->pw_gecos);
++  result->pw_dir = alloc_buffer_maybe_copy_string (&buf, local->pw_dir);
++  result->pw_shell = alloc_buffer_maybe_copy_string (&buf, local->pw_shell);
++
++  if (alloc_buffer_has_failed (&buf))
++    {
++      *errnop = ERANGE;
++      return NSS_STATUS_TRYAGAIN;
++    }
++
++  return NSS_STATUS_SUCCESS;
++}
+ 
+ enum nss_status
+-_nss_test1_getpwent_r (struct passwd *result, char *buffer, size_t buflen,
++NAME(getpwent_r) (struct passwd *result, char *buffer, size_t buflen,
+ 		       int *errnop)
+ {
+-  char *cp = buffer;
+   int res = NSS_STATUS_SUCCESS;
+ 
++  init();
+   pthread_mutex_lock (&pwd_lock);
+ 
+   if (pwd_iter >= npwd_data)
+     res = NSS_STATUS_NOTFOUND;
+   else
+     {
+-      result->pw_name = COPY_IF_ROOM (CURPWD.pw_name);
+-      result->pw_passwd = COPY_IF_ROOM (CURPWD.pw_passwd);
+-      result->pw_uid = CURPWD.pw_uid;
+-      result->pw_gid = CURPWD.pw_gid;
+-      result->pw_gecos = COPY_IF_ROOM (CURPWD.pw_gecos);
+-      result->pw_dir = COPY_IF_ROOM (CURPWD.pw_dir);
+-      result->pw_shell = COPY_IF_ROOM (CURPWD.pw_shell);
+-
+-      if (result->pw_name == NULL || result->pw_passwd == NULL
+-	  || result->pw_gecos == NULL || result->pw_dir == NULL
+-	  || result->pw_shell == NULL)
+-	{
+-	  *errnop = ERANGE;
+-	  res = NSS_STATUS_TRYAGAIN;
+-	}
+-
++      res = copy_passwd (result, &CURPWD, buffer, buflen, errnop);
+       ++pwd_iter;
+     }
+ 
+@@ -89,65 +173,140 @@ _nss_test1_getpwent_r (struct passwd *result, char *buffer, size_t buflen,
+ 
+ 
+ enum nss_status
+-_nss_test1_getpwuid_r (uid_t uid, struct passwd *result, char *buffer,
++NAME(getpwuid_r) (uid_t uid, struct passwd *result, char *buffer,
+ 		       size_t buflen, int *errnop)
+ {
++  init();
+   for (size_t idx = 0; idx < npwd_data; ++idx)
+     if (pwd_data[idx].pw_uid == uid)
+-      {
+-	char *cp = buffer;
+-	int res = NSS_STATUS_SUCCESS;
+-
+-	result->pw_name = COPY_IF_ROOM (pwd_data[idx].pw_name);
+-	result->pw_passwd = COPY_IF_ROOM (pwd_data[idx].pw_passwd);
+-	result->pw_uid = pwd_data[idx].pw_uid;
+-	result->pw_gid = pwd_data[idx].pw_gid;
+-	result->pw_gecos = COPY_IF_ROOM (pwd_data[idx].pw_gecos);
+-	result->pw_dir = COPY_IF_ROOM (pwd_data[idx].pw_dir);
+-	result->pw_shell = COPY_IF_ROOM (pwd_data[idx].pw_shell);
+-
+-	if (result->pw_name == NULL || result->pw_passwd == NULL
+-	    || result->pw_gecos == NULL || result->pw_dir == NULL
+-	    || result->pw_shell == NULL)
+-	  {
+-	    *errnop = ERANGE;
+-	    res = NSS_STATUS_TRYAGAIN;
+-	  }
+-
+-	return res;
+-      }
++      return copy_passwd (result, &pwd_data[idx], buffer, buflen, errnop);
+ 
+   return NSS_STATUS_NOTFOUND;
+ }
+ 
+ 
+ enum nss_status
+-_nss_test1_getpwnam_r (const char *name, struct passwd *result, char *buffer,
++NAME(getpwnam_r) (const char *name, struct passwd *result, char *buffer,
+ 		       size_t buflen, int *errnop)
+ {
++  init();
+   for (size_t idx = 0; idx < npwd_data; ++idx)
++    if (strcmp (pwd_data[idx].pw_name, name) == 0)
++      return copy_passwd (result, &pwd_data[idx], buffer, buflen, errnop);
++
++  return NSS_STATUS_NOTFOUND;
++}
++
++/* -------------------------------------------------- */
++/* Group handling.  */
++
++static size_t grp_iter;
++#define CURGRP grp_data[grp_iter]
++
++static pthread_mutex_t grp_lock = PTHREAD_MUTEX_INITIALIZER;
++
++enum nss_status
++NAME(setgrent) (int stayopen)
++{
++  init();
++  grp_iter = 0;
++  return NSS_STATUS_SUCCESS;
++}
++
++
++enum nss_status
++NAME(endgrent) (void)
++{
++  init();
++  return NSS_STATUS_SUCCESS;
++}
++
++static enum nss_status
++copy_group (struct group *result, struct group *local,
++	    char *buffer, size_t buflen, int *errnop)
++{
++  struct alloc_buffer buf = alloc_buffer_create (buffer, buflen);
++  char **memlist;
++  int i;
++
++  if (local->gr_mem)
++    {
++      i = 0;
++      while (local->gr_mem[i])
++	++i;
++
++      memlist = alloc_buffer_alloc_array (&buf, char *, i + 1);
++
++      if (memlist) {
++	for (i = 0; local->gr_mem[i]; ++i)
++	  memlist[i] = alloc_buffer_maybe_copy_string (&buf, local->gr_mem[i]);
++	memlist[i] = NULL;
++      }
++
++      result->gr_mem = memlist;
++    }
++  else
++    result->gr_mem = NULL;
++
++  result->gr_name = alloc_buffer_maybe_copy_string (&buf, local->gr_name);
++  result->gr_passwd = alloc_buffer_maybe_copy_string (&buf, local->gr_passwd);
++  result->gr_gid = local->gr_gid;
++
++  if (alloc_buffer_has_failed (&buf))
++    {
++      *errnop = ERANGE;
++      return NSS_STATUS_TRYAGAIN;
++    }
++
++  return NSS_STATUS_SUCCESS;
++}
++
++
++enum nss_status
++NAME(getgrent_r) (struct group *result, char *buffer, size_t buflen,
++		       int *errnop)
++{
++  int res = NSS_STATUS_SUCCESS;
++
++  init();
++  pthread_mutex_lock (&grp_lock);
++
++  if (grp_iter >= ngrp_data)
++    res = NSS_STATUS_NOTFOUND;
++  else
++    {
++      res = copy_group (result, &CURGRP, buffer, buflen, errnop);
++      ++grp_iter;
++    }
++
++  pthread_mutex_unlock (&pwd_lock);
++
++  return res;
++}
++
++
++enum nss_status
++NAME(getgrgid_r) (gid_t gid, struct group *result, char *buffer,
++		  size_t buflen, int *errnop)
++{
++  init();
++  for (size_t idx = 0; idx < ngrp_data; ++idx)
++    if (grp_data[idx].gr_gid == gid)
++      return copy_group (result, &grp_data[idx], buffer, buflen, errnop);
++
++  return NSS_STATUS_NOTFOUND;
++}
++
++
++enum nss_status
++NAME(getgrnam_r) (const char *name, struct group *result, char *buffer,
++		       size_t buflen, int *errnop)
++{
++  init();
++  for (size_t idx = 0; idx < ngrp_data; ++idx)
+     if (strcmp (pwd_data[idx].pw_name, name) == 0)
+       {
+-	char *cp = buffer;
+-	int res = NSS_STATUS_SUCCESS;
+-
+-	result->pw_name = COPY_IF_ROOM (pwd_data[idx].pw_name);
+-	result->pw_passwd = COPY_IF_ROOM (pwd_data[idx].pw_passwd);
+-	result->pw_uid = pwd_data[idx].pw_uid;
+-	result->pw_gid = pwd_data[idx].pw_gid;
+-	result->pw_gecos = COPY_IF_ROOM (pwd_data[idx].pw_gecos);
+-	result->pw_dir = COPY_IF_ROOM (pwd_data[idx].pw_dir);
+-	result->pw_shell = COPY_IF_ROOM (pwd_data[idx].pw_shell);
+-
+-	if (result->pw_name == NULL || result->pw_passwd == NULL
+-	    || result->pw_gecos == NULL || result->pw_dir == NULL
+-	    || result->pw_shell == NULL)
+-	  {
+-	    *errnop = ERANGE;
+-	    res = NSS_STATUS_TRYAGAIN;
+-	  }
+-
+-	return res;
++	return copy_group (result, &grp_data[idx], buffer, buflen, errnop);
+       }
+ 
+   return NSS_STATUS_NOTFOUND;
+diff --git a/nss/nss_test2.c b/nss/nss_test2.c
+new file mode 100644
+index 0000000000..0169344e5f
+--- /dev/null
++++ b/nss/nss_test2.c
+@@ -0,0 +1,20 @@
++/* Instance of a generic NSS service provider.  See nss_test.h for usage.
++   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/>.  */
++
++#define NAME(x) NAME_(x,test2)
++#include "nss_test1.c"
+diff --git a/nss/tst-nss-test2.c b/nss/tst-nss-test2.c
+new file mode 100644
+index 0000000000..11c2edf118
+--- /dev/null
++++ b/nss/tst-nss-test2.c
+@@ -0,0 +1,136 @@
++/* Basic test for two passwd databases.
++   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/>.  */
++
++#include <nss.h>
++#include <pwd.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include "nss_test.h"
++
++/* The data in these tables is arbitrary, but the merged data based on
++   the first two tables will be compared against the expected data in
++   the pwd_expected table, and the tests[] array.  */
++
++static struct passwd pwd_table_1[] = {
++    PWD (100),
++    PWD (30),
++    PWD (200),
++    PWD (60),
++    PWD (20000),
++    PWD_LAST ()
++  };
++
++static struct passwd pwd_table_2[] = {
++    PWD (5),
++    PWD_N(200, "name30"),
++    PWD (16),
++    PWD_LAST ()
++  };
++
++void
++_nss_test1_init_hook(test_tables *t)
++{
++  t->pwd_table = pwd_table_1;
++}
++
++void
++_nss_test2_init_hook(test_tables *t)
++{
++  t->pwd_table = pwd_table_2;
++}
++
++static struct passwd pwd_expected[] = {
++  PWD(100),
++  PWD(30),
++  PWD(200),
++  PWD(60),
++  PWD(20000),
++  PWD(5),
++  PWD_N(200, "name30"),
++  PWD(16),
++  PWD_LAST ()
++};
++
++static struct {
++  uid_t uid;
++  const char *name;
++} tests[] = {
++  { 100, "name100" }, /* control, first db */
++  {  16, "name16"  }, /* second db */
++  {  30, "name30"  }, /* test overlaps in name */
++  { 200, "name200" }, /* test overlaps uid */
++  { 0, NULL }
++};
++
++static int
++do_test (void)
++{
++  int retval = 0;
++  int i;
++
++  __nss_configure_lookup ("passwd", "test1 test2");
++
++  setpwent ();
++
++  i = 0;
++  for (struct passwd *p = getpwent (); p != NULL; ++i, p = getpwent ())
++    {
++      retval += compare_passwds (i, & pwd_expected[i], p);
++
++      if (p->pw_uid != pwd_expected[i].pw_uid || strcmp (p->pw_name, pwd_expected[i].pw_name) != 0)
++      {
++	printf ("FAIL: getpwent for %u.%s returned %u.%s\n",
++		pwd_expected[i].pw_uid, pwd_expected[i].pw_name,
++		p->pw_uid, p->pw_name);
++	retval = 1;
++	break;
++      }
++    }
++
++  endpwent ();
++
++  for (i=0; tests[i].name; i++)
++    {
++      struct passwd *p = getpwnam (tests[i].name);
++      if (strcmp (p->pw_name, tests[i].name) != 0
++	  || p->pw_uid != tests[i].uid)
++	{
++	  printf("FAIL: getpwnam for %u.%s returned %u.%s\n",
++		 tests[i].uid, tests[i].name,
++		 p->pw_uid, p->pw_name);
++	  retval = 1;
++	}
++
++      p = getpwuid (tests[i].uid);
++      if (strcmp (p->pw_name, tests[i].name) != 0
++	  || p->pw_uid != tests[i].uid)
++	{
++	  printf("FAIL: getpwuid for %u.%s returned %u.%s\n",
++		 tests[i].uid, tests[i].name,
++		 p->pw_uid, p->pw_name);
++	  retval = 1;
++	}
++    }
++
++  return retval;
++}
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
+diff --git a/nss/tst-nss-test3.c b/nss/tst-nss-test3.c
+new file mode 100644
+index 0000000000..308708f387
+--- /dev/null
++++ b/nss/tst-nss-test3.c
+@@ -0,0 +1,150 @@
++/* Test error checking for group entries.
++   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/>.  */
++
++#include <nss.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/signal.h>
++
++#include "nss_test.h"
++
++/* The names here are arbitrary, but the *lengths* of the arrays is
++   not, and groups 6 and 7 test for partial matches.  */
++
++static const char *group_2[] = {
++  "foo", "bar", NULL
++};
++
++static const char *group_3[] = {
++  "tom", "dick", "harry", NULL
++};
++
++static const char *group_4[] = {
++  "alpha", "beta", "gamma", "fred", NULL
++};
++
++static const char *group_6[] = {
++  "larry", "curly", "moe", NULL
++};
++
++static const char *group_7[] = {
++  "larry", "curly", "darryl", NULL
++};
++
++static const char *group_14[] = {
++  "huey", "dewey", "louis", NULL
++};
++
++/* Note that we're intentionally causing mis-matches here; the purpose
++   of this test case is to test each error check and make sure they
++   detect the errors they check for, and to ensure that the harness
++   can process all the error cases properly (i.e. a NULL gr_name
++   field).  We check for the correct number of mismatches at the
++   end.  */
++
++/* This is the data we're giving the service.  */
++static struct group group_table_data[] = {
++  GRP(4), /* match */
++  GRP_N(8, "name6", group_6), /* wrong gid */
++  GRP_N(14, NULL, group_14), /* missing name */
++  GRP(14), /* unexpected name */
++  GRP_N(7, "name7_wrong", group_7), /* wrong name */
++  { .gr_name =  (char *)"name5", .gr_passwd =  (char *)"wilma", .gr_gid = 5, .gr_mem = NULL }, /* unexpected passwd */
++  { .gr_name =  (char *)"name5", .gr_passwd = NULL, .gr_gid = 5, .gr_mem = NULL }, /* missing passwd */
++  { .gr_name =  (char *)"name5", .gr_passwd = (char *)"wilma", .gr_gid = 5, .gr_mem = NULL }, /* wrong passwd */
++  GRP_N(3, "name3a", NULL),   /* missing member list */
++  GRP_N(3, "name3b", group_3), /* unexpected member list */
++  GRP_N(3, "name3c", group_3), /* wrong/short member list */
++  GRP_N(3, "name3d", group_4), /* wrong/long member list */
++  GRP_LAST ()
++};
++
++/* This is the data we compare against.  */
++static struct group group_table[] = {
++  GRP(4),
++  GRP(6),
++  GRP(14),
++  GRP_N(14, NULL, group_14),
++  GRP(7),
++  { .gr_name =  (char *)"name5", .gr_passwd = NULL, .gr_gid = 5, .gr_mem = NULL },
++  { .gr_name =  (char *)"name5", .gr_passwd =  (char *)"fred", .gr_gid = 5, .gr_mem = NULL },
++  { .gr_name =  (char *)"name5", .gr_passwd =  (char *)"fred", .gr_gid = 5, .gr_mem = NULL },
++  GRP_N(3, "name3a", group_3),
++  GRP_N(3, "name3b", NULL),
++  GRP_N(3, "name3c", group_4),
++  GRP_N(3, "name3d", group_3),
++  GRP(2),
++  GRP_LAST ()
++};
++
++void
++_nss_test1_init_hook(test_tables *t)
++{
++  t->grp_table = group_table_data;
++}
++
++static int
++do_test (void)
++{
++  int retval = 0;
++  int i;
++  struct group *g = NULL;
++
++  __nss_configure_lookup ("group", "test1");
++
++  setgrent ();
++
++  i = 0;
++  for (g = getgrent () ;
++       g != NULL && ! GRP_ISLAST(&group_table[i]);
++       ++i, g = getgrent ())
++    {
++      retval += compare_groups (i, g, & group_table[i]);
++    }
++
++  endgrent ();
++
++  if (g)
++    {
++      printf ("FAIL: [?] group entry %u.%s unexpected\n", g->gr_gid, g->gr_name);
++      ++retval;
++    }
++  if (group_table[i].gr_name || group_table[i].gr_gid)
++    {
++      printf ("FAIL: [%d] group entry %u.%s missing\n", i,
++	      group_table[i].gr_gid, group_table[i].gr_name);
++      ++retval;
++    }
++
++#define EXPECTED 18
++  if (retval == EXPECTED)
++    {
++      if (retval > 0)
++	printf ("PASS: Found %d expected errors\n", retval);
++      return 0;
++    }
++  else
++    {
++      printf ("FAIL: Found %d errors, expected %d\n", retval, EXPECTED);
++      return 1;
++    }
++}
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
+diff --git a/nss/tst-nss-test4.c b/nss/tst-nss-test4.c
+new file mode 100644
+index 0000000000..731e0ed10a
+--- /dev/null
++++ b/nss/tst-nss-test4.c
+@@ -0,0 +1,137 @@
++/* Test group merging.
++   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/>.  */
++
++#include <nss.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/signal.h>
++
++#include "nss_test.h"
++
++/* The name choices here are arbitrary, aside from the merge_1 list
++   needing to be an expected merge of group_1 and group_2.  */
++
++static const char *group_1[] = {
++  "foo", "bar", NULL
++};
++
++static const char *group_2[] = {
++  "foo", "dick", "harry", NULL
++};
++
++/* Note that deduplication is NOT supposed to happen.  */
++static const char *merge_1[] = {
++  "foo", "bar", "foo", "dick", "harry", NULL
++};
++
++static const char *group_4[] = {
++  "fred", "wilma", NULL
++};
++
++/* This is the data we're giving the service.  */
++static struct group group_table_data1[] = {
++  GRP_N(1, "name1", group_1),
++  GRP(2),
++  GRP_LAST ()
++};
++
++/* This is the data we're giving the service.  */
++static struct group group_table_data2[] = {
++  GRP_N(1, "name1", group_2),
++  GRP(4),
++  GRP_LAST ()
++};
++
++/* This is the data we compare against.  */
++static struct group group_table[] = {
++  GRP_N(1, "name1", merge_1),
++  GRP(2),
++  GRP(4),
++  GRP_LAST ()
++};
++
++void
++_nss_test1_init_hook(test_tables *t)
++{
++  t->grp_table = group_table_data1;
++}
++
++void
++_nss_test2_init_hook(test_tables *t)
++{
++  t->grp_table = group_table_data2;
++}
++
++static int
++do_test (void)
++{
++  int retval = 0;
++  int i;
++  struct group *g = NULL;
++  uintptr_t align_mask;
++
++  __nss_configure_lookup ("group", "test1 [SUCCESS=merge] test2");
++
++  align_mask = __alignof__ (struct group *) - 1;
++
++  setgrent ();
++
++  for (i = 0; group_table[i].gr_gid; ++i)
++    {
++      g = getgrgid (group_table[i].gr_gid);
++      if (g)
++	{
++	  retval += compare_groups (i, g, & group_table[i]);
++	  if ((uintptr_t)g & align_mask)
++	    {
++	      printf("FAIL: [%d] unaligned group %p\n", i, g);
++	      ++retval;
++	    }
++	  if ((uintptr_t)(g->gr_mem) & align_mask)
++	    {
++	      printf("FAIL: [%d] unaligned member list %p\n", i, g->gr_mem);
++	      ++retval;
++	    }
++	}
++      else
++	{
++	  printf ("FAIL: [%d] group %u.%s not found\n", i,
++	      group_table[i].gr_gid, group_table[i].gr_name);
++	  ++retval;
++	}
++    }
++
++  endgrent ();
++
++#define EXPECTED 0
++  if (retval == EXPECTED)
++    {
++      if (retval > 0)
++	printf ("PASS: Found %d expected errors\n", retval);
++      return 0;
++    }
++  else
++    {
++      printf ("FAIL: Found %d errors, expected %d\n", retval, EXPECTED);
++      return 1;
++    }
++}
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
+diff --git a/nss/tst-nss-test5.c b/nss/tst-nss-test5.c
+new file mode 100644
+index 0000000000..b70f21e8e5
+--- /dev/null
++++ b/nss/tst-nss-test5.c
+@@ -0,0 +1,108 @@
++/* Test error checking for passwd entries.
++   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/>.  */
++
++#include <nss.h>
++#include <pwd.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include "nss_test.h"
++
++/* The specific values and names used here are arbitrary, other than
++   correspondence (with suitable differences according to the tests as
++   commented) between the given and expected entries.  */
++
++static struct passwd pwd_table[] = {
++  PWD (100),  /* baseline, matches */
++  PWD (300),  /* wrong name and uid */
++  PWD_N (200, NULL), /* missing name */
++  PWD (60), /* unexpected name */
++  { .pw_name = (char *)"name20000",  .pw_passwd = (char *) "*", .pw_uid = 20000,  \
++    .pw_gid = 200, .pw_gecos = (char *) "*", .pw_dir = (char *) "*",	\
++    .pw_shell = (char *) "*" }, /* wrong gid */
++  { .pw_name = (char *)"name2",  .pw_passwd = (char *) "x", .pw_uid = 2,  \
++    .pw_gid = 2, .pw_gecos = (char *) "y", .pw_dir = (char *) "z",	\
++    .pw_shell = (char *) "*" }, /* spot check other text fields */
++  PWD_LAST ()
++};
++
++static struct passwd exp_table[] = {
++  PWD (100),
++  PWD (30),
++  PWD (200),
++  PWD_N (60, NULL),
++  PWD (20000),
++  PWD (2),
++  PWD_LAST ()
++};
++
++void
++_nss_test1_init_hook(test_tables *t)
++{
++  t->pwd_table = pwd_table;
++}
++
++static int
++do_test (void)
++{
++  int retval = 0;
++  int i;
++  struct passwd *p;
++
++  __nss_configure_lookup ("passwd", "test1 test2");
++
++  setpwent ();
++
++  i = 0;
++  for (p = getpwent ();
++       p != NULL && ! PWD_ISLAST (& exp_table[i]);
++       ++i, p = getpwent ())
++    retval += compare_passwds (i, p, & exp_table[i]);
++
++  endpwent ();
++
++
++  if (p)
++    {
++      printf ("FAIL: [?] passwd entry %u.%s unexpected\n", p->pw_uid, p->pw_name);
++      ++retval;
++    }
++  if (! PWD_ISLAST (& exp_table[i]))
++    {
++      printf ("FAIL: [%d] passwd entry %u.%s missing\n", i,
++	      exp_table[i].pw_uid, exp_table[i].pw_name);
++      ++retval;
++    }
++
++#define EXPECTED 9
++  if (retval == EXPECTED)
++    {
++      if (retval > 0)
++	printf ("PASS: Found %d expected errors\n", retval);
++      return 0;
++    }
++  else
++    {
++      printf ("FAIL: Found %d errors, expected %d\n", retval, EXPECTED);
++      return 1;
++    }
++}
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
diff --git a/SOURCES/glibc-rh1636229-2.patch b/SOURCES/glibc-rh1636229-2.patch
new file mode 100644
index 0000000..0e4fb4a
--- /dev/null
+++ b/SOURCES/glibc-rh1636229-2.patch
@@ -0,0 +1,196 @@
+commit a3fe6a20bf81ef6a97a761dac9050517e7fd7a1f
+Author: DJ Delorie <dj@redhat.com>
+Date:   Thu Aug 17 17:58:25 2017 -0400
+
+    Update nss tests to new skeleton
+    
+    * bug17079.c: Update to new test harness.
+    * test-digits-dots.c: Likewise.
+    * test-netdb.c: Likewise.
+    * tst-field.c: Likewise.
+    * tst-nss-getpwent.c: Likewise.
+    * tst-nss-static.c: Likewise.
+    * tst-nss-test1.c: Likewise.
+    * tst-nss-test2.c: Likewise.
+    * tst-nss-test3.c: Likewise.
+    * tst-nss-test4.c: Likewise.
+    * tst-nss-test5.c: Likewise.
+
+Partial port of this patch - tst-field.c changes not ported.
+
+diff --git a/nss/bug17079.c b/nss/bug17079.c
+index 4171c7db55..09d33f018c 100644
+--- a/nss/bug17079.c
++++ b/nss/bug17079.c
+@@ -23,6 +23,8 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
++#include <support/support.h>
++
+ /* Check if two passwd structs contain the same data.  */
+ static bool
+ equal (const struct passwd *a, const struct passwd *b)
+@@ -52,13 +54,13 @@ init_test_items (void)
+       if (pwd == NULL)
+         break;
+       struct passwd *target = test_items + test_count;
+-      target->pw_name = strdup (pwd->pw_name);
+-      target->pw_passwd = strdup (pwd->pw_passwd);
++      target->pw_name = xstrdup (pwd->pw_name);
++      target->pw_passwd = xstrdup (pwd->pw_passwd);
+       target->pw_uid = pwd->pw_uid;
+       target->pw_gid = pwd->pw_gid;
+-      target->pw_gecos = strdup (pwd->pw_gecos);
+-      target->pw_dir = strdup (pwd->pw_dir);
+-      target->pw_shell = strdup (pwd->pw_shell);
++      target->pw_gecos = xstrdup (pwd->pw_gecos);
++      target->pw_dir = xstrdup (pwd->pw_dir);
++      target->pw_shell = xstrdup (pwd->pw_shell);
+     }
+   while (++test_count < MAX_TEST_ITEMS);
+   endpwent ();
+@@ -108,13 +110,7 @@ static void
+ test_one (const struct passwd *item, size_t buffer_size,
+            char pad, size_t padding_size)
+ {
+-  char *buffer = malloc (buffer_size + padding_size);
+-  if (buffer == NULL)
+-    {
+-      puts ("error: malloc failure");
+-      errors = true;
+-      return;
+-    }
++  char *buffer = xmalloc (buffer_size + padding_size);
+ 
+   struct passwd pwd;
+   struct passwd *result;
+@@ -240,5 +236,4 @@ do_test (void)
+     return 0;
+ }
+ 
+-#define TEST_FUNCTION do_test ()
+-#include "../test-skeleton.c"
++#include <support/test-driver.c>
+diff --git a/nss/test-digits-dots.c b/nss/test-digits-dots.c
+index 2685161e65..5b898a932d 100644
+--- a/nss/test-digits-dots.c
++++ b/nss/test-digits-dots.c
+@@ -21,6 +21,8 @@
+ #include <netdb.h>
+ #include <errno.h>
+ 
++#include <support/support.h>
++
+ static int
+ do_test (void)
+ {
+@@ -34,5 +36,4 @@ do_test (void)
+   return err == ERANGE && h_err == NETDB_INTERNAL ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+ 
+-#define TEST_FUNCTION do_test ()
+-#include "../test-skeleton.c"
++#include <support/test-driver.c>
+diff --git a/nss/tst-nss-static.c b/nss/tst-nss-static.c
+index 98cf073deb..6c3dc07622 100644
+--- a/nss/tst-nss-static.c
++++ b/nss/tst-nss-static.c
+@@ -1,7 +1,8 @@
+ /* glibc test for static NSS.  */
+ #include <stdio.h>
+ 
+-#define TEST_FUNCTION do_test ()
++#include <support/support.h>
++
+ static int
+ do_test (void)
+ {
+@@ -12,4 +13,4 @@ do_test (void)
+ }
+ 
+ 
+-#include "../test-skeleton.c"
++#include <support/test-driver.c>
+diff --git a/nss/tst-nss-test2.c b/nss/tst-nss-test2.c
+index 11c2edf118..ac45d58c4b 100644
+--- a/nss/tst-nss-test2.c
++++ b/nss/tst-nss-test2.c
+@@ -22,6 +22,8 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
++#include <support/support.h>
++
+ #include "nss_test.h"
+ 
+ /* The data in these tables is arbitrary, but the merged data based on
+@@ -132,5 +134,4 @@ do_test (void)
+   return retval;
+ }
+ 
+-#define TEST_FUNCTION do_test ()
+-#include "../test-skeleton.c"
++#include <support/test-driver.c>
+diff --git a/nss/tst-nss-test3.c b/nss/tst-nss-test3.c
+index 308708f387..5098aae67b 100644
+--- a/nss/tst-nss-test3.c
++++ b/nss/tst-nss-test3.c
+@@ -20,7 +20,8 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+-#include <sys/signal.h>
++
++#include <support/support.h>
+ 
+ #include "nss_test.h"
+ 
+@@ -146,5 +147,4 @@ do_test (void)
+     }
+ }
+ 
+-#define TEST_FUNCTION do_test ()
+-#include "../test-skeleton.c"
++#include <support/test-driver.c>
+diff --git a/nss/tst-nss-test4.c b/nss/tst-nss-test4.c
+index 731e0ed10a..6e0ac84acc 100644
+--- a/nss/tst-nss-test4.c
++++ b/nss/tst-nss-test4.c
+@@ -20,7 +20,8 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+-#include <sys/signal.h>
++
++#include <support/support.h>
+ 
+ #include "nss_test.h"
+ 
+@@ -133,5 +134,4 @@ do_test (void)
+     }
+ }
+ 
+-#define TEST_FUNCTION do_test ()
+-#include "../test-skeleton.c"
++#include <support/test-driver.c>
+diff --git a/nss/tst-nss-test5.c b/nss/tst-nss-test5.c
+index fef41f08df..8f02cb7779 100644
+--- a/nss/tst-nss-test5.c
++++ b/nss/tst-nss-test5.c
+@@ -22,6 +22,8 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
++#include <support/support.h>
++
+ #include "nss_test.h"
+ 
+ /* The specific values and names used here are arbitrary, other than
+@@ -104,5 +106,4 @@ do_test (void)
+     }
+ }
+ 
+-#define TEST_FUNCTION do_test ()
+-#include "../test-skeleton.c"
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1636229-3.patch b/SOURCES/glibc-rh1636229-3.patch
new file mode 100644
index 0000000..2058cb3
--- /dev/null
+++ b/SOURCES/glibc-rh1636229-3.patch
@@ -0,0 +1,294 @@
+This file contains the reworked/backported sections from these two
+upstream commits:
+
+commit ae5c498d93d049d9574d3f8f18e62cac64cbdf5c
+Author: DJ Delorie <dj@delorie.com>
+Date:   Mon Jul 17 15:50:43 2017 -0400
+
+    Extend NSS test suite
+
+commit a3fe6a20bf81ef6a97a761dac9050517e7fd7a1f
+Author: DJ Delorie <dj@redhat.com>
+Date:   Thu Aug 17 17:58:25 2017 -0400
+
+    Update nss tests to new skeleton
+ 
+diff -Nrup a/nss/Makefile b/nss/Makefile
+--- a/nss/Makefile	2019-07-29 22:25:16.482170120 -0400
++++ b/nss/Makefile	2019-07-29 22:37:05.675342258 -0400
+@@ -38,8 +38,14 @@ install-bin             := getent makedb
+ makedb-modules = xmalloc hash-string
+ extra-objs		+= $(makedb-modules:=.o)
+ 
+-tests			= test-netdb tst-nss-test1 bug17079 tst-nss-getpwent \
+-			 test-digits-dots tst-nss-files-hosts-erange
++tests                  = test-netdb test-digits-dots tst-nss-getpwent bug17079 \
++			 tst-nss-files-hosts-erange \
++                         tst-nss-test1 \
++                         tst-nss-test2 \
++                         tst-nss-test3 \
++                         tst-nss-test4 \
++                         tst-nss-test5
++
+ xtests			= bug-erange
+ 
+ include ../Makeconfig
+@@ -80,6 +86,8 @@ tests-static		= tst-nss-static
+ tests			+= $(tests-static)
+ endif
+ 
++extra-test-objs                += nss_test1.os nss_test2.os
++
+ include ../Rules
+ 
+ ifeq (yes,$(have-selinux))
+@@ -107,13 +115,28 @@ $(objpfx)makedb: $(makedb-modules:%=$(ob
+ $(inst_vardbdir)/Makefile: db-Makefile $(+force)
+ 	$(do-install)
+ 
++libnss_test1.so-no-z-defs = 1
++libnss_test2.so-no-z-defs = 1
++
++rtld-tests-LDFLAGS += -Wl,--dynamic-list=nss_test.ver
++
+ libof-nss_test1 = extramodules
++libof-nss_test2 = extramodules
+ $(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(link-libc-deps)
+ 	$(build-module)
++$(objpfx)/libnss_test2.so: $(objpfx)nss_test2.os $(link-libc-deps)
++	$(build-module)
++$(objpfx)nss_test2.os : nss_test1.c
+ ifdef libnss_test1.so-version
+ $(objpfx)/libnss_test1.so$(libnss_test1.so-version): $(objpfx)/libnss_test1.so
+ 	$(make-link)
+ endif
+-$(objpfx)tst-nss-test1.out: $(objpfx)/libnss_test1.so$(libnss_test1.so-version)
++ifdef libnss_test2.so-version
++$(objpfx)/libnss_test2.so$(libnss_test2.so-version): $(objpfx)/libnss_test2.so
++	$(make-link)
++endif
++$(patsubst %,$(objpfx)%.out,$(tests)) : \
++	$(objpfx)/libnss_test1.so$(libnss_test1.so-version) \
++	$(objpfx)/libnss_test2.so$(libnss_test2.so-version)
+ 
+ $(objpfx)tst-nss-files-hosts-erange: $(libdl)
+diff -Nrup a/nss/tst-nss-getpwent.c b/nss/tst-nss-getpwent.c
+--- a/nss/tst-nss-getpwent.c	2019-07-29 16:44:37.670904243 -0400
++++ b/nss/tst-nss-getpwent.c	2019-07-29 16:49:58.538313946 -0400
+@@ -21,6 +21,8 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
++#include <support/support.h>
++
+ int
+ do_test (void)
+ {
+@@ -37,22 +39,12 @@ do_test (void)
+     {
+       if (first_name == NULL)
+ 	{
+-	  first_name = strdup (pw->pw_name);
+-	  if (first_name == NULL)
+-	    {
+-	      printf ("strdup: %m\n");
+-	      return 1;
+-	    }
++          first_name = xstrdup (pw->pw_name);
+ 	  first_uid = pw->pw_uid;
+ 	}
+       
+       free (last_name);
+-      last_name = strdup (pw->pw_name);
+-      if (last_name == NULL)
+-	{
+-	  printf ("strdup: %m\n");
+-	  return 1;
+-	}
++      last_name = xstrdup (pw->pw_name);
+       last_uid = pw->pw_uid;
+       ++count;
+     }
+@@ -112,5 +104,4 @@ do_test (void)
+   return 0;
+ }
+ 
+-#define TEST_FUNCTION do_test ()
+-#include "../test-skeleton.c"
++#include <support/test-driver.c>
+diff -Nrup a/shlib-versions b/shlib-versions
+--- a/shlib-versions	2019-07-29 16:50:46.222077613 -0400
++++ b/shlib-versions	2019-07-29 16:53:04.745391058 -0400
+@@ -87,6 +87,7 @@ sh.*-.*-linux.*		ld=ld-linux.so.2	GLIBC_
+ # Tests for NSS.  They must have the same NSS_SHLIB_REVISION number as
+ # the rest.
+ .*-.*-.*		libnss_test1=2
++.*-.*-.*                libnss_test2=2
+ 
+ # Version for libnsl with YP and NIS+ functions.
+ .*-.*-.*		libnsl=1
+diff -Nrup a/nss/tst-nss-test1.c b/nss/tst-nss-test1.c
+--- a/nss/tst-nss-test1.c	2019-07-29 16:54:05.824241220 -0400
++++ b/nss/tst-nss-test1.c	2019-07-29 17:13:55.696765720 -0400
+@@ -1,9 +1,51 @@
++/* Basic test of passwd database handling.
++   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/>.  */
++
+ #include <nss.h>
+ #include <pwd.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ 
++#include <support/support.h>
++
++#include "nss_test.h"
++
++static int hook_called = 0;
++
++/* Note: the values chosen here are arbitrary; they need only be
++   unique within the table.  However, they do need to match the
++   "pwdids" array further down.  */
++static struct passwd pwd_table[] = {
++    PWD (100),
++    PWD (30),
++    PWD (200),
++    PWD (60),
++    PWD (20000),
++    PWD_LAST ()
++  };
++
++void
++_nss_test1_init_hook(test_tables *t)
++{
++  hook_called = 1;
++  t->pwd_table = pwd_table;
++}
+ 
+ static int
+ do_test (void)
+@@ -12,20 +54,26 @@ do_test (void)
+ 
+   __nss_configure_lookup ("passwd", "test1");
+ 
++  /* This must match the pwd_table above.  */
+   static const unsigned int pwdids[] = { 100, 30, 200, 60, 20000 };
+ #define npwdids (sizeof (pwdids) / sizeof (pwdids[0]))
++
+   setpwent ();
+ 
+   const unsigned int *np = pwdids;
+   for (struct passwd *p = getpwent (); p != NULL; ++np, p = getpwent ())
+-    if (p->pw_uid != *np || strncmp (p->pw_name, "name", 4) != 0
+-	|| atol (p->pw_name + 4) != *np)
+-      {
+-	printf ("passwd entry %td wrong (%s, %u)\n",
+-		np - pwdids, p->pw_name, p->pw_uid);
+-	retval = 1;
+-	break;
+-      }
++    {
++      retval += compare_passwds (np-pwdids, p, & pwd_table[np-pwdids]);
++
++      if (p->pw_uid != *np || strncmp (p->pw_name, "name", 4) != 0
++         || atol (p->pw_name + 4) != *np)
++       {
++         printf ("FAIL: passwd entry %td wrong (%s, %u)\n",
++                 np - pwdids, p->pw_name, p->pw_uid);
++         retval = 1;
++         break;
++       }
++    }
+ 
+   endpwent ();
+ 
+@@ -37,14 +85,14 @@ do_test (void)
+       struct passwd *p = getpwnam (buf);
+       if (p == NULL || p->pw_uid != pwdids[i] || strcmp (buf, p->pw_name) != 0)
+ 	{
+-	  printf ("passwd entry \"%s\" wrong\n", buf);
++          printf ("FAIL: passwd entry \"%s\" wrong\n", buf);
+ 	  retval = 1;
+ 	}
+ 
+       p = getpwuid (pwdids[i]);
+       if (p == NULL || p->pw_uid != pwdids[i] || strcmp (buf, p->pw_name) != 0)
+ 	{
+-	  printf ("passwd entry %u wrong\n", pwdids[i]);
++          printf ("FAIL: passwd entry %u wrong\n", pwdids[i]);
+ 	  retval = 1;
+ 	}
+ 
+@@ -53,20 +101,25 @@ do_test (void)
+       p = getpwnam (buf);
+       if (p != NULL)
+ 	{
+-	  printf ("passwd entry \"%s\" wrong\n", buf);
++          printf ("FAIL: passwd entry \"%s\" wrong\n", buf);
+ 	  retval = 1;
+ 	}
+ 
+       p = getpwuid (pwdids[i] + 1);
+       if (p != NULL)
+ 	{
+-	  printf ("passwd entry %u wrong\n", pwdids[i] + 1);
++          printf ("FAIL: passwd entry %u wrong\n", pwdids[i] + 1);
+ 	  retval = 1;
+ 	}
+     }
+ 
++  if (!hook_called)
++    {
++      retval = 1;
++      printf("FAIL: init hook never called\n");
++    }
++
+   return retval;
+ }
+ 
+-#define TEST_FUNCTION do_test ()
+-#include "../test-skeleton.c"
++#include <support/test-driver.c>
+diff -Nrup a/nss/test-netdb.c b/nss/test-netdb.c
+--- a/nss/test-netdb.c	2019-07-30 15:31:30.468602060 -0400
++++ b/nss/test-netdb.c	2019-07-30 15:37:29.116601115 -0400
+@@ -42,6 +42,8 @@
+ #include <errno.h>
+ #include "nss.h"
+ 
++#include <support/support.h>
++
+ /*
+   The following define is necessary for glibc 2.0.6
+ */
+@@ -179,7 +181,7 @@ test_hosts (void)
+   while (gethostname (name, namelen) < 0 && errno == ENAMETOOLONG)
+     {
+       namelen += 2;		/* tiny increments to test a lot */
+-      name = realloc (name, namelen);
++      name = xrealloc (name, namelen);
+     }
+   if (gethostname (name, namelen) == 0)
+     {
+@@ -377,5 +379,4 @@ do_test (void)
+   return (error_count != 0);
+ }
+ 
+-#define TEST_FUNCTION do_test ()
+-#include "../test-skeleton.c"
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-rh1636229-4.patch b/SOURCES/glibc-rh1636229-4.patch
new file mode 100644
index 0000000..b165be7
--- /dev/null
+++ b/SOURCES/glibc-rh1636229-4.patch
@@ -0,0 +1,21 @@
+NOTE: This is a downstream patch that should not go upstream.
+
+diff -Nrup a/nss/Makefile b/nss/Makefile
+--- a/nss/Makefile	2019-07-30 13:28:36.493476963 -0400
++++ b/nss/Makefile	2019-07-30 13:33:14.536086456 -0400
+@@ -118,7 +118,14 @@ $(inst_vardbdir)/Makefile: db-Makefile $
+ libnss_test1.so-no-z-defs = 1
+ libnss_test2.so-no-z-defs = 1
+ 
+-rtld-tests-LDFLAGS += -Wl,--dynamic-list=nss_test.ver
++# RHEL 7 glibc tree does not support rtld-tests-LDFLAGS.
++# Instead we directly alter the way the tests are built.
++# rtld-tests-LDFLAGS += -Wl,--dynamic-list=nss_test.ver
++LDFLAGS-tst-nss-test1 += -Wl,-E
++LDFLAGS-tst-nss-test2 += -Wl,-E
++LDFLAGS-tst-nss-test3 += -Wl,-E
++LDFLAGS-tst-nss-test4 += -Wl,-E
++LDFLAGS-tst-nss-test5 += -Wl,-E
+ 
+ libof-nss_test1 = extramodules
+ libof-nss_test2 = extramodules
diff --git a/SOURCES/glibc-rh1670041.patch b/SOURCES/glibc-rh1670041.patch
new file mode 100644
index 0000000..a6ab8fe
--- /dev/null
+++ b/SOURCES/glibc-rh1670041.patch
@@ -0,0 +1,104 @@
+commit 08504de71813ddbd447bfbca4a325cbe8ce8bcda
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Mar 12 11:40:47 2019 +0100
+
+    resolv: Enable full ICMP errors for UDP DNS sockets [BZ #24047]
+    
+    The Linux kernel suppresses some ICMP error messages by default for
+    UDP sockets.  This commit enables full ICMP error reporting,
+    hopefully resulting in faster failover to working name servers.
+
+diff --git a/resolv/Makefile b/resolv/Makefile
+index 033c3c651f0deb1b..133fe5885c5b65b5 100644
+--- a/resolv/Makefile
++++ b/resolv/Makefile
+@@ -92,7 +92,7 @@ libresolv-routines := res_comp res_debug \
+ 		      res_data res_mkquery res_query res_send		\
+ 		      inet_net_ntop inet_net_pton inet_neta base64	\
+ 		      ns_parse ns_name ns_netint ns_ttl ns_print	\
+-		      ns_samedomain ns_date \
++		      ns_samedomain ns_date res_enable_icmp \
+ 		      compat-hooks compat-gethnamaddr
+ 
+ libanl-routines := gai_cancel gai_error gai_misc gai_notify gai_suspend \
+diff --git a/resolv/res_enable_icmp.c b/resolv/res_enable_icmp.c
+new file mode 100644
+index 0000000000000000..bdc9220f08cef71d
+--- /dev/null
++++ b/resolv/res_enable_icmp.c
+@@ -0,0 +1,37 @@
++/* Enable full ICMP errors on a socket.
++   Copyright (C) 2019 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 <errno.h>
++#include <netinet/in.h>
++#include <sys/socket.h>
++
++int
++__res_enable_icmp (int family, int fd)
++{
++  int one = 1;
++  switch (family)
++    {
++    case AF_INET:
++      return setsockopt (fd, SOL_IP, IP_RECVERR, &one, sizeof (one));
++    case AF_INET6:
++      return setsockopt (fd, SOL_IPV6, IPV6_RECVERR, &one, sizeof (one));
++    default:
++      __set_errno (EAFNOSUPPORT);
++      return -1;
++    }
++}
+diff --git a/resolv/res_send.c b/resolv/res_send.c
+index 05c7ba511b0383c1..e57bb12a66b087e4 100644
+--- a/resolv/res_send.c
++++ b/resolv/res_send.c
+@@ -943,6 +943,18 @@ reopen (res_state statp, int *terrno, int ns)
+ 			return (-1);
+ 		}
+ 
++		/* Enable full ICMP error reporting for this
++		   socket.  */
++		if (__res_enable_icmp (nsap->sa_family,
++				       EXT (statp).nssocks[ns]) < 0)
++		  {
++		    int saved_errno = errno;
++		    __res_iclose (statp, false);
++		    __set_errno (saved_errno);
++		    *terrno = saved_errno;
++		    return -1;
++		  }
++
+ 		/*
+ 		 * On a 4.3BSD+ machine (client and server,
+ 		 * actually), sending to a nameserver datagram
+diff --git a/resolv/resolv-internal.h b/resolv/resolv-internal.h
+index 32dc44777e311849..d73a2c1b944bcbbe 100644
+--- a/resolv/resolv-internal.h
++++ b/resolv/resolv-internal.h
+@@ -97,4 +97,10 @@ int __res_nopt (struct resolv_context *, int n0,
+ int __inet_pton_length (int af, const char *src, size_t srclen, void *);
+ libc_hidden_proto (__inet_pton_length)
+ 
++/* The Linux kernel does not enable all ICMP messages on a UDP socket
++   by default.  A call this function enables full error reporting for
++   the socket FD.  FAMILY must be AF_INET or AF_INET6.  Returns 0 on
++   success, -1 on failure.  */
++int __res_enable_icmp (int family, int fd) attribute_hidden;
++
+ #endif  /* _RESOLV_INTERNAL_H */
diff --git a/SOURCES/glibc-rh1672771.patch b/SOURCES/glibc-rh1672771.patch
new file mode 100644
index 0000000..8898423
--- /dev/null
+++ b/SOURCES/glibc-rh1672771.patch
@@ -0,0 +1,200 @@
+commit 823624bdc47f1f80109c9c52dee7939b9386d708
+Author: Stefan Liebler <stli@linux.ibm.com>
+Date:   Thu Feb 7 15:18:36 2019 +0100
+
+    Add compiler barriers around modifications of the robust mutex list for pthread_mutex_trylock. [BZ #24180]
+
+    While debugging a kernel warning, Thomas Gleixner, Sebastian Sewior and
+    Heiko Carstens found a bug in pthread_mutex_trylock due to misordered
+    instructions:
+    140:   a5 1b 00 01             oill    %r1,1
+    144:   e5 48 a0 f0 00 00       mvghi   240(%r10),0   <--- THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+    14a:   e3 10 a0 e0 00 24       stg     %r1,224(%r10) <--- last THREAD_SETMEM of ENQUEUE_MUTEX_PI
+
+    vs (with compiler barriers):
+    140:   a5 1b 00 01             oill    %r1,1
+    144:   e3 10 a0 e0 00 24       stg     %r1,224(%r10)
+    14a:   e5 48 a0 f0 00 00       mvghi   240(%r10),0
+
+    Please have a look at the discussion:
+    "Re: WARN_ON_ONCE(!new_owner) within wake_futex_pi() triggerede"
+    (https://lore.kernel.org/lkml/20190202112006.GB3381@osiris/)
+
+    This patch is introducing the same compiler barriers and comments
+    for pthread_mutex_trylock as introduced for pthread_mutex_lock and
+    pthread_mutex_timedlock by commit 8f9450a0b7a9e78267e8ae1ab1000ebca08e473e
+    "Add compiler barriers around modifications of the robust mutex list."
+
+    ChangeLog:
+
+            [BZ #24180]
+            * nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock):
+
+
+diff -Nrup a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c
+--- a/nptl/pthread_mutex_trylock.c	2019-07-26 16:43:11.028271897 -0400
++++ b/nptl/pthread_mutex_trylock.c	2019-07-26 17:06:48.708748979 -0400
+@@ -95,6 +95,9 @@ __pthread_mutex_trylock (pthread_mutex_t
+     case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
+       THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ 		     &mutex->__data.__list.__next);
++      /* We need to set op_pending before starting the operation.  Also
++	 see comments at ENQUEUE_MUTEX.  */
++      __asm ("" ::: "memory");
+ 
+       oldval = mutex->__data.__lock;
+       do
+@@ -120,7 +123,12 @@ __pthread_mutex_trylock (pthread_mutex_t
+ 	      /* But it is inconsistent unless marked otherwise.  */
+ 	      mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
+ 
++	      /* We must not enqueue the mutex before we have acquired it.
++		 Also see comments at ENQUEUE_MUTEX.  */
++	      __asm ("" ::: "memory");
+ 	      ENQUEUE_MUTEX (mutex);
++	      /* We need to clear op_pending after we enqueue the mutex.  */
++	      __asm ("" ::: "memory");
+ 	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 
+ 	      /* Note that we deliberately exist here.  If we fall
+@@ -136,6 +144,8 @@ __pthread_mutex_trylock (pthread_mutex_t
+ 	      int kind = PTHREAD_MUTEX_TYPE (mutex);
+ 	      if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+ 		{
++		  /* We do not need to ensure ordering wrt another memory
++		     access.  Also see comments at ENQUEUE_MUTEX. */
+ 		  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ 				 NULL);
+ 		  return EDEADLK;
+@@ -143,6 +153,8 @@ __pthread_mutex_trylock (pthread_mutex_t
+ 
+ 	      if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
+ 		{
++		  /* We do not need to ensure ordering wrt another memory
++		     access.  */
+ 		  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ 				 NULL);
+ 
+@@ -160,6 +172,10 @@ __pthread_mutex_trylock (pthread_mutex_t
+ 	  oldval = lll_robust_trylock (mutex->__data.__lock, id);
+ 	  if (oldval != 0 && (oldval & FUTEX_OWNER_DIED) == 0)
+ 	    {
++             /* We haven't acquired the lock as it is already acquired by
++                another owner.  We do not need to ensure ordering wrt another
++                memory access.  */
++
+ 	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 
+ 	      return EBUSY;
+@@ -173,13 +189,20 @@ __pthread_mutex_trylock (pthread_mutex_t
+ 	      if (oldval == id)
+ 		lll_unlock (mutex->__data.__lock,
+ 			    PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
++	      /* FIXME This violates the mutex destruction requirements.  See
++		 __pthread_mutex_unlock_full.  */
+ 	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 	      return ENOTRECOVERABLE;
+ 	    }
+ 	}
+       while ((oldval & FUTEX_OWNER_DIED) != 0);
+ 
++      /* We must not enqueue the mutex before we have acquired it.
++	 Also see comments at ENQUEUE_MUTEX.  */
++      __asm ("" ::: "memory");
+       ENQUEUE_MUTEX (mutex);
++      /* We need to clear op_pending after we enqueue the mutex.  */
++      __asm ("" ::: "memory");
+       THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 
+       mutex->__data.__owner = id;
+@@ -201,10 +224,15 @@ __pthread_mutex_trylock (pthread_mutex_t
+ 	int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ 
+ 	if (robust)
+-	  /* Note: robust PI futexes are signaled by setting bit 0.  */
+-	  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+-			 (void *) (((uintptr_t) &mutex->__data.__list.__next)
+-				   | 1));
++         {
++           /* Note: robust PI futexes are signaled by setting bit 0.  */
++           THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
++                          (void *) (((uintptr_t) &mutex->__data.__list.__next)
++                                    | 1));
++           /* We need to set op_pending before starting the operation.  Also
++              see comments at ENQUEUE_MUTEX.  */
++           __asm ("" ::: "memory");
++         }
+ 
+ 	oldval = mutex->__data.__lock;
+ 
+@@ -213,12 +241,16 @@ __pthread_mutex_trylock (pthread_mutex_t
+ 	  {
+ 	    if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
+ 	      {
++		/* We do not need to ensure ordering wrt another memory
++		   access.  */
+ 		THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 		return EDEADLK;
+ 	      }
+ 
+ 	    if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
+ 	      {
++		/* We do not need to ensure ordering wrt another memory
++		   access.  */
+ 		THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 
+ 		/* Just bump the counter.  */
+@@ -240,6 +272,9 @@ __pthread_mutex_trylock (pthread_mutex_t
+ 	  {
+ 	    if ((oldval & FUTEX_OWNER_DIED) == 0)
+ 	      {
++		/* We haven't acquired the lock as it is already acquired by
++		   another owner.  We do not need to ensure ordering wrt another
++		   memory access.  */
+ 		THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 
+ 		return EBUSY;
+@@ -260,6 +295,9 @@ __pthread_mutex_trylock (pthread_mutex_t
+ 	    if (INTERNAL_SYSCALL_ERROR_P (e, __err)
+ 		&& INTERNAL_SYSCALL_ERRNO (e, __err) == EWOULDBLOCK)
+ 	      {
++		/* The kernel has not yet finished the mutex owner death.
++		   We do not need to ensure ordering wrt another memory
++		   access.  */
+ 		THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 
+ 		return EBUSY;
+@@ -277,7 +315,12 @@ __pthread_mutex_trylock (pthread_mutex_t
+ 	    /* But it is inconsistent unless marked otherwise.  */
+ 	    mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
+ 
++	    /* We must not enqueue the mutex before we have acquired it.
++	       Also see comments at ENQUEUE_MUTEX.  */
++	    __asm ("" ::: "memory");
+ 	    ENQUEUE_MUTEX (mutex);
++	    /* We need to clear op_pending after we enqueue the mutex.  */
++	    __asm ("" ::: "memory");
+ 	    THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 
+ 	    /* Note that we deliberately exit here.  If we fall
+@@ -300,13 +343,20 @@ __pthread_mutex_trylock (pthread_mutex_t
+ 						  PTHREAD_ROBUST_MUTEX_PSHARED (mutex)),
+ 			      0, 0);
+ 
++	    /* To the kernel, this will be visible after the kernel has
++	       acquired the mutex in the syscall.  */
+ 	    THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 	    return ENOTRECOVERABLE;
+ 	  }
+ 
+ 	if (robust)
+ 	  {
++	    /* We must not enqueue the mutex before we have acquired it.
++	       Also see comments at ENQUEUE_MUTEX.  */
++	    __asm ("" ::: "memory");
+ 	    ENQUEUE_MUTEX_PI (mutex);
++	    /* We need to clear op_pending after we enqueue the mutex.  */
++	    __asm ("" ::: "memory");
+ 	    THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+ 	  }
+ 
diff --git a/SOURCES/glibc-rh1691534-1.patch b/SOURCES/glibc-rh1691534-1.patch
new file mode 100644
index 0000000..1c38e4c
--- /dev/null
+++ b/SOURCES/glibc-rh1691534-1.patch
@@ -0,0 +1,46 @@
+commit ac64195ccd4f320659fd0058bc7524c6fd0b37b4
+Author: DJ Delorie <dj@redhat.com>
+Date:   Wed Mar 20 23:56:59 2019 -0400
+
+    iconv, localedef: avoid floating point rounding differences [BZ #24372]
+    
+    Two cases of "int * 1.4" may result in imprecise results, which
+    in at least one case resulted in i686 and x86-64 producing
+    different locale files.  This replaced that floating point multiply
+    with integer operations.  While the hash table margin is increased
+    from 40% to 50%, testing shows only 2% increase in overall size
+    of the locale archive.
+    
+    https://bugzilla.redhat.com/show_bug.cgi?id=1311954
+
+diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c
+index 0201450..1e6066c 100644
+--- a/iconv/iconvconfig.c
++++ b/iconv/iconvconfig.c
+@@ -1079,9 +1079,9 @@ write_output (void)
+ 
+   /* Create the hashing table.  We know how many strings we have.
+      Creating a perfect hash table is not reasonable here.  Therefore
+-     we use open hashing and a table size which is the next prime 40%
++     we use open hashing and a table size which is the next prime 50%
+      larger than the number of strings.  */
+-  hash_size = next_prime (nnames * 1.4);
++  hash_size = next_prime (nnames + nnames >> 1);
+   hash_table = (struct hash_entry *) xcalloc (hash_size,
+ 					      sizeof (struct hash_entry));
+   /* Fill the hash table.  */
+diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
+index bb4e2c5..19b23c2 100644
+--- a/locale/programs/ld-collate.c
++++ b/locale/programs/ld-collate.c
+@@ -2401,8 +2401,8 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
+ 
+       runp = runp->next;
+     }
+-  /* Add 40% and find the next prime number.  */
+-  elem_size = next_prime (elem_size * 1.4);
++  /* Add 50% and find the next prime number.  */
++  elem_size = next_prime (elem_size + elem_size >> 1);
+ 
+   /* Allocate the table.  Each entry consists of two words: the hash
+      value and an index in a secondary table which provides the index
diff --git a/SOURCES/glibc-rh1691534-2.patch b/SOURCES/glibc-rh1691534-2.patch
new file mode 100644
index 0000000..f94f9c6
--- /dev/null
+++ b/SOURCES/glibc-rh1691534-2.patch
@@ -0,0 +1,47 @@
+commit 5abcddd7949270998c6e8d99fdbbba821b664f8b
+Author: Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
+Date:   Thu Mar 21 17:24:30 2019 -0300
+
+    Fix parentheses error in iconvconfig.c and ld-collate.c [BZ #24372]
+    
+    When -Werror=parentheses is in use, iconvconfig.c builds fail with:
+    
+      iconvconfig.c: In function ‘write_output’:
+      iconvconfig.c:1084:34: error: suggest parentheses around ‘+’ inside ‘>>’ [-Werror=parentheses]
+         hash_size = next_prime (nnames + nnames >> 1);
+                                 ~~~~~~~^~~~~~~~
+    
+    This patch adds parentheses to the expression.  Not where suggested by
+    the compiler warning, but where it produces the expected result, i.e.:
+    where it has the effect of multiplying nnames by 1.5.
+    
+    Likewise for elem_size in ld-collate.c.
+    
+    Tested for powerpc64le.
+    
+diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c
+index 1e6066c..f75e46d 100644
+--- a/iconv/iconvconfig.c
++++ b/iconv/iconvconfig.c
+@@ -1081,7 +1081,7 @@ write_output (void)
+      Creating a perfect hash table is not reasonable here.  Therefore
+      we use open hashing and a table size which is the next prime 50%
+      larger than the number of strings.  */
+-  hash_size = next_prime (nnames + nnames >> 1);
++  hash_size = next_prime (nnames + (nnames >> 1));
+   hash_table = (struct hash_entry *) xcalloc (hash_size,
+ 					      sizeof (struct hash_entry));
+   /* Fill the hash table.  */
+diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
+index 19b23c2..6baab6c 100644
+--- a/locale/programs/ld-collate.c
++++ b/locale/programs/ld-collate.c
+@@ -2402,7 +2402,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
+       runp = runp->next;
+     }
+   /* Add 50% and find the next prime number.  */
+-  elem_size = next_prime (elem_size + elem_size >> 1);
++  elem_size = next_prime (elem_size + (elem_size >> 1));
+ 
+   /* Allocate the table.  Each entry consists of two words: the hash
+      value and an index in a secondary table which provides the index
diff --git a/SOURCES/glibc-rh1698015.patch b/SOURCES/glibc-rh1698015.patch
new file mode 100644
index 0000000..c5e7ae9
--- /dev/null
+++ b/SOURCES/glibc-rh1698015.patch
@@ -0,0 +1,32 @@
+commit 99135114ba23c3110b7e4e650fabdc5e639746b7
+Author: DJ Delorie <dj@redhat.com>
+Date:   Fri Jun 28 18:30:00 2019 -0500
+
+    nss_db: fix endent wrt NULL mappings [BZ #24695] [BZ #24696]
+    
+    nss_db allows for getpwent et al to be called without a set*ent,
+    but it only works once.  After the last get*ent a set*ent is
+    required to restart, because the end*ent did not properly reset
+    the module.  Resetting it to NULL allows for a proper restart.
+    
+    If the database doesn't exist, however, end*ent erroniously called
+    munmap which set errno.
+
+Note: the test case has not been included in this backport as the
+required test harness infrastructure does not exist.
+    
+diff --git a/nss/nss_db/db-open.c b/nss/nss_db/db-open.c
+index 8a83d6b..3fa11e9 100644
+--- a/nss/nss_db/db-open.c
++++ b/nss/nss_db/db-open.c
+@@ -63,5 +63,9 @@ internal_setent (const char *file, struct nss_db_map *mapping)
+ void
+ internal_endent (struct nss_db_map *mapping)
+ {
+-  munmap (mapping->header, mapping->len);
++  if (mapping->header != NULL)
++    {
++      munmap (mapping->header, mapping->len);
++      mapping->header = NULL;
++    }
+ }
diff --git a/SOURCES/glibc-rh1740039-1.patch b/SOURCES/glibc-rh1740039-1.patch
new file mode 100644
index 0000000..cc439f6
--- /dev/null
+++ b/SOURCES/glibc-rh1740039-1.patch
@@ -0,0 +1,160 @@
+Partial backport of:
+
+commit a42faf59d6d9f82e5293a9ebcc26d9c9e562b12b
+Author: Paul Pluzhnikov <ppluzhnikov@google.com>
+Date:   Mon Mar 24 10:58:26 2014 -0700
+
+    Fix BZ #16634.
+    
+    An application that erroneously tries to repeatedly dlopen("a.out", ...)
+    may hit assertion failure:
+    
+      Inconsistency detected by ld.so: dl-tls.c: 474: _dl_allocate_tls_init:
+      Assertion `listp != ((void *)0)' failed!
+    
+    dlopen() actually fails with  "./a.out: cannot dynamically load executable",
+    but it does so after incrementing dl_tls_max_dtv_idx.
+    
+    Once we run out of TLS_SLOTINFO_SURPLUS (62), we exit with above assertion
+    failure.
+    
+    2014-03-24  Paul Pluzhnikov  <ppluzhnikov@google.com>
+    
+            [BZ #16634]
+    
+            * elf/dl-load.c (open_verify): Add mode parameter.
+            Error early when ET_EXEC and mode does not have __RTLD_OPENEXEC.
+            (open_path): Change from boolean 'secure' to complete flag 'mode'
+            (_dl_map_object): Adjust.
+            * elf/Makefile (tests): Add tst-dlopen-aout.
+            * elf/tst-dlopen-aout.c: New test.
+
+Only the change to elf/dl-load.c is included here.  The upstream test
+does not work because it depends on --enable-hardcoded-path-in-tests
+(which is not available in this tree, despite being documented in the
+manual).
+
+diff --git a/elf/dl-load.c b/elf/dl-load.c
+index 6a0005da502c8f37..0ba0712aa5201fa0 100644
+--- a/elf/dl-load.c
++++ b/elf/dl-load.c
+@@ -1686,7 +1686,7 @@ print_search_path (struct r_search_path_elem **list,
+    user might want to know about this.  */
+ static int
+ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
+-	     int whatcode, bool *found_other_class, bool free_name)
++	     int whatcode, int mode, bool *found_other_class, bool free_name)
+ {
+   /* This is the expected ELF header.  */
+ #define ELF32_CLASS ELFCLASS32
+@@ -1863,6 +1863,17 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
+ 	  errstring = N_("only ET_DYN and ET_EXEC can be loaded");
+ 	  goto call_lose;
+ 	}
++      else if (__glibc_unlikely (ehdr->e_type == ET_EXEC
++				 && (mode & __RTLD_OPENEXEC) == 0))
++	{
++	  /* BZ #16634. It is an error to dlopen ET_EXEC (unless
++	     __RTLD_OPENEXEC is explicitly set).  We return error here
++	     so that code in _dl_map_object_from_fd does not try to set
++	     l_tls_modid for this module.  */
++
++	  errstring = N_("cannot dynamically load executable");
++	  goto call_lose;
++	}
+       else if (__builtin_expect (ehdr->e_phentsize, sizeof (ElfW(Phdr)))
+ 	       != sizeof (ElfW(Phdr)))
+ 	{
+@@ -1964,7 +1975,7 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
+    if MAY_FREE_DIRS is true.  */
+ 
+ static int
+-open_path (const char *name, size_t namelen, int secure,
++open_path (const char *name, size_t namelen, int mode,
+ 	   struct r_search_path_struct *sps, char **realname,
+ 	   struct filebuf *fbp, struct link_map *loader, int whatcode,
+ 	   bool *found_other_class)
+@@ -2016,8 +2027,8 @@ open_path (const char *name, size_t namelen, int secure,
+ 	  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))
+ 	    _dl_debug_printf ("  trying file=%s\n", buf);
+ 
+-	  fd = open_verify (buf, fbp, loader, whatcode, found_other_class,
+-			    false);
++	  fd = open_verify (buf, fbp, loader, whatcode, mode,
++			    found_other_class, false);
+ 	  if (this_dir->status[cnt] == unknown)
+ 	    {
+ 	      if (fd != -1)
+@@ -2046,7 +2057,7 @@ open_path (const char *name, size_t namelen, int secure,
+ 	  /* Remember whether we found any existing directory.  */
+ 	  here_any |= this_dir->status[cnt] != nonexisting;
+ 
+-	  if (fd != -1 && __builtin_expect (secure, 0)
++	  if (fd != -1 && __builtin_expect (mode & __RTLD_SECURE, 0)
+ 	      && INTUSE(__libc_enable_secure))
+ 	    {
+ 	      /* This is an extra security effort to make sure nobody can
+@@ -2236,7 +2247,7 @@ _dl_map_object (struct link_map *loader, const char *name,
+ 	  for (l = loader; l; l = l->l_loader)
+ 	    if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH"))
+ 	      {
+-		fd = open_path (name, namelen, mode & __RTLD_SECURE,
++		fd = open_path (name, namelen, mode,
+ 				&l->l_rpath_dirs,
+ 				&realname, &fb, loader, LA_SER_RUNPATH,
+ 				&found_other_class);
+@@ -2252,7 +2263,7 @@ _dl_map_object (struct link_map *loader, const char *name,
+ 	      && main_map != NULL && main_map->l_type != lt_loaded
+ 	      && cache_rpath (main_map, &main_map->l_rpath_dirs, DT_RPATH,
+ 			      "RPATH"))
+-	    fd = open_path (name, namelen, mode & __RTLD_SECURE,
++	    fd = open_path (name, namelen, mode,
+ 			    &main_map->l_rpath_dirs,
+ 			    &realname, &fb, loader ?: main_map, LA_SER_RUNPATH,
+ 			    &found_other_class);
+@@ -2260,7 +2271,7 @@ _dl_map_object (struct link_map *loader, const char *name,
+ 
+       /* Try the LD_LIBRARY_PATH environment variable.  */
+       if (fd == -1 && env_path_list.dirs != (void *) -1)
+-	fd = open_path (name, namelen, mode & __RTLD_SECURE, &env_path_list,
++	fd = open_path (name, namelen, mode, &env_path_list,
+ 			&realname, &fb,
+ 			loader ?: GL(dl_ns)[LM_ID_BASE]._ns_loaded,
+ 			LA_SER_LIBPATH, &found_other_class);
+@@ -2269,7 +2280,7 @@ _dl_map_object (struct link_map *loader, const char *name,
+       if (fd == -1 && loader != NULL
+ 	  && cache_rpath (loader, &loader->l_runpath_dirs,
+ 			  DT_RUNPATH, "RUNPATH"))
+-	fd = open_path (name, namelen, mode & __RTLD_SECURE,
++	fd = open_path (name, namelen, mode,
+ 			&loader->l_runpath_dirs, &realname, &fb, loader,
+ 			LA_SER_RUNPATH, &found_other_class);
+ 
+@@ -2326,7 +2337,8 @@ _dl_map_object (struct link_map *loader, const char *name,
+ 		{
+ 		  fd = open_verify (cached,
+ 				    &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
+-				    LA_SER_CONFIG, &found_other_class, false);
++				    LA_SER_CONFIG, mode, &found_other_class,
++				    false);
+ 		  if (__builtin_expect (fd != -1, 1))
+ 		    realname = cached;
+ 		  else
+@@ -2341,7 +2353,7 @@ _dl_map_object (struct link_map *loader, const char *name,
+ 	  && ((l = loader ?: GL(dl_ns)[nsid]._ns_loaded) == NULL
+ 	      || __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1))
+ 	  && rtld_search_dirs.dirs != (void *) -1)
+-	fd = open_path (name, namelen, mode & __RTLD_SECURE, &rtld_search_dirs,
++	fd = open_path (name, namelen, mode, &rtld_search_dirs,
+ 			&realname, &fb, l, LA_SER_DEFAULT, &found_other_class);
+ 
+       /* Add another newline when we are tracing the library loading.  */
+@@ -2359,7 +2371,7 @@ _dl_map_object (struct link_map *loader, const char *name,
+       else
+ 	{
+ 	  fd = open_verify (realname, &fb,
+-			    loader ?: GL(dl_ns)[nsid]._ns_loaded, 0,
++			    loader ?: GL(dl_ns)[nsid]._ns_loaded, 0, mode,
+ 			    &found_other_class, true);
+ 	  if (__builtin_expect (fd, 0) == -1)
+ 	    free (realname);
diff --git a/SOURCES/glibc-rh1740039-2.patch b/SOURCES/glibc-rh1740039-2.patch
new file mode 100644
index 0000000..7102aa2
--- /dev/null
+++ b/SOURCES/glibc-rh1740039-2.patch
@@ -0,0 +1,174 @@
+Partial backport of:
+
+commit 7d3db434f910c23591f748a6d0ac3548af1048bb
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Oct 17 08:51:21 2019 +0200
+
+    Rename and split elf/tst-dlopen-aout collection of tests
+    
+    From the beginning, elf/tst-dlopen-aout has exercised two different
+    bugs: (a) failure to report errors for a dlopen of the executable
+    itself in some cases (bug 24900) and (b) incorrect rollback of the
+    TLS modid allocation in case of a dlopen failure (bug 16634).
+    
+    This commit replaces the test with elf/tst-dlopen-self for (a) and
+    elf/tst-dlopen-tlsmodid for (b).  The latter tests use the
+    elf/tst-dlopen-self binaries (or iconv) with dlopen, so they are
+    no longer self-dlopen tests.
+    
+    Tested on x86_64-linux-gnu and i686-linux-gnu, with a toolchain that
+    does not default to PIE.
+
+Only the non-PIE, non-container test elf/tst-dlopen-tlsmodid is
+included.  The reason is that the self-dlopen fixes and the PIE TLS
+modid fix have not been backported, and that container testing support
+is missing downstream.  The test binary is adjusted to tst-tls10
+because tst-dlopen-self does not exist in the backport.
+
+diff --git a/elf/Makefile b/elf/Makefile
+index cfd039fc9dfb0be7..c22008b54afc91f5 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -153,7 +153,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
+ 	 tst-stackguard1 tst-addr1 tst-thrlock \
+ 	 tst-unique1 tst-unique2 tst-unique3 tst-unique4 \
+ 	 tst-initorder tst-initorder2 tst-relsort1 tst-ptrguard1 \
+-	 tst-big-note
++	 tst-big-note tst-dlopen-tlsmodid
+ #	 reldep9
+ test-srcs = tst-pathopt
+ selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null)
+@@ -1101,6 +1101,9 @@ $(objpfx)tst-addr1: $(libdl)
+ 
+ $(objpfx)tst-thrlock: $(libdl) $(shared-thread-library)
+ 
++$(objpfx)tst-dlopen-tlsmodid: $(libdl) $(shared-thread-library)
++$(objpfx)tst-dlopen-tlsmodid.out: $(objpfx)tst-tls10
++
+ CFLAGS-ifuncmain1pic.c += $(pic-ccflag)
+ CFLAGS-ifuncmain1picstatic.c += $(pic-ccflag)
+ CFLAGS-ifuncmain1staticpic.c += $(pic-ccflag)
+diff --git a/elf/tst-dlopen-tlsmodid.c b/elf/tst-dlopen-tlsmodid.c
+new file mode 100644
+index 0000000000000000..c5b1c39369aa610c
+--- /dev/null
++++ b/elf/tst-dlopen-tlsmodid.c
+@@ -0,0 +1,25 @@
++/* Test case for BZ #16634.  Non-PIE version.
++
++   Verify that incorrectly dlopen()ing an executable without
++   __RTLD_OPENEXEC does not cause assertion in ld.so, and that it
++   actually results in an error.
++
++   Copyright (C) 2014-2019 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
++   <https://www.gnu.org/licenses/>.  */
++
++#define TST_DLOPEN_TLSMODID_PATH "tst-tls10"
++#include "tst-dlopen-tlsmodid.h"
+diff --git a/elf/tst-dlopen-tlsmodid.h b/elf/tst-dlopen-tlsmodid.h
+new file mode 100644
+index 0000000000000000..c747cb14911c72fa
+--- /dev/null
++++ b/elf/tst-dlopen-tlsmodid.h
+@@ -0,0 +1,87 @@
++/* Common code for tst-dlopen-tlsmodid, tst-dlopen-tlsmodid-pie,
++   tst-dlopen-tlsmodid-container.
++
++   Verify that incorrectly dlopen()ing an executable without
++   __RTLD_OPENEXEC does not cause assertion in ld.so, and that it
++   actually results in an error.
++
++   Copyright (C) 2014-2019 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
++   <https://www.gnu.org/licenses/>.  */
++
++/* Before including this file, the macro TST_DLOPEN_TLSMODID_PATH must
++   be defined, to specify the path used for the open operation.  */
++
++#include <dlfcn.h>
++#include <pthread.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <support/check.h>
++#include <support/support.h>
++#include <support/xthread.h>
++
++__thread int x;
++
++void *
++fn (void *p)
++{
++  return p;
++}
++
++/* Call dlopen and check that fails with an error message indicating
++   an attempt to open an ET_EXEC or PIE object.  */
++static void
++check_dlopen_failure (void)
++{
++  void *handle = dlopen (TST_DLOPEN_TLSMODID_PATH, RTLD_LAZY);
++  if (handle != NULL)
++    FAIL_EXIT1 ("dlopen succeeded unexpectedly: %s", TST_DLOPEN_TLSMODID_PATH);
++
++  const char *message = dlerror ();
++  TEST_VERIFY_EXIT (message != NULL);
++  if ((strstr (message,
++	       "cannot dynamically load position-independent executable")
++       == NULL)
++      && strstr (message, "cannot dynamically load executable") == NULL)
++    FAIL_EXIT1 ("invalid dlopen error message: \"%s\"", message);
++}
++
++static int
++do_test (int argc, char *argv[])
++{
++  int j;
++
++  for (j = 0; j < 100; ++j)
++    {
++      pthread_t thr;
++
++      check_dlopen_failure ();
++
++      /* We create threads to force TLS allocation, which triggers
++	 the original bug i.e. running out of surplus slotinfo entries
++	 for TLS.  */
++      thr = xpthread_create (NULL, fn, NULL);
++      xpthread_join (thr);
++    }
++
++  check_dlopen_failure ();
++
++  return 0;
++}
++
++#define TEST_FUNCTION_ARGV do_test
++#include <support/test-driver.c>
diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec
index ebf161b..17ad979 100644
--- a/SPECS/glibc.spec
+++ b/SPECS/glibc.spec
@@ -1,6 +1,6 @@
 %define glibcsrcdir glibc-2.17-c758a686
 %define glibcversion 2.17
-%define glibcrelease 292%{?dist}
+%define glibcrelease 307%{?dist}.1
 ##############################################################################
 # We support the following options:
 # --with/--without,
@@ -149,26 +149,16 @@ Source1: %{glibcsrcdir}-releng.tar.gz
 Source2: verify.md5
 
 ##############################################################################
-# Start of glibc patches
-##############################################################################
-# 0000-0999 for patches which are unlikely to ever go upstream or which
-# have not been analyzed to see if they ought to go upstream yet.
-#
-# 1000-2000 for patches that are already upstream.
 #
-# 2000-3000 for patches that are awaiting upstream approval
+# Add your new glibc patches to the *end* of the list of patches.
+# Please treat the patch list as an immutable history.
 #
-# Yes, I realize this means some gratutious changes as patches to from
-# one bucket to another, but I find this scheme makes it easier to track
-# the upstream divergence and patches needing approval.
-#
-# Note that we can still apply the patches in any order we see fit, so
-# the changes from one bucket to another won't necessarily result in needing
-# to twiddle the patch because of dependencies on prior patches and the like.
-
-##############################################################################
-#
-# Patches that are unlikely to go upstream or not yet analyzed.
+# During the initial development of RHEL7 we used to have patch group numbers
+# but these turned out to be insufficient to manage the patch list and we no
+# longer use them, but it does mean that early patches are listed in one
+# order and applied in another. We could renumber all the patches in the right
+# order but it is not required, just add patches to the *end* of the list of
+# patches and include all relevant information inside the patch header.
 #
 ##############################################################################
 
@@ -258,11 +248,6 @@ Patch0068: glibc-rh1349982.patch
 
 # These changes were brought forward from RHEL 6 for compatibility
 Patch0069: glibc-rh1448107.patch
-##############################################################################
-#
-# Patches from upstream
-#
-##############################################################################
 
 Patch1000: glibc-rh905877.patch
 Patch1001: glibc-rh958652.patch
@@ -1164,6 +1149,132 @@ Patch1902: glibc-rh1523119-compat-symbols.patch
 # RHBZ #1609067: Backfort of upstream [#15804] - fix race condition in pldd
 Patch1903: glibc-rh1609067.patch
 
+# RHBZ #1672771: 
+Patch1904: glibc-rh1672771.patch
+
+# http://sourceware.org/ml/libc-alpha/2012-12/msg00103.html
+# Not upstream as of 2014-02-27
+Patch2007: glibc-rh697421.patch
+
+# Not upstream as of 2014-02-27
+Patch2011: glibc-rh757881.patch
+
+# Not upstream as of 2014-02-27
+Patch2013: glibc-rh741105.patch
+
+# Upstream BZ 14247
+# Not upstream as of 2014-02-27.
+Patch2023: glibc-rh827510.patch
+
+# Upstream BZ 14185
+# Not upstream as of 2014-02-27.
+Patch2027: glibc-rh819430.patch
+
+# Fix nscd to use permission names not constants.
+# Not upstream as of 2014-02-27.
+Patch2048: glibc-rh1025934.patch
+
+# Upstream BZ 16398.
+Patch2051: glibc-rh1048036.patch
+Patch2052: glibc-rh1048123.patch
+
+# Upstream BZ 16680
+Patch2053: glibc-rh1074410-2.patch
+
+# Upstream BZ 15493.
+# Upstream as of 2013-03-20
+Patch2055: glibc-rh1073667.patch
+
+Patch2060: glibc-aarch64-rh1076760.patch
+
+# Include pthread.h in rtkaio/tst-aiod2.c and rtkaio/tst-aiod3.c.
+Patch2062: glibc-rtkaio-inc-pthread.patch
+
+Patch2063: glibc-rh1084089.patch
+
+Patch2064: glibc-rh1161666.patch
+
+Patch2065: glibc-rh1156331.patch
+
+# Upstream BZ 18557: Fix ruserok scalability issues.
+Patch2066: glibc-rh1216246.patch
+
+# Backport of fix for malloc arena free list management (upstream bug 19048)
+# The preparatory patch removes !PER_THREAD conditional code.
+Patch20670: glibc-rh1276753-0.patch
+Patch2067: glibc-rh1276753.patch
+
+# Backport to fix ld.so crash when audit modules provide path (upstream bug 18251)
+Patch2068: glibc-rh1211100.patch
+
+# aarch64 MINSIGSTKSZ/SIGSTKSZ fix
+Patch2069: glibc-rh1335629.patch
+Patch2070: glibc-rh1335925-1.patch
+Patch2071: glibc-rh1335925-2.patch
+Patch2072: glibc-rh1335925-3.patch
+Patch2073: glibc-rh1335925-4.patch
+
+# Do not set initgroups in default nsswitch.conf
+Patch2074: glibc-rh1366569.patch
+
+# Various nss_db fixes
+Patch2075: glibc-rh1318890.patch
+Patch2076: glibc-rh1213603.patch
+Patch2077: glibc-rh1370630.patch
+
+# Add internal-only support for O_TMPFILE.
+Patch2078: glibc-rh1330705-1.patch
+Patch2079: glibc-rh1330705-2.patch
+Patch2080: glibc-rh1330705-3.patch
+Patch2081: glibc-rh1330705-4.patch
+Patch2082: glibc-rh1330705-5.patch
+# The following patch *removes* the public definition of O_TMPFILE.
+Patch2083: glibc-rh1330705-6.patch
+
+# getaddrinfo with nscd fixes
+Patch2084: glibc-rh1324568.patch
+
+# RHBZ #1404435 - Remove power8 platform directory
+Patch2085: glibc-rh1404435.patch
+
+# RHBZ #1144516 - aarch64 profil fix
+Patch2086: glibc-rh1144516.patch
+
+# RHBZ #1392540 - Add "sss" service to the automount database in nsswitch.conf
+Patch2087: glibc-rh1392540.patch
+
+# RHBZ #1452721: Avoid large allocas in the dynamic linker
+Patch2088: glibc-rh1452721-1.patch
+Patch2089: glibc-rh1452721-2.patch
+Patch2090: glibc-rh1452721-3.patch
+Patch2091: glibc-rh1452721-4.patch
+
+Patch2092: glibc-rh677316-libc-pointer-arith.patch
+Patch2093: glibc-rh677316-libc-lock.patch
+Patch2094: glibc-rh677316-libc-diag.patch
+Patch2095: glibc-rh677316-check_mul_overflow_size_t.patch
+Patch2096: glibc-rh677316-res_state.patch
+Patch2097: glibc-rh677316-qsort_r.patch
+Patch2098: glibc-rh677316-fgets_unlocked.patch
+Patch2099: glibc-rh677316-in6addr_any.patch
+Patch2100: glibc-rh677316-netdb-reentrant.patch
+Patch2101: glibc-rh677316-h_errno.patch
+Patch2102: glibc-rh677316-scratch_buffer.patch
+Patch2103: glibc-rh677316-mtrace.patch
+Patch2104: glibc-rh677316-dynarray.patch
+Patch2105: glibc-rh677316-alloc_buffer.patch
+Patch2106: glibc-rh677316-RES_USE_INET6.patch
+Patch2107: glibc-rh677316-inet_pton.patch
+Patch2108: glibc-rh677316-inet_pton-zeros.patch
+Patch2109: glibc-rh677316-hesiod.patch
+Patch2110: glibc-rh677316-resolv.patch
+Patch2111: glibc-rh677316-legacy.patch
+
+Patch2112: glibc-rh1498566.patch
+Patch2113: glibc-rh1445644.patch
+
+Patch2114: glibc-rh1471405.patch
+
 Patch2500: glibc-rh1505492-nscd_stat.patch
 Patch2501: glibc-rh1564638.patch
 Patch2502: glibc-rh1566623.patch
@@ -1479,139 +1590,34 @@ Patch2806: glibc-rh1555189-1.patch
 Patch2807: glibc-rh1555189-2.patch
 Patch2808: glibc-rh1427734-1.patch
 Patch2809: glibc-rh1427734-2.patch
-
-##############################################################################
-#
-# Patches submitted, but not yet approved upstream.
-#
-##############################################################################
-#
-# Each should be associated with a BZ.
-# Obviously we're not there right now, but that's the goal
-#
-
-# http://sourceware.org/ml/libc-alpha/2012-12/msg00103.html
-# Not upstream as of 2014-02-27
-Patch2007: glibc-rh697421.patch
-
-# Not upstream as of 2014-02-27
-Patch2011: glibc-rh757881.patch
-
-# Not upstream as of 2014-02-27
-Patch2013: glibc-rh741105.patch
-
-# Upstream BZ 14247
-# Not upstream as of 2014-02-27.
-Patch2023: glibc-rh827510.patch
-
-# Upstream BZ 14185
-# Not upstream as of 2014-02-27.
-Patch2027: glibc-rh819430.patch
-
-# Fix nscd to use permission names not constants.
-# Not upstream as of 2014-02-27.
-Patch2048: glibc-rh1025934.patch
-
-# Upstream BZ 16398.
-Patch2051: glibc-rh1048036.patch
-Patch2052: glibc-rh1048123.patch
-
-# Upstream BZ 16680
-Patch2053: glibc-rh1074410-2.patch
-
-# Upstream BZ 15493.
-# Upstream as of 2013-03-20
-Patch2055: glibc-rh1073667.patch
-
-Patch2060: glibc-aarch64-rh1076760.patch
-
-# Include pthread.h in rtkaio/tst-aiod2.c and rtkaio/tst-aiod3.c.
-Patch2062: glibc-rtkaio-inc-pthread.patch
-
-Patch2063: glibc-rh1084089.patch
-
-Patch2064: glibc-rh1161666.patch
-
-Patch2065: glibc-rh1156331.patch
-
-# Upstream BZ 18557: Fix ruserok scalability issues.
-Patch2066: glibc-rh1216246.patch
-
-# Backport of fix for malloc arena free list management (upstream bug 19048)
-# The preparatory patch removes !PER_THREAD conditional code.
-Patch20670: glibc-rh1276753-0.patch
-Patch2067: glibc-rh1276753.patch
-
-# Backport to fix ld.so crash when audit modules provide path (upstream bug 18251)
-Patch2068: glibc-rh1211100.patch
-
-# aarch64 MINSIGSTKSZ/SIGSTKSZ fix
-Patch2069: glibc-rh1335629.patch
-Patch2070: glibc-rh1335925-1.patch
-Patch2071: glibc-rh1335925-2.patch
-Patch2072: glibc-rh1335925-3.patch
-Patch2073: glibc-rh1335925-4.patch
-
-# Do not set initgroups in default nsswitch.conf
-Patch2074: glibc-rh1366569.patch
-
-# Various nss_db fixes
-Patch2075: glibc-rh1318890.patch
-Patch2076: glibc-rh1213603.patch
-Patch2077: glibc-rh1370630.patch
-
-# Add internal-only support for O_TMPFILE.
-Patch2078: glibc-rh1330705-1.patch
-Patch2079: glibc-rh1330705-2.patch
-Patch2080: glibc-rh1330705-3.patch
-Patch2081: glibc-rh1330705-4.patch
-Patch2082: glibc-rh1330705-5.patch
-# The following patch *removes* the public definition of O_TMPFILE.
-Patch2083: glibc-rh1330705-6.patch
-
-# getaddrinfo with nscd fixes
-Patch2084: glibc-rh1324568.patch
-
-# RHBZ #1404435 - Remove power8 platform directory
-Patch2085: glibc-rh1404435.patch
-
-# RHBZ #1144516 - aarch64 profil fix
-Patch2086: glibc-rh1144516.patch
-
-# RHBZ #1392540 - Add "sss" service to the automount database in nsswitch.conf
-Patch2087: glibc-rh1392540.patch
-
-# RHBZ #1452721: Avoid large allocas in the dynamic linker
-Patch2088: glibc-rh1452721-1.patch
-Patch2089: glibc-rh1452721-2.patch
-Patch2090: glibc-rh1452721-3.patch
-Patch2091: glibc-rh1452721-4.patch
-
-Patch2092: glibc-rh677316-libc-pointer-arith.patch
-Patch2093: glibc-rh677316-libc-lock.patch
-Patch2094: glibc-rh677316-libc-diag.patch
-Patch2095: glibc-rh677316-check_mul_overflow_size_t.patch
-Patch2096: glibc-rh677316-res_state.patch
-Patch2097: glibc-rh677316-qsort_r.patch
-Patch2098: glibc-rh677316-fgets_unlocked.patch
-Patch2099: glibc-rh677316-in6addr_any.patch
-Patch2100: glibc-rh677316-netdb-reentrant.patch
-Patch2101: glibc-rh677316-h_errno.patch
-Patch2102: glibc-rh677316-scratch_buffer.patch
-Patch2103: glibc-rh677316-mtrace.patch
-Patch2104: glibc-rh677316-dynarray.patch
-Patch2105: glibc-rh677316-alloc_buffer.patch
-Patch2106: glibc-rh677316-RES_USE_INET6.patch
-Patch2107: glibc-rh677316-inet_pton.patch
-Patch2108: glibc-rh677316-inet_pton-zeros.patch
-Patch2109: glibc-rh677316-hesiod.patch
-Patch2110: glibc-rh677316-resolv.patch
-Patch2111: glibc-rh677316-legacy.patch
-
-Patch2112: glibc-rh1498566.patch
-Patch2113: glibc-rh1445644.patch
-
-Patch2114: glibc-rh1471405.patch
+Patch2810: glibc-rh1414263.patch
+Patch2811: glibc-rh1406732-1.patch
+Patch2812: glibc-rh1406732-2.patch
+Patch2813: glibc-rh1406732-3.patch
+Patch2814: glibc-rh1406732-4.patch
+Patch2815: glibc-rh1406732-5.patch
+Patch2816: glibc-rh1670041.patch
+Patch2817: glibc-rh1451308.patch
+Patch2818: glibc-rh1636229-1.patch
+Patch2819: glibc-rh1636229-2.patch
+Patch2820: glibc-rh1636229-3.patch
+Patch2821: glibc-rh1636229-4.patch
+Patch2822: glibc-rh1579451.patch
+Patch2823: glibc-rh1634021.patch
+Patch2824: glibc-rh1691534-1.patch
+Patch2825: glibc-rh1691534-2.patch
+Patch2826: glibc-rh1698015.patch
+Patch2827: glibc-rh1065574-1.patch
+Patch2828: glibc-rh1065574-2.patch
+Patch2829: glibc-rh1065574-3.patch
+Patch2830: glibc-rh1065574-4.patch
+Patch2831: glibc-rh1065574-5.patch
+Patch2832: glibc-rh1065574-6.patch
+Patch2833: glibc-rh1065574-7.patch
+Patch2834: glibc-rh1484832.patch
+Patch2835: glibc-rh1740039-1.patch
+Patch2836: glibc-rh1740039-2.patch
+Patch2837: glibc-rh1406732-6.patch
 
 ##############################################################################
 # End of glibc patches.
@@ -2628,6 +2634,7 @@ package or when debugging this package.
 %patch1901 -p1
 %patch1902 -p1
 %patch1903 -p1
+%patch1904 -p1
 %patch2500 -p1
 %patch2501 -p1
 %patch2502 -p1
@@ -2941,6 +2948,34 @@ package or when debugging this package.
 %patch2807 -p1
 %patch2808 -p1
 %patch2809 -p1
+%patch2810 -p1
+%patch2811 -p1
+%patch2812 -p1
+%patch2813 -p1
+%patch2814 -p1
+%patch2815 -p1
+%patch2816 -p1
+%patch2817 -p1
+%patch2818 -p1
+%patch2819 -p1
+%patch2820 -p1
+%patch2821 -p1
+%patch2822 -p1
+%patch2823 -p1
+%patch2824 -p1
+%patch2825 -p1
+%patch2826 -p1
+%patch2827 -p1
+%patch2828 -p1
+%patch2829 -p1
+%patch2830 -p1
+%patch2831 -p1
+%patch2832 -p1
+%patch2833 -p1
+%patch2834 -p1
+%patch2835 -p1
+%patch2836 -p1
+%patch2837 -p1
 
 ##############################################################################
 # %%prep - Additional prep required...
@@ -3106,10 +3141,23 @@ build_CFLAGS="$BuildFlags -g -O3 $*"
 # Some configure checks can spuriously fail for some architectures if
 # unwind info is present
 configure_CFLAGS="$build_CFLAGS -fno-asynchronous-unwind-tables"
+
+# See bug 1790475 for the history behind --disable-bind-now for ppc64.
+# In summary: COPY relocations and BIND_NOW are incompatible on ppc64.
+# The solution is to globally disable BIND_NOW hardening on ppc64 with
+# --disable-bind-now and then use a downstream-only patch
+# (glibc-rh1406732-6.patch) to partially enable BIND_NOW hardening for
+# ppc64 to the level of hardening that works given the toolchain.
+
 ../configure CC="$GCC" CXX="$GXX" CFLAGS="$configure_CFLAGS" \
 	--prefix=%{_prefix} \
 	--enable-add-ons=nptl$AddOns \
-	--with-headers=%{_prefix}/include $EnableKernel --enable-bind-now \
+	--with-headers=%{_prefix}/include $EnableKernel \
+%ifarch ppc64
+	--disable-bind-now \
+%else
+	--enable-bind-now \
+%endif
 	--build=%{target} \
 %ifarch %{multiarcharches}
 	--enable-multi-arch \
@@ -3441,7 +3489,19 @@ $olddir/build-%{target}/elf/ld.so \
     --prefix ${RPM_BUILD_ROOT} --add-to-archive \
     *_*
 rm -rf *_*
-mv locale-archive{,.tmpl}
+# Setup the locale-archive template.  We copy the archive in place to
+# keep the size of the file. Even though we mark the file with "ghost"
+# the size is used by rpm to compute the required free space (see
+# rhbz#1714888). We do this because there is a point in the install
+# when build-locale-archive has copied 100% of the template into the
+# new locale archive and so this consumes twice the amount of
+# diskspace. Note that this doesn't account for copying existing
+# compiled locales into the archive, this may consume even more disk
+# space and we can't fix that issue. In upstream we have moved away
+# from this process, removing build-locale-archive and installing a
+# default locale-archive without modification, and leaving compiled
+# locales as they are (without inclusion into the archive).
+cp locale-archive{,.tmpl}
 popd
 %endif
 
@@ -3906,10 +3966,6 @@ touch $RPM_BUILD_ROOT/var/{db,run}/nscd/{passwd,group,hosts,services}
 touch $RPM_BUILD_ROOT/var/run/nscd/{socket,nscd.pid}
 %endif
 
-%ifnarch %{auxarches}
-> $RPM_BUILD_ROOT/%{_prefix}/lib/locale/locale-archive
-%endif
-
 mkdir -p $RPM_BUILD_ROOT/var/cache/ldconfig
 > $RPM_BUILD_ROOT/var/cache/ldconfig/aux-cache
 
@@ -4057,7 +4113,7 @@ rm -f *.filelist*
 %files -f common.filelist common
 %defattr(-,root,root)
 %attr(0644,root,root) %verify(not md5 size mtime) %{_prefix}/lib/locale/locale-archive.tmpl
-%attr(0644,root,root) %verify(not md5 size mtime mode) %ghost %config(missingok,noreplace) %{_prefix}/lib/locale/locale-archive
+%attr(0644,root,root) %verify(not md5 size mtime mode) %ghost %{_prefix}/lib/locale/locale-archive
 %dir %attr(755,root,root) /etc/default
 %verify(not md5 size mtime) %config(noreplace) /etc/default/nss
 %doc documentation/*
@@ -4107,6 +4163,57 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Tue Jan 21 2020 Carlos O'Donell <carlos@redhat.com> - 2.17-307.1
+- Adjust security hardening changes for 64-bit POWER BE due to
+  toolchain limitations (#1790475)
+
+* Tue Oct 22 2019 Florian Weimer <fweimer@redhat.com> - 2.17-307
+- Fix assert after attempting to dlopen main programs (#1740039)
+
+* Fri Aug  2 2019 Carlos O'Donell <carlos@redhat.com> - 2.17-306
+- Fix dlopen crash when LD_LIBRARY_PATH is set (#1484832)
+
+* Thu Aug  1 2019 Florian Weimer <fweimer@redhat.com> - 2.17-305
+- Fix race condition in malloc_info (#1065574)
+
+* Thu Aug  1 2019 Florian Weimer <fweimer@redhat.com> - 2.17-304
+- Account for size of locale-archive in RPM package (#1714888)
+
+* Thu Aug  1 2019 Florian Weimer <fweimer@redhat.com> - 2.17-303
+- Do not mark locale archive as %%config (#1717512)
+
+* Wed Jul 31 2019 DJ Delorie <dj@redhat.com> - 2.17-302
+- Allow endpwent without getpwent (#1698015)
+
+* Wed Jul 31 2019 DJ Delorie <dj@redhat.com> - 2.17-301
+- Ensure binary locale files are identical across multilibs (#1691534)
+
+* Wed Jul 31 2019 DJ Delorie <dj@redhat.com> - 2.17-300
+- Fix off-by-one in nscd getservbyport call (#1634021)
+
+* Tue Jul 30 2019 Patsy Griffin <pfrankli@redhat.com> - 2.17-299
+- Update glibc headers for Linux 4.0, 4.1 definitions and 
+  Linux 4.2 netinet/in.h values. (#1579451)
+
+* Mon Jul 29 2019 Patsy Griffin <pfrankli@redhat.com> - 2.17-298
+- Improve NSS testing including new MERGE feature testing (#1636229)
+
+* Fri Jul 26 2019 Patsy Griffin <pfrankli@redhat.com> - 2.17-297
+- Add compiler barriers around modifications of the robust mutex list
+  for pthread_mutex_trylock. (#1672771)
+
+* Fri Jul 26 2019 Arjun Shankar <arjun@redhat.com> - 2.17-296
+- Fix crash in posix/bug-ga2 test when there is no IPv6 interface (#1451308)
+
+* Fri Jul 26 2019 Arjun Shankar <arjun@redhat.com> - 2.17-295
+- resolv: Switch DNS servers on all ICMP errors (#1670041)
+
+* Thu Jul 25 2019 Arjun Shankar <arjun@redhat.com> - 2.17-294
+- Build glibc with additional hardening (#1406732)
+
+* Wed Jul 24 2019 Arjun Shankar <arjun@redhat.com> - 2.17-293
+- iconv: Add support for IBM858 character encoding (#1414263)
+
 * Tue Apr 30 2019 Arjun Shankar <arjun@redhat.com> - 2.17-292
 - Avoid iconv hang on invalid multi-byte sequences (#1427734)