summary refs log tree commit diff
path: root/gnu
diff options
context:
space:
mode:
Diffstat (limited to 'gnu')
-rw-r--r--gnu/local.mk10
-rw-r--r--gnu/packages/base.scm112
-rw-r--r--gnu/packages/patches/glibc-CVE-2015-5180.patch311
-rw-r--r--gnu/packages/patches/glibc-CVE-2015-7547.patch590
-rw-r--r--gnu/packages/patches/glibc-CVE-2016-3075.patch43
-rw-r--r--gnu/packages/patches/glibc-CVE-2016-3706.patch188
-rw-r--r--gnu/packages/patches/glibc-CVE-2016-4429.patch58
-rw-r--r--gnu/packages/patches/glibc-CVE-2017-1000366-pt1.patch36
-rw-r--r--gnu/packages/patches/glibc-CVE-2017-1000366-pt2.patch124
-rw-r--r--gnu/packages/patches/glibc-CVE-2017-1000366-pt3.patch206
-rw-r--r--gnu/packages/patches/glibc-o-largefile.patch25
-rw-r--r--gnu/packages/patches/glibc-vectorized-strcspn-guards.patch23
12 files changed, 0 insertions, 1726 deletions
diff --git a/gnu/local.mk b/gnu/local.mk
index f2a7b6b984..ef6533bd8d 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1016,14 +1016,6 @@ dist_patch_DATA =						\
   %D%/packages/patches/ghostscript-no-header-uuid.patch		\
   %D%/packages/patches/ghostscript-no-header-creationdate.patch \
   %D%/packages/patches/glib-tests-timer.patch			\
-  %D%/packages/patches/glibc-CVE-2015-5180.patch		\
-  %D%/packages/patches/glibc-CVE-2015-7547.patch		\
-  %D%/packages/patches/glibc-CVE-2016-3075.patch		\
-  %D%/packages/patches/glibc-CVE-2016-3706.patch		\
-  %D%/packages/patches/glibc-CVE-2016-4429.patch		\
-  %D%/packages/patches/glibc-CVE-2017-1000366-pt1.patch		\
-  %D%/packages/patches/glibc-CVE-2017-1000366-pt2.patch		\
-  %D%/packages/patches/glibc-CVE-2017-1000366-pt3.patch		\
   %D%/packages/patches/glibc-CVE-2018-11236.patch		\
   %D%/packages/patches/glibc-CVE-2018-11237.patch		\
   %D%/packages/patches/glibc-CVE-2019-7309.patch		\
@@ -1045,9 +1037,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/glibc-ldd-x86_64.patch			\
   %D%/packages/patches/glibc-locales.patch			\
   %D%/packages/patches/glibc-locales-2.28.patch			\
-  %D%/packages/patches/glibc-o-largefile.patch			\
   %D%/packages/patches/glibc-reinstate-prlimit64-fallback.patch	\
-  %D%/packages/patches/glibc-vectorized-strcspn-guards.patch	\
   %D%/packages/patches/glibc-versioned-locpath.patch		\
   %D%/packages/patches/glibc-2.27-git-fixes.patch		\
   %D%/packages/patches/glibc-2.28-git-fixes.patch		\
diff --git a/gnu/packages/base.scm b/gnu/packages/base.scm
index 7116708743..6cd7ed749b 100644
--- a/gnu/packages/base.scm
+++ b/gnu/packages/base.scm
@@ -1014,118 +1014,6 @@ with the Linux kernel.")
                                        "glibc-CVE-2018-11237.patch"))))
     (properties `((lint-hidden-cve . ("CVE-2017-18269")))))) ; glibc-2.27-git-fixes
 
-(define-public glibc-2.26
-  (package
-    (inherit glibc)
-    ;; This version number corresponds to the output of `git describe` and the
-    ;; archive can be generated by checking out the commit ID and running:
-    ;;  git archive --prefix=$(git describe)/ HEAD | xz > $(git describe).tar.xz
-    ;; See <https://bugs.gnu.org/29406> for why this was necessary.
-    (version "2.26.105-g0890d5379c")
-    (source (origin
-              (inherit (package-source glibc))
-              (uri (string-append "https://alpha.gnu.org/gnu/guix/mirror/"
-                                  "glibc-" (version-major+minor version) "-"
-                                  (caddr (string-split version #\.)) ".tar.xz"))
-              (sha256
-               (base32
-                "1jck0c1i248sn02rvsfjykk77qncma34bjq89dyy2irwm50d7s3g"))
-              (patches (search-patches "glibc-ldd-x86_64.patch"
-                                       "glibc-versioned-locpath.patch"
-                                       "glibc-allow-kernel-2.6.32.patch"))))))
-
-(define-public glibc-2.25
-  (package
-    (inherit glibc)
-    (version "2.25")
-    (source (origin
-              (inherit (package-source glibc))
-              (uri (string-append "mirror://gnu/glibc/glibc-"
-                                  version ".tar.xz"))
-              (sha256
-               (base32
-                "1813dzkgw6v8q8q1m4v96yfis7vjqc9pslqib6j9mrwh6fxxjyq6"))
-              (patches (search-patches "glibc-ldd-x86_64.patch"
-                                       "glibc-versioned-locpath.patch"
-                                       "glibc-vectorized-strcspn-guards.patch"
-                                       "glibc-CVE-2017-1000366-pt1.patch"
-                                       "glibc-CVE-2017-1000366-pt2.patch"
-                                       "glibc-CVE-2017-1000366-pt3.patch"))))))
-
-(define-public glibc-2.24
-  (package
-    (inherit glibc)
-    (version "2.24")
-    (source (origin
-              (inherit (package-source glibc))
-              (uri (string-append "mirror://gnu/glibc/glibc-"
-                                  version ".tar.xz"))
-              (sha256
-               (base32
-                "1lxmprg9gm73gvafxd503x70z32phwjzcy74i0adfi6ixzla7m4r"))
-              (patches (search-patches "glibc-ldd-x86_64.patch"
-                                       "glibc-versioned-locpath.patch"
-                                       "glibc-vectorized-strcspn-guards.patch"
-                                       "glibc-CVE-2015-5180.patch"
-                                       "glibc-CVE-2017-1000366-pt1.patch"
-                                       "glibc-CVE-2017-1000366-pt2.patch"
-                                       "glibc-CVE-2017-1000366-pt3.patch"))))))
-
-(define-public glibc-2.23
-  (package
-    (inherit glibc)
-    (version "2.23")
-    (source (origin
-              (inherit (package-source glibc))
-              (uri (string-append "mirror://gnu/glibc/glibc-"
-                                  version ".tar.xz"))
-              (sha256
-               (base32
-                "1s8krs3y2n6pzav7ic59dz41alqalphv7vww4138ag30wh0fpvwl"))
-              (patches (search-patches "glibc-ldd-x86_64.patch"
-                                       "glibc-versioned-locpath.patch"
-                                       "glibc-vectorized-strcspn-guards.patch"
-                                       "glibc-CVE-2015-5180.patch"
-                                       "glibc-CVE-2016-3075.patch"
-                                       "glibc-CVE-2016-3706.patch"
-                                       "glibc-CVE-2016-4429.patch"
-                                       "glibc-CVE-2017-1000366-pt1.patch"
-                                       "glibc-CVE-2017-1000366-pt2.patch"
-                                       "glibc-CVE-2017-1000366-pt3.patch"))))))
-
-(define-public glibc-2.22
-  (package
-    (inherit glibc)
-    (version "2.22")
-    (source (origin
-              (inherit (package-source glibc))
-              (uri (string-append "mirror://gnu/glibc/glibc-"
-                                  version ".tar.xz"))
-              (sha256
-               (base32
-                "0j49682pm2nh4qbdw35bas82p1pgfnz4d2l7iwfyzvrvj0318wzb"))
-              (patches (search-patches "glibc-ldd-x86_64.patch"
-                                       "glibc-o-largefile.patch"
-                                       "glibc-vectorized-strcspn-guards.patch"
-                                       "glibc-CVE-2015-5180.patch"
-                                       "glibc-CVE-2015-7547.patch"
-                                       "glibc-CVE-2016-3075.patch"
-                                       "glibc-CVE-2016-3706.patch"
-                                       "glibc-CVE-2016-4429.patch"
-                                       "glibc-CVE-2017-1000366-pt1.patch"
-                                       "glibc-CVE-2017-1000366-pt2.patch"
-                                       "glibc-CVE-2017-1000366-pt3.patch"))))
-    (arguments
-      (substitute-keyword-arguments (package-arguments glibc)
-        ((#:phases phases)
-         `(modify-phases ,phases
-            (add-before 'configure 'fix-pwd
-              (lambda _
-                ;; Use `pwd' instead of `/bin/pwd' for glibc-2.22.
-                (substitute* "configure"
-                  (("/bin/pwd") "pwd"))
-                #t))))))))
-
 (define-public (make-gcc-libc base-gcc libc)
   "Return a GCC that targets LIBC."
   (package (inherit base-gcc)
diff --git a/gnu/packages/patches/glibc-CVE-2015-5180.patch b/gnu/packages/patches/glibc-CVE-2015-5180.patch
deleted file mode 100644
index 92e3740fc1..0000000000
--- a/gnu/packages/patches/glibc-CVE-2015-5180.patch
+++ /dev/null
@@ -1,311 +0,0 @@
-From b3b37f1a5559a7620e31c8053ed1b44f798f2b6d Mon Sep 17 00:00:00 2001
-From: Florian Weimer <fweimer@redhat.com>
-Date: Sat, 31 Dec 2016 20:22:09 +0100
-Subject: [PATCH] CVE-2015-5180: resolv: Fix crash with internal QTYPE [BZ
- #18784]
-
-Also rename T_UNSPEC because an upcoming public header file
-update will use that name.
-
-(cherry picked from commit fc82b0a2dfe7dbd35671c10510a8da1043d746a5)
----
- ChangeLog                     |  14 ++++
- NEWS                          |   6 ++
- include/arpa/nameser_compat.h |   6 +-
- resolv/Makefile               |   5 ++
- resolv/nss_dns/dns-host.c     |   2 +-
- resolv/res_mkquery.c          |   4 +
- resolv/res_query.c            |   6 +-
- resolv/tst-resolv-qtypes.c    | 185 ++++++++++++++++++++++++++++++++++++++++++
- 8 files changed, 221 insertions(+), 7 deletions(-)
- create mode 100644 resolv/tst-resolv-qtypes.c
-
-diff --git a/include/arpa/nameser_compat.h b/include/arpa/nameser_compat.h
-index 2e735ed..7c0deed 100644
---- a/include/arpa/nameser_compat.h
-+++ b/include/arpa/nameser_compat.h
-@@ -1,8 +1,8 @@
- #ifndef _ARPA_NAMESER_COMPAT_
- #include <resolv/arpa/nameser_compat.h>
- 
--/* Picksome unused number to represent lookups of IPv4 and IPv6 (i.e.,
--   T_A and T_AAAA).  */
--#define T_UNSPEC 62321
-+/* The number is outside the 16-bit RR type range and is used
-+   internally by the implementation.  */
-+#define T_QUERY_A_AND_AAAA 439963904
- 
- #endif
-diff --git a/resolv/Makefile b/resolv/Makefile
-index 8be41d3..a4c86b9 100644
---- a/resolv/Makefile
-+++ b/resolv/Makefile
-@@ -40,6 +40,9 @@ ifeq ($(have-thread-library),yes)
- extra-libs += libanl
- routines += gai_sigqueue
- tests += tst-res_hconf_reorder
-+
-+# This test sends millions of packets and is rather slow.
-+xtests += tst-resolv-qtypes
- endif
- extra-libs-others = $(extra-libs)
- libresolv-routines := gethnamaddr res_comp res_debug	\
-@@ -117,3 +120,5 @@ tst-leaks2-ENV = MALLOC_TRACE=$(objpfx)tst-leaks2.mtrace
- $(objpfx)mtrace-tst-leaks2.out: $(objpfx)tst-leaks2.out
- 	$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks2.mtrace > $@; \
- 	$(evaluate-test)
-+
-+$(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
-diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
-index 5f9e357..d16fa4b 100644
---- a/resolv/nss_dns/dns-host.c
-+++ b/resolv/nss_dns/dns-host.c
-@@ -323,7 +323,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
- 
-   int olderr = errno;
-   enum nss_status status;
--  int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
-+  int n = __libc_res_nsearch (&_res, name, C_IN, T_QUERY_A_AND_AAAA,
- 			      host_buffer.buf->buf, 2048, &host_buffer.ptr,
- 			      &ans2p, &nans2p, &resplen2, &ans2p_malloced);
-   if (n >= 0)
-diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c
-index 12f9730..d80b531 100644
---- a/resolv/res_mkquery.c
-+++ b/resolv/res_mkquery.c
-@@ -103,6 +103,10 @@ res_nmkquery(res_state statp,
- 	int n;
- 	u_char *dnptrs[20], **dpp, **lastdnptr;
- 
-+	if (class < 0 || class > 65535
-+	    || type < 0 || type > 65535)
-+	  return -1;
-+
- #ifdef DEBUG
- 	if (statp->options & RES_DEBUG)
- 		printf(";; res_nmkquery(%s, %s, %s, %s)\n",
-diff --git a/resolv/res_query.c b/resolv/res_query.c
-index 944d1a9..07dc6f6 100644
---- a/resolv/res_query.c
-+++ b/resolv/res_query.c
-@@ -122,7 +122,7 @@ __libc_res_nquery(res_state statp,
- 	int n, use_malloc = 0;
- 	u_int oflags = statp->_flags;
- 
--	size_t bufsize = (type == T_UNSPEC ? 2 : 1) * QUERYSIZE;
-+	size_t bufsize = (type == T_QUERY_A_AND_AAAA ? 2 : 1) * QUERYSIZE;
- 	u_char *buf = alloca (bufsize);
- 	u_char *query1 = buf;
- 	int nquery1 = -1;
-@@ -137,7 +137,7 @@ __libc_res_nquery(res_state statp,
- 		printf(";; res_query(%s, %d, %d)\n", name, class, type);
- #endif
- 
--	if (type == T_UNSPEC)
-+	if (type == T_QUERY_A_AND_AAAA)
- 	  {
- 	    n = res_nmkquery(statp, QUERY, name, class, T_A, NULL, 0, NULL,
- 			     query1, bufsize);
-@@ -190,7 +190,7 @@ __libc_res_nquery(res_state statp,
- 	if (__builtin_expect (n <= 0, 0) && !use_malloc) {
- 		/* Retry just in case res_nmkquery failed because of too
- 		   short buffer.  Shouldn't happen.  */
--		bufsize = (type == T_UNSPEC ? 2 : 1) * MAXPACKET;
-+		bufsize = (type == T_QUERY_A_AND_AAAA ? 2 : 1) * MAXPACKET;
- 		buf = malloc (bufsize);
- 		if (buf != NULL) {
- 			query1 = buf;
-diff --git a/resolv/tst-resolv-qtypes.c b/resolv/tst-resolv-qtypes.c
-new file mode 100644
-index 0000000..b3e60c6
---- /dev/null
-+++ b/resolv/tst-resolv-qtypes.c
-@@ -0,0 +1,185 @@
-+/* Exercise low-level query functions with different QTYPEs.
-+   Copyright (C) 2016 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 <resolv.h>
-+#include <string.h>
-+#include <support/check.h>
-+#include <support/check_nss.h>
-+#include <support/resolv_test.h>
-+#include <support/support.h>
-+#include <support/test-driver.h>
-+#include <support/xmemstream.h>
-+
-+/* If ture, the response function will send the actual response packet
-+   over TCP instead of UDP.  */
-+static volatile bool force_tcp;
-+
-+/* Send back a fake resource record matching the QTYPE.  */
-+static void
-+response (const struct resolv_response_context *ctx,
-+          struct resolv_response_builder *b,
-+          const char *qname, uint16_t qclass, uint16_t qtype)
-+{
-+  if (force_tcp && ctx->tcp)
-+    {
-+      resolv_response_init (b, (struct resolv_response_flags) { .tc = 1 });
-+      resolv_response_add_question (b, qname, qclass, qtype);
-+      return;
-+    }
-+
-+  resolv_response_init (b, (struct resolv_response_flags) { });
-+  resolv_response_add_question (b, qname, qclass, qtype);
-+  resolv_response_section (b, ns_s_an);
-+  resolv_response_open_record (b, qname, qclass, qtype, 0);
-+  resolv_response_add_data (b, &qtype, sizeof (qtype));
-+  resolv_response_close_record (b);
-+}
-+
-+static const const char *domain = "www.example.com";
-+
-+static int
-+wrap_res_query (int type, unsigned char *answer, int answer_length)
-+{
-+  return res_query (domain, C_IN, type, answer, answer_length);
-+}
-+
-+static int
-+wrap_res_search (int type, unsigned char *answer, int answer_length)
-+{
-+  return res_query (domain, C_IN, type, answer, answer_length);
-+}
-+
-+static int
-+wrap_res_querydomain (int type, unsigned char *answer, int answer_length)
-+{
-+  return res_querydomain ("www", "example.com", C_IN, type,
-+                           answer, answer_length);
-+}
-+
-+static int
-+wrap_res_send (int type, unsigned char *answer, int answer_length)
-+{
-+  unsigned char buf[512];
-+  int ret = res_mkquery (QUERY, domain, C_IN, type,
-+                         (const unsigned char *) "", 0, NULL,
-+                         buf, sizeof (buf));
-+  if (type < 0 || type >= 65536)
-+    {
-+      /* res_mkquery fails for out-of-range record types.  */
-+      TEST_VERIFY_EXIT (ret == -1);
-+      return -1;
-+    }
-+  TEST_VERIFY_EXIT (ret > 12);  /* DNS header length.  */
-+  return res_send (buf, ret, answer, answer_length);
-+}
-+
-+static int
-+wrap_res_nquery (int type, unsigned char *answer, int answer_length)
-+{
-+  return res_nquery (&_res, domain, C_IN, type, answer, answer_length);
-+}
-+
-+static int
-+wrap_res_nsearch (int type, unsigned char *answer, int answer_length)
-+{
-+  return res_nquery (&_res, domain, C_IN, type, answer, answer_length);
-+}
-+
-+static int
-+wrap_res_nquerydomain (int type, unsigned char *answer, int answer_length)
-+{
-+  return res_nquerydomain (&_res, "www", "example.com", C_IN, type,
-+                           answer, answer_length);
-+}
-+
-+static int
-+wrap_res_nsend (int type, unsigned char *answer, int answer_length)
-+{
-+  unsigned char buf[512];
-+  int ret = res_nmkquery (&_res, QUERY, domain, C_IN, type,
-+                         (const unsigned char *) "", 0, NULL,
-+                         buf, sizeof (buf));
-+  if (type < 0 || type >= 65536)
-+    {
-+      /* res_mkquery fails for out-of-range record types.  */
-+      TEST_VERIFY_EXIT (ret == -1);
-+      return -1;
-+    }
-+  TEST_VERIFY_EXIT (ret > 12);  /* DNS header length.  */
-+  return res_nsend (&_res, buf, ret, answer, answer_length);
-+}
-+
-+static void
-+test_function (const char *fname,
-+               int (*func) (int type,
-+                            unsigned char *answer, int answer_length))
-+{
-+  unsigned char buf[512];
-+  for (int tcp = 0; tcp < 2; ++tcp)
-+    {
-+      force_tcp = tcp;
-+      for (unsigned int type = 1; type <= 65535; ++type)
-+        {
-+          if (test_verbose)
-+            printf ("info: sending QTYPE %d with %s (tcp=%d)\n",
-+                    type, fname, tcp);
-+          int ret = func (type, buf, sizeof (buf));
-+          if (ret != 47)
-+            FAIL_EXIT1 ("%s tcp=%d qtype=%d return value %d",
-+                        fname,tcp, type, ret);
-+          /* One question, one answer record.  */
-+          TEST_VERIFY (memcmp (buf + 4, "\0\1\0\1\0\0\0\0", 8) == 0);
-+          /* Question section.  */
-+          static const char qname[] = "\3www\7example\3com";
-+          size_t qname_length = sizeof (qname);
-+          TEST_VERIFY (memcmp (buf + 12, qname, qname_length) == 0);
-+          /* RDATA part of answer.  */
-+          uint16_t type16 = type;
-+          TEST_VERIFY (memcmp (buf + ret - 2, &type16, sizeof (type16)) == 0);
-+        }
-+    }
-+
-+  TEST_VERIFY (func (-1, buf, sizeof (buf) == -1));
-+  TEST_VERIFY (func (65536, buf, sizeof (buf) == -1));
-+}
-+
-+static int
-+do_test (void)
-+{
-+  struct resolv_redirect_config config =
-+    {
-+      .response_callback = response,
-+    };
-+  struct resolv_test *obj = resolv_test_start (config);
-+
-+  test_function ("res_query", &wrap_res_query);
-+  test_function ("res_search", &wrap_res_search);
-+  test_function ("res_querydomain", &wrap_res_querydomain);
-+  test_function ("res_send", &wrap_res_send);
-+
-+  test_function ("res_nquery", &wrap_res_nquery);
-+  test_function ("res_nsearch", &wrap_res_nsearch);
-+  test_function ("res_nquerydomain", &wrap_res_nquerydomain);
-+  test_function ("res_nsend", &wrap_res_nsend);
-+
-+  resolv_test_end (obj);
-+  return 0;
-+}
-+
-+#define TIMEOUT 300
-+#include <support/test-driver.c>
--- 
-2.9.3
-
diff --git a/gnu/packages/patches/glibc-CVE-2015-7547.patch b/gnu/packages/patches/glibc-CVE-2015-7547.patch
deleted file mode 100644
index 12abeb76d4..0000000000
--- a/gnu/packages/patches/glibc-CVE-2015-7547.patch
+++ /dev/null
@@ -1,590 +0,0 @@
-From b995d95a5943785be3ab862b2d3276f3b4a22481 Mon Sep 17 00:00:00 2001
-From: Carlos O'Donell <carlos@systemhalted.org>
-Date: Tue, 16 Feb 2016 21:26:37 -0500
-Subject: [PATCH] CVE-2015-7547: getaddrinfo() stack-based buffer overflow (Bug
- 18665).
-
-* A stack-based buffer overflow was found in libresolv when invoked from
-  libnss_dns, allowing specially crafted DNS responses to seize control
-  of execution flow in the DNS client.  The buffer overflow occurs in
-  the functions send_dg (send datagram) and send_vc (send TCP) for the
-  NSS module libnss_dns.so.2 when calling getaddrinfo with AF_UNSPEC
-  family.  The use of AF_UNSPEC triggers the low-level resolver code to
-  send out two parallel queries for A and AAAA.  A mismanagement of the
-  buffers used for those queries could result in the response of a query
-  writing beyond the alloca allocated buffer created by
-  _nss_dns_gethostbyname4_r.  Buffer management is simplified to remove
-  the overflow.  Thanks to the Google Security Team and Red Hat for
-  reporting the security impact of this issue, and Robert Holiday of
-  Ciena for reporting the related bug 18665. (CVE-2015-7547)
-
-See also:
-https://sourceware.org/ml/libc-alpha/2016-02/msg00416.html
-https://sourceware.org/ml/libc-alpha/2016-02/msg00418.html
-
-(cherry picked from commit e9db92d3acfe1822d56d11abcea5bfc4c41cf6ca)
----
- ChangeLog                 |  15 +++
- NEWS                      |  14 +++
- resolv/nss_dns/dns-host.c | 111 ++++++++++++++++++-
- resolv/res_query.c        |   3 +
- resolv/res_send.c         | 264 ++++++++++++++++++++++++++++++++++------------
- 5 files changed, 338 insertions(+), 69 deletions(-)
-
-diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
-index 357ac04..a0fe9a8 100644
---- a/resolv/nss_dns/dns-host.c
-+++ b/resolv/nss_dns/dns-host.c
-@@ -1031,7 +1031,10 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
-   int h_namelen = 0;
- 
-   if (ancount == 0)
--    return NSS_STATUS_NOTFOUND;
-+    {
-+      *h_errnop = HOST_NOT_FOUND;
-+      return NSS_STATUS_NOTFOUND;
-+    }
- 
-   while (ancount-- > 0 && cp < end_of_message && had_error == 0)
-     {
-@@ -1208,7 +1211,14 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
-   /* Special case here: if the resolver sent a result but it only
-      contains a CNAME while we are looking for a T_A or T_AAAA record,
-      we fail with NOTFOUND instead of TRYAGAIN.  */
--  return canon == NULL ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
-+  if (canon != NULL)
-+    {
-+      *h_errnop = HOST_NOT_FOUND;
-+      return NSS_STATUS_NOTFOUND;
-+    }
-+
-+  *h_errnop = NETDB_INTERNAL;
-+  return NSS_STATUS_TRYAGAIN;
- }
- 
- 
-@@ -1222,11 +1232,101 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
- 
-   enum nss_status status = NSS_STATUS_NOTFOUND;
- 
-+  /* Combining the NSS status of two distinct queries requires some
-+     compromise and attention to symmetry (A or AAAA queries can be
-+     returned in any order).  What follows is a breakdown of how this
-+     code is expected to work and why. We discuss only SUCCESS,
-+     TRYAGAIN, NOTFOUND and UNAVAIL, since they are the only returns
-+     that apply (though RETURN and MERGE exist).  We make a distinction
-+     between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable).
-+     A recoverable TRYAGAIN is almost always due to buffer size issues
-+     and returns ERANGE in errno and the caller is expected to retry
-+     with a larger buffer.
-+
-+     Lastly, you may be tempted to make significant changes to the
-+     conditions in this code to bring about symmetry between responses.
-+     Please don't change anything without due consideration for
-+     expected application behaviour.  Some of the synthesized responses
-+     aren't very well thought out and sometimes appear to imply that
-+     IPv4 responses are always answer 1, and IPv6 responses are always
-+     answer 2, but that's not true (see the implementation of send_dg
-+     and send_vc to see response can arrive in any order, particularly
-+     for UDP). However, we expect it holds roughly enough of the time
-+     that this code works, but certainly needs to be fixed to make this
-+     a more robust implementation.
-+
-+     ----------------------------------------------
-+     | Answer 1 Status /   | Synthesized | Reason |
-+     | Answer 2 Status     | Status      |        |
-+     |--------------------------------------------|
-+     | SUCCESS/SUCCESS     | SUCCESS     | [1]    |
-+     | SUCCESS/TRYAGAIN    | TRYAGAIN    | [5]    |
-+     | SUCCESS/TRYAGAIN'   | SUCCESS     | [1]    |
-+     | SUCCESS/NOTFOUND    | SUCCESS     | [1]    |
-+     | SUCCESS/UNAVAIL     | SUCCESS     | [1]    |
-+     | TRYAGAIN/SUCCESS    | TRYAGAIN    | [2]    |
-+     | TRYAGAIN/TRYAGAIN   | TRYAGAIN    | [2]    |
-+     | TRYAGAIN/TRYAGAIN'  | TRYAGAIN    | [2]    |
-+     | TRYAGAIN/NOTFOUND   | TRYAGAIN    | [2]    |
-+     | TRYAGAIN/UNAVAIL    | TRYAGAIN    | [2]    |
-+     | TRYAGAIN'/SUCCESS   | SUCCESS     | [3]    |
-+     | TRYAGAIN'/TRYAGAIN  | TRYAGAIN    | [3]    |
-+     | TRYAGAIN'/TRYAGAIN' | TRYAGAIN'   | [3]    |
-+     | TRYAGAIN'/NOTFOUND  | TRYAGAIN'   | [3]    |
-+     | TRYAGAIN'/UNAVAIL   | UNAVAIL     | [3]    |
-+     | NOTFOUND/SUCCESS    | SUCCESS     | [3]    |
-+     | NOTFOUND/TRYAGAIN   | TRYAGAIN    | [3]    |
-+     | NOTFOUND/TRYAGAIN'  | TRYAGAIN'   | [3]    |
-+     | NOTFOUND/NOTFOUND   | NOTFOUND    | [3]    |
-+     | NOTFOUND/UNAVAIL    | UNAVAIL     | [3]    |
-+     | UNAVAIL/SUCCESS     | UNAVAIL     | [4]    |
-+     | UNAVAIL/TRYAGAIN    | UNAVAIL     | [4]    |
-+     | UNAVAIL/TRYAGAIN'   | UNAVAIL     | [4]    |
-+     | UNAVAIL/NOTFOUND    | UNAVAIL     | [4]    |
-+     | UNAVAIL/UNAVAIL     | UNAVAIL     | [4]    |
-+     ----------------------------------------------
-+
-+     [1] If the first response is a success we return success.
-+	 This ignores the state of the second answer and in fact
-+	 incorrectly sets errno and h_errno to that of the second
-+	 answer.  However because the response is a success we ignore
-+	 *errnop and *h_errnop (though that means you touched errno on
-+	 success).  We are being conservative here and returning the
-+	 likely IPv4 response in the first answer as a success.
-+
-+     [2] If the first response is a recoverable TRYAGAIN we return
-+	 that instead of looking at the second response.  The
-+	 expectation here is that we have failed to get an IPv4 response
-+	 and should retry both queries.
-+
-+     [3] If the first response was not a SUCCESS and the second
-+	 response is not NOTFOUND (had a SUCCESS, need to TRYAGAIN,
-+	 or failed entirely e.g. TRYAGAIN' and UNAVAIL) then use the
-+	 result from the second response, otherwise the first responses
-+	 status is used.  Again we have some odd side-effects when the
-+	 second response is NOTFOUND because we overwrite *errnop and
-+	 *h_errnop that means that a first answer of NOTFOUND might see
-+	 its *errnop and *h_errnop values altered.  Whether it matters
-+	 in practice that a first response NOTFOUND has the wrong
-+	 *errnop and *h_errnop is undecided.
-+
-+     [4] If the first response is UNAVAIL we return that instead of
-+	 looking at the second response.  The expectation here is that
-+	 it will have failed similarly e.g. configuration failure.
-+
-+     [5] Testing this code is complicated by the fact that truncated
-+	 second response buffers might be returned as SUCCESS if the
-+	 first answer is a SUCCESS.  To fix this we add symmetry to
-+	 TRYAGAIN with the second response.  If the second response
-+	 is a recoverable error we now return TRYAGIN even if the first
-+	 response was SUCCESS.  */
-+
-   if (anslen1 > 0)
-     status = gaih_getanswer_slice(answer1, anslen1, qname,
- 				  &pat, &buffer, &buflen,
- 				  errnop, h_errnop, ttlp,
- 				  &first);
-+
-   if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
-        || (status == NSS_STATUS_TRYAGAIN
- 	   /* We want to look at the second answer in case of an
-@@ -1242,8 +1342,15 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
- 						     &pat, &buffer, &buflen,
- 						     errnop, h_errnop, ttlp,
- 						     &first);
-+      /* Use the second response status in some cases.  */
-       if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND)
- 	status = status2;
-+      /* Do not return a truncated second response (unless it was
-+	 unavoidable e.g. unrecoverable TRYAGAIN).  */
-+      if (status == NSS_STATUS_SUCCESS
-+	  && (status2 == NSS_STATUS_TRYAGAIN
-+	      && *errnop == ERANGE && *h_errnop != NO_RECOVERY))
-+	status = NSS_STATUS_TRYAGAIN;
-     }
- 
-   return status;
-diff --git a/resolv/res_query.c b/resolv/res_query.c
-index 4a9b3b3..95470a9 100644
---- a/resolv/res_query.c
-+++ b/resolv/res_query.c
-@@ -396,6 +396,7 @@ __libc_res_nsearch(res_state statp,
- 		  {
- 		    free (*answerp2);
- 		    *answerp2 = NULL;
-+		    *nanswerp2 = 0;
- 		    *answerp2_malloced = 0;
- 		  }
- 	}
-@@ -447,6 +448,7 @@ __libc_res_nsearch(res_state statp,
- 			  {
- 			    free (*answerp2);
- 			    *answerp2 = NULL;
-+			    *nanswerp2 = 0;
- 			    *answerp2_malloced = 0;
- 			  }
- 
-@@ -521,6 +523,7 @@ __libc_res_nsearch(res_state statp,
- 	  {
- 	    free (*answerp2);
- 	    *answerp2 = NULL;
-+	    *nanswerp2 = 0;
- 	    *answerp2_malloced = 0;
- 	  }
- 	if (saved_herrno != -1)
-diff --git a/resolv/res_send.c b/resolv/res_send.c
-index 5e53cc2..6511bb1 100644
---- a/resolv/res_send.c
-+++ b/resolv/res_send.c
-@@ -1,3 +1,20 @@
-+/* Copyright (C) 2016 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/>.  */
-+
- /*
-  * Copyright (c) 1985, 1989, 1993
-  *    The Regents of the University of California.  All rights reserved.
-@@ -363,6 +380,8 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
- #ifdef USE_HOOKS
- 	if (__glibc_unlikely (statp->qhook || statp->rhook))       {
- 		if (anssiz < MAXPACKET && ansp) {
-+			/* Always allocate MAXPACKET, callers expect
-+			   this specific size.  */
- 			u_char *buf = malloc (MAXPACKET);
- 			if (buf == NULL)
- 				return (-1);
-@@ -638,6 +657,77 @@ get_nsaddr (res_state statp, int n)
-     return (struct sockaddr *) (void *) &statp->nsaddr_list[n];
- }
- 
-+/* The send_vc function is responsible for sending a DNS query over TCP
-+   to the nameserver numbered NS from the res_state STATP i.e.
-+   EXT(statp).nssocks[ns].  The function supports sending both IPv4 and
-+   IPv6 queries at the same serially on the same socket.
-+
-+   Please note that for TCP there is no way to disable sending both
-+   queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP
-+   and sends the queries serially and waits for the result after each
-+   sent query.  This implemetnation should be corrected to honour these
-+   options.
-+
-+   Please also note that for TCP we send both queries over the same
-+   socket one after another.  This technically violates best practice
-+   since the server is allowed to read the first query, respond, and
-+   then close the socket (to service another client).  If the server
-+   does this, then the remaining second query in the socket data buffer
-+   will cause the server to send the client an RST which will arrive
-+   asynchronously and the client's OS will likely tear down the socket
-+   receive buffer resulting in a potentially short read and lost
-+   response data.  This will force the client to retry the query again,
-+   and this process may repeat until all servers and connection resets
-+   are exhausted and then the query will fail.  It's not known if this
-+   happens with any frequency in real DNS server implementations.  This
-+   implementation should be corrected to use two sockets by default for
-+   parallel queries.
-+
-+   The query stored in BUF of BUFLEN length is sent first followed by
-+   the query stored in BUF2 of BUFLEN2 length.  Queries are sent
-+   serially on the same socket.
-+
-+   Answers to the query are stored firstly in *ANSP up to a max of
-+   *ANSSIZP bytes.  If more than *ANSSIZP bytes are needed and ANSCP
-+   is non-NULL (to indicate that modifying the answer buffer is allowed)
-+   then malloc is used to allocate a new response buffer and ANSCP and
-+   ANSP will both point to the new buffer.  If more than *ANSSIZP bytes
-+   are needed but ANSCP is NULL, then as much of the response as
-+   possible is read into the buffer, but the results will be truncated.
-+   When truncation happens because of a small answer buffer the DNS
-+   packets header field TC will bet set to 1, indicating a truncated
-+   message and the rest of the socket data will be read and discarded.
-+
-+   Answers to the query are stored secondly in *ANSP2 up to a max of
-+   *ANSSIZP2 bytes, with the actual response length stored in
-+   *RESPLEN2.  If more than *ANSSIZP bytes are needed and ANSP2
-+   is non-NULL (required for a second query) then malloc is used to
-+   allocate a new response buffer, *ANSSIZP2 is set to the new buffer
-+   size and *ANSP2_MALLOCED is set to 1.
-+
-+   The ANSP2_MALLOCED argument will eventually be removed as the
-+   change in buffer pointer can be used to detect the buffer has
-+   changed and that the caller should use free on the new buffer.
-+
-+   Note that the answers may arrive in any order from the server and
-+   therefore the first and second answer buffers may not correspond to
-+   the first and second queries.
-+
-+   It is not supported to call this function with a non-NULL ANSP2
-+   but a NULL ANSCP.  Put another way, you can call send_vc with a
-+   single unmodifiable buffer or two modifiable buffers, but no other
-+   combination is supported.
-+
-+   It is the caller's responsibility to free the malloc allocated
-+   buffers by detecting that the pointers have changed from their
-+   original values i.e. *ANSCP or *ANSP2 has changed.
-+
-+   If errors are encountered then *TERRNO is set to an appropriate
-+   errno value and a zero result is returned for a recoverable error,
-+   and a less-than zero result is returned for a non-recoverable error.
-+
-+   If no errors are encountered then *TERRNO is left unmodified and
-+   a the length of the first response in bytes is returned.  */
- static int
- send_vc(res_state statp,
- 	const u_char *buf, int buflen, const u_char *buf2, int buflen2,
-@@ -647,11 +737,7 @@ send_vc(res_state statp,
- {
- 	const HEADER *hp = (HEADER *) buf;
- 	const HEADER *hp2 = (HEADER *) buf2;
--	u_char *ans = *ansp;
--	int orig_anssizp = *anssizp;
--	// XXX REMOVE
--	// int anssiz = *anssizp;
--	HEADER *anhp = (HEADER *) ans;
-+	HEADER *anhp = (HEADER *) *ansp;
- 	struct sockaddr *nsap = get_nsaddr (statp, ns);
- 	int truncating, connreset, n;
- 	/* On some architectures compiler might emit a warning indicating
-@@ -743,6 +829,8 @@ send_vc(res_state statp,
- 	 * Receive length & response
- 	 */
- 	int recvresp1 = 0;
-+	/* Skip the second response if there is no second query.
-+	   To do that we mark the second response as received.  */
- 	int recvresp2 = buf2 == NULL;
- 	uint16_t rlen16;
-  read_len:
-@@ -779,40 +867,14 @@ send_vc(res_state statp,
- 	u_char **thisansp;
- 	int *thisresplenp;
- 	if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
-+		/* We have not received any responses
-+		   yet or we only have one response to
-+		   receive.  */
- 		thisanssizp = anssizp;
- 		thisansp = anscp ?: ansp;
- 		assert (anscp != NULL || ansp2 == NULL);
- 		thisresplenp = &resplen;
- 	} else {
--		if (*anssizp != MAXPACKET) {
--			/* No buffer allocated for the first
--			   reply.  We can try to use the rest
--			   of the user-provided buffer.  */
--#if __GNUC_PREREQ (4, 7)
--			DIAG_PUSH_NEEDS_COMMENT;
--			DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
--#endif
--#if _STRING_ARCH_unaligned
--			*anssizp2 = orig_anssizp - resplen;
--			*ansp2 = *ansp + resplen;
--#else
--			int aligned_resplen
--			  = ((resplen + __alignof__ (HEADER) - 1)
--			     & ~(__alignof__ (HEADER) - 1));
--			*anssizp2 = orig_anssizp - aligned_resplen;
--			*ansp2 = *ansp + aligned_resplen;
--#endif
--#if __GNUC_PREREQ (4, 7)
--			DIAG_POP_NEEDS_COMMENT;
--#endif
--		} else {
--			/* The first reply did not fit into the
--			   user-provided buffer.  Maybe the second
--			   answer will.  */
--			*anssizp2 = orig_anssizp;
--			*ansp2 = *ansp;
--		}
--
- 		thisanssizp = anssizp2;
- 		thisansp = ansp2;
- 		thisresplenp = resplen2;
-@@ -820,10 +882,14 @@ send_vc(res_state statp,
- 	anhp = (HEADER *) *thisansp;
- 
- 	*thisresplenp = rlen;
--	if (rlen > *thisanssizp) {
--		/* Yes, we test ANSCP here.  If we have two buffers
--		   both will be allocatable.  */
--		if (__glibc_likely (anscp != NULL))       {
-+	/* Is the answer buffer too small?  */
-+	if (*thisanssizp < rlen) {
-+		/* If the current buffer is not the the static
-+		   user-supplied buffer then we can reallocate
-+		   it.  */
-+		if (thisansp != NULL && thisansp != ansp) {
-+			/* Always allocate MAXPACKET, callers expect
-+			   this specific size.  */
- 			u_char *newp = malloc (MAXPACKET);
- 			if (newp == NULL) {
- 				*terrno = ENOMEM;
-@@ -835,6 +901,9 @@ send_vc(res_state statp,
- 			if (thisansp == ansp2)
- 			  *ansp2_malloced = 1;
- 			anhp = (HEADER *) newp;
-+			/* A uint16_t can't be larger than MAXPACKET
-+			   thus it's safe to allocate MAXPACKET but
-+			   read RLEN bytes instead.  */
- 			len = rlen;
- 		} else {
- 			Dprint(statp->options & RES_DEBUG,
-@@ -997,6 +1066,66 @@ reopen (res_state statp, int *terrno, int ns)
- 	return 1;
- }
- 
-+/* The send_dg function is responsible for sending a DNS query over UDP
-+   to the nameserver numbered NS from the res_state STATP i.e.
-+   EXT(statp).nssocks[ns].  The function supports IPv4 and IPv6 queries
-+   along with the ability to send the query in parallel for both stacks
-+   (default) or serially (RES_SINGLKUP).  It also supports serial lookup
-+   with a close and reopen of the socket used to talk to the server
-+   (RES_SNGLKUPREOP) to work around broken name servers.
-+
-+   The query stored in BUF of BUFLEN length is sent first followed by
-+   the query stored in BUF2 of BUFLEN2 length.  Queries are sent
-+   in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP).
-+
-+   Answers to the query are stored firstly in *ANSP up to a max of
-+   *ANSSIZP bytes.  If more than *ANSSIZP bytes are needed and ANSCP
-+   is non-NULL (to indicate that modifying the answer buffer is allowed)
-+   then malloc is used to allocate a new response buffer and ANSCP and
-+   ANSP will both point to the new buffer.  If more than *ANSSIZP bytes
-+   are needed but ANSCP is NULL, then as much of the response as
-+   possible is read into the buffer, but the results will be truncated.
-+   When truncation happens because of a small answer buffer the DNS
-+   packets header field TC will bet set to 1, indicating a truncated
-+   message, while the rest of the UDP packet is discarded.
-+
-+   Answers to the query are stored secondly in *ANSP2 up to a max of
-+   *ANSSIZP2 bytes, with the actual response length stored in
-+   *RESPLEN2.  If more than *ANSSIZP bytes are needed and ANSP2
-+   is non-NULL (required for a second query) then malloc is used to
-+   allocate a new response buffer, *ANSSIZP2 is set to the new buffer
-+   size and *ANSP2_MALLOCED is set to 1.
-+
-+   The ANSP2_MALLOCED argument will eventually be removed as the
-+   change in buffer pointer can be used to detect the buffer has
-+   changed and that the caller should use free on the new buffer.
-+
-+   Note that the answers may arrive in any order from the server and
-+   therefore the first and second answer buffers may not correspond to
-+   the first and second queries.
-+
-+   It is not supported to call this function with a non-NULL ANSP2
-+   but a NULL ANSCP.  Put another way, you can call send_vc with a
-+   single unmodifiable buffer or two modifiable buffers, but no other
-+   combination is supported.
-+
-+   It is the caller's responsibility to free the malloc allocated
-+   buffers by detecting that the pointers have changed from their
-+   original values i.e. *ANSCP or *ANSP2 has changed.
-+
-+   If an answer is truncated because of UDP datagram DNS limits then
-+   *V_CIRCUIT is set to 1 and the return value non-zero to indicate to
-+   the caller to retry with TCP.  The value *GOTSOMEWHERE is set to 1
-+   if any progress was made reading a response from the nameserver and
-+   is used by the caller to distinguish between ECONNREFUSED and
-+   ETIMEDOUT (the latter if *GOTSOMEWHERE is 1).
-+
-+   If errors are encountered then *TERRNO is set to an appropriate
-+   errno value and a zero result is returned for a recoverable error,
-+   and a less-than zero result is returned for a non-recoverable error.
-+
-+   If no errors are encountered then *TERRNO is left unmodified and
-+   a the length of the first response in bytes is returned.  */
- static int
- send_dg(res_state statp,
- 	const u_char *buf, int buflen, const u_char *buf2, int buflen2,
-@@ -1006,8 +1135,6 @@ send_dg(res_state statp,
- {
- 	const HEADER *hp = (HEADER *) buf;
- 	const HEADER *hp2 = (HEADER *) buf2;
--	u_char *ans = *ansp;
--	int orig_anssizp = *anssizp;
- 	struct timespec now, timeout, finish;
- 	struct pollfd pfd[1];
- 	int ptimeout;
-@@ -1040,6 +1167,8 @@ send_dg(res_state statp,
- 	int need_recompute = 0;
- 	int nwritten = 0;
- 	int recvresp1 = 0;
-+	/* Skip the second response if there is no second query.
-+	   To do that we mark the second response as received.  */
- 	int recvresp2 = buf2 == NULL;
- 	pfd[0].fd = EXT(statp).nssocks[ns];
- 	pfd[0].events = POLLOUT;
-@@ -1203,55 +1332,56 @@ send_dg(res_state statp,
- 		int *thisresplenp;
- 
- 		if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
-+			/* We have not received any responses
-+			   yet or we only have one response to
-+			   receive.  */
- 			thisanssizp = anssizp;
- 			thisansp = anscp ?: ansp;
- 			assert (anscp != NULL || ansp2 == NULL);
- 			thisresplenp = &resplen;
- 		} else {
--			if (*anssizp != MAXPACKET) {
--				/* No buffer allocated for the first
--				   reply.  We can try to use the rest
--				   of the user-provided buffer.  */
--#if _STRING_ARCH_unaligned
--				*anssizp2 = orig_anssizp - resplen;
--				*ansp2 = *ansp + resplen;
--#else
--				int aligned_resplen
--				  = ((resplen + __alignof__ (HEADER) - 1)
--				     & ~(__alignof__ (HEADER) - 1));
--				*anssizp2 = orig_anssizp - aligned_resplen;
--				*ansp2 = *ansp + aligned_resplen;
--#endif
--			} else {
--				/* The first reply did not fit into the
--				   user-provided buffer.  Maybe the second
--				   answer will.  */
--				*anssizp2 = orig_anssizp;
--				*ansp2 = *ansp;
--			}
--
- 			thisanssizp = anssizp2;
- 			thisansp = ansp2;
- 			thisresplenp = resplen2;
- 		}
- 
- 		if (*thisanssizp < MAXPACKET
--		    /* Yes, we test ANSCP here.  If we have two buffers
--		       both will be allocatable.  */
--		    && anscp
-+		    /* If the current buffer is not the the static
-+		       user-supplied buffer then we can reallocate
-+		       it.  */
-+		    && (thisansp != NULL && thisansp != ansp)
- #ifdef FIONREAD
-+		    /* Is the size too small?  */
- 		    && (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0
- 			|| *thisanssizp < *thisresplenp)
- #endif
-                     ) {
-+			/* Always allocate MAXPACKET, callers expect
-+			   this specific size.  */
- 			u_char *newp = malloc (MAXPACKET);
- 			if (newp != NULL) {
--				*anssizp = MAXPACKET;
--				*thisansp = ans = newp;
-+				*thisanssizp = MAXPACKET;
-+				*thisansp = newp;
- 				if (thisansp == ansp2)
- 				  *ansp2_malloced = 1;
- 			}
- 		}
-+		/* We could end up with truncation if anscp was NULL
-+		   (not allowed to change caller's buffer) and the
-+		   response buffer size is too small.  This isn't a
-+		   reliable way to detect truncation because the ioctl
-+		   may be an inaccurate report of the UDP message size.
-+		   Therefore we use this only to issue debug output.
-+		   To do truncation accurately with UDP we need
-+		   MSG_TRUNC which is only available on Linux.  We
-+		   can abstract out the Linux-specific feature in the
-+		   future to detect truncation.  */
-+		if (__glibc_unlikely (*thisanssizp < *thisresplenp)) {
-+			Dprint(statp->options & RES_DEBUG,
-+			       (stdout, ";; response may be truncated (UDP)\n")
-+			);
-+		}
-+
- 		HEADER *anhp = (HEADER *) *thisansp;
- 		socklen_t fromlen = sizeof(struct sockaddr_in6);
- 		assert (sizeof(from) <= fromlen);
--- 
-2.9.3
-
diff --git a/gnu/packages/patches/glibc-CVE-2016-3075.patch b/gnu/packages/patches/glibc-CVE-2016-3075.patch
deleted file mode 100644
index d16722806e..0000000000
--- a/gnu/packages/patches/glibc-CVE-2016-3075.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 146b58d11fddbef15b888906e3be4f33900c416f Mon Sep 17 00:00:00 2001
-From: Florian Weimer <fweimer@redhat.com>
-Date: Tue, 29 Mar 2016 12:57:56 +0200
-Subject: [PATCH] CVE-2016-3075: Stack overflow in _nss_dns_getnetbyname_r [BZ
- #19879]
-
-The defensive copy is not needed because the name may not alias the
-output buffer.
-
-(cherry picked from commit 317b199b4aff8cfa27f2302ab404d2bb5032b9a4)
-(cherry picked from commit 883dceebc8f11921a9890211a4e202e5be17562f)
----
- ChangeLog                    |  7 +++++++
- NEWS                         | 10 ++++++++--
- resolv/nss_dns/dns-network.c |  5 +----
- 3 files changed, 16 insertions(+), 6 deletions(-)
-
-diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c
-index 2eb2f67..8f301a7 100644
---- a/resolv/nss_dns/dns-network.c
-+++ b/resolv/nss_dns/dns-network.c
-@@ -118,17 +118,14 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result,
-   } net_buffer;
-   querybuf *orig_net_buffer;
-   int anslen;
--  char *qbuf;
-   enum nss_status status;
- 
-   if (__res_maybe_init (&_res, 0) == -1)
-     return NSS_STATUS_UNAVAIL;
- 
--  qbuf = strdupa (name);
--
-   net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
- 
--  anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
-+  anslen = __libc_res_nsearch (&_res, name, C_IN, T_PTR, net_buffer.buf->buf,
- 			       1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
-   if (anslen < 0)
-     {
--- 
-2.9.3
-
diff --git a/gnu/packages/patches/glibc-CVE-2016-3706.patch b/gnu/packages/patches/glibc-CVE-2016-3706.patch
deleted file mode 100644
index 617242df24..0000000000
--- a/gnu/packages/patches/glibc-CVE-2016-3706.patch
+++ /dev/null
@@ -1,188 +0,0 @@
-From 1a8a7c12950a0026a3c406a7cb1608f96aa1460e Mon Sep 17 00:00:00 2001
-From: Florian Weimer <fweimer@redhat.com>
-Date: Fri, 29 Apr 2016 10:35:34 +0200
-Subject: [PATCH] CVE-2016-3706: getaddrinfo: stack overflow in hostent
- conversion [BZ #20010]
-
-When converting a struct hostent response to struct gaih_addrtuple, the
-gethosts macro (which is called from gaih_inet) used alloca, without
-malloc fallback for large responses.  This commit changes this code to
-use calloc unconditionally.
-
-This commit also consolidated a second hostent-to-gaih_addrtuple
-conversion loop (in gaih_inet) to use the new conversion function.
-
-(cherry picked from commit 4ab2ab03d4351914ee53248dc5aef4a8c88ff8b9)
----
- ChangeLog                   |  10 ++++
- sysdeps/posix/getaddrinfo.c | 130 +++++++++++++++++++++++---------------------
- 2 files changed, 79 insertions(+), 61 deletions(-)
-
-diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
-index 1ef3f20..fed2d3b 100644
---- a/sysdeps/posix/getaddrinfo.c
-+++ b/sysdeps/posix/getaddrinfo.c
-@@ -168,9 +168,58 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
-   return 0;
- }
- 
-+/* Convert struct hostent to a list of struct gaih_addrtuple objects.
-+   h_name is not copied, and the struct hostent object must not be
-+   deallocated prematurely.  *RESULT must be NULL or a pointer to an
-+   object allocated using malloc, which is freed.  */
-+static bool
-+convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
-+				   int family,
-+				   struct hostent *h,
-+				   struct gaih_addrtuple **result)
-+{
-+  free (*result);
-+  *result = NULL;
-+
-+  /* Count the number of addresses in h->h_addr_list.  */
-+  size_t count = 0;
-+  for (char **p = h->h_addr_list; *p != NULL; ++p)
-+    ++count;
-+
-+  /* Report no data if no addresses are available, or if the incoming
-+     address size is larger than what we can store.  */
-+  if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
-+    return true;
-+
-+  struct gaih_addrtuple *array = calloc (count, sizeof (*array));
-+  if (array == NULL)
-+    return false;
-+
-+  for (size_t i = 0; i < count; ++i)
-+    {
-+      if (family == AF_INET && req->ai_family == AF_INET6)
-+	{
-+	  /* Perform address mapping. */
-+	  array[i].family = AF_INET6;
-+	  memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t));
-+	  array[i].addr[2] = htonl (0xffff);
-+	}
-+      else
-+	{
-+	  array[i].family = family;
-+	  memcpy (array[i].addr, h->h_addr_list[i], h->h_length);
-+	}
-+      array[i].next = array + i + 1;
-+    }
-+  array[0].name = h->h_name;
-+  array[count - 1].next = NULL;
-+
-+  *result = array;
-+  return true;
-+}
-+
- #define gethosts(_family, _type) \
-  {									      \
--  int i;								      \
-   int herrno;								      \
-   struct hostent th;							      \
-   struct hostent *h;							      \
-@@ -219,36 +268,23 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
-     }									      \
-   else if (h != NULL)							      \
-     {									      \
--      for (i = 0; h->h_addr_list[i]; i++)				      \
-+      /* Make sure that addrmem can be freed.  */			      \
-+      if (!malloc_addrmem)						      \
-+	addrmem = NULL;							      \
-+      if (!convert_hostent_to_gaih_addrtuple (req, _family,h, &addrmem))      \
- 	{								      \
--	  if (*pat == NULL)						      \
--	    {								      \
--	      *pat = __alloca (sizeof (struct gaih_addrtuple));		      \
--	      (*pat)->scopeid = 0;					      \
--	    }								      \
--	  uint32_t *addr = (*pat)->addr;				      \
--	  (*pat)->next = NULL;						      \
--	  (*pat)->name = i == 0 ? strdupa (h->h_name) : NULL;		      \
--	  if (_family == AF_INET && req->ai_family == AF_INET6)		      \
--	    {								      \
--	      (*pat)->family = AF_INET6;				      \
--	      addr[3] = *(uint32_t *) h->h_addr_list[i];		      \
--	      addr[2] = htonl (0xffff);					      \
--	      addr[1] = 0;						      \
--	      addr[0] = 0;						      \
--	    }								      \
--	  else								      \
--	    {								      \
--	      (*pat)->family = _family;					      \
--	      memcpy (addr, h->h_addr_list[i], sizeof(_type));		      \
--	    }								      \
--	  pat = &((*pat)->next);					      \
-+	  _res.options |= old_res_options & RES_USE_INET6;		      \
-+	  result = -EAI_SYSTEM;						      \
-+	  goto free_and_return;						      \
- 	}								      \
-+      *pat = addrmem;							      \
-+      /* The conversion uses malloc unconditionally.  */		      \
-+      malloc_addrmem = true;						      \
- 									      \
-       if (localcanon !=	NULL && canon == NULL)				      \
- 	canon = strdupa (localcanon);					      \
- 									      \
--      if (_family == AF_INET6 && i > 0)					      \
-+      if (_family == AF_INET6 && *pat != NULL)				      \
- 	got_ipv6 = true;						      \
-     }									      \
-  }
-@@ -612,44 +648,16 @@ gaih_inet (const char *name, const struct gaih_service *service,
- 		{
- 		  if (h != NULL)
- 		    {
--		      int i;
--		      /* We found data, count the number of addresses.  */
--		      for (i = 0; h->h_addr_list[i]; ++i)
--			;
--		      if (i > 0 && *pat != NULL)
--			--i;
--
--		      if (__libc_use_alloca (alloca_used
--					     + i * sizeof (struct gaih_addrtuple)))
--			addrmem = alloca_account (i * sizeof (struct gaih_addrtuple),
--						  alloca_used);
--		      else
--			{
--			  addrmem = malloc (i
--					    * sizeof (struct gaih_addrtuple));
--			  if (addrmem == NULL)
--			    {
--			      result = -EAI_MEMORY;
--			      goto free_and_return;
--			    }
--			  malloc_addrmem = true;
--			}
--
--		      /* Now convert it into the list.  */
--		      struct gaih_addrtuple *addrfree = addrmem;
--		      for (i = 0; h->h_addr_list[i]; ++i)
-+		      /* We found data, convert it.  */
-+		      if (!convert_hostent_to_gaih_addrtuple
-+			  (req, AF_INET, h, &addrmem))
- 			{
--			  if (*pat == NULL)
--			    {
--			      *pat = addrfree++;
--			      (*pat)->scopeid = 0;
--			    }
--			  (*pat)->next = NULL;
--			  (*pat)->family = AF_INET;
--			  memcpy ((*pat)->addr, h->h_addr_list[i],
--				  h->h_length);
--			  pat = &((*pat)->next);
-+			  result = -EAI_MEMORY;
-+			  goto free_and_return;
- 			}
-+		      *pat = addrmem;
-+		      /* The conversion uses malloc unconditionally.  */
-+		      malloc_addrmem = true;
- 		    }
- 		}
- 	      else
--- 
-2.9.3
-
diff --git a/gnu/packages/patches/glibc-CVE-2016-4429.patch b/gnu/packages/patches/glibc-CVE-2016-4429.patch
deleted file mode 100644
index 5eebd10543..0000000000
--- a/gnu/packages/patches/glibc-CVE-2016-4429.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From bdce95930e1d9a7d013d1ba78740243491262879 Mon Sep 17 00:00:00 2001
-From: Florian Weimer <fweimer@redhat.com>
-Date: Mon, 23 May 2016 20:18:34 +0200
-Subject: [PATCH] CVE-2016-4429: sunrpc: Do not use alloca in clntudp_call [BZ
- #20112]
-
-The call is technically in a loop, and under certain circumstances
-(which are quite difficult to reproduce in a test case), alloca
-can be invoked repeatedly during a single call to clntudp_call.
-As a result, the available stack space can be exhausted (even
-though individual alloca sizes are bounded implicitly by what
-can fit into a UDP packet, as a side effect of the earlier
-successful send operation).
-
-(cherry picked from commit bc779a1a5b3035133024b21e2f339fe4219fb11c)
----
- ChangeLog         |  7 +++++++
- NEWS              |  4 ++++
- sunrpc/clnt_udp.c | 10 +++++++++-
- 3 files changed, 20 insertions(+), 1 deletion(-)
-
-diff --git a/sunrpc/clnt_udp.c b/sunrpc/clnt_udp.c
-index a6cf5f1..4d9acb1 100644
---- a/sunrpc/clnt_udp.c
-+++ b/sunrpc/clnt_udp.c
-@@ -388,9 +388,15 @@ send_again:
- 	  struct sock_extended_err *e;
- 	  struct sockaddr_in err_addr;
- 	  struct iovec iov;
--	  char *cbuf = (char *) alloca (outlen + 256);
-+	  char *cbuf = malloc (outlen + 256);
- 	  int ret;
- 
-+	  if (cbuf == NULL)
-+	    {
-+	      cu->cu_error.re_errno = errno;
-+	      return (cu->cu_error.re_status = RPC_CANTRECV);
-+	    }
-+
- 	  iov.iov_base = cbuf + 256;
- 	  iov.iov_len = outlen;
- 	  msg.msg_name = (void *) &err_addr;
-@@ -415,10 +421,12 @@ send_again:
- 		 cmsg = CMSG_NXTHDR (&msg, cmsg))
- 	      if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR)
- 		{
-+		  free (cbuf);
- 		  e = (struct sock_extended_err *) CMSG_DATA(cmsg);
- 		  cu->cu_error.re_errno = e->ee_errno;
- 		  return (cu->cu_error.re_status = RPC_CANTRECV);
- 		}
-+	  free (cbuf);
- 	}
- #endif
-       do
--- 
-2.9.3
-
diff --git a/gnu/packages/patches/glibc-CVE-2017-1000366-pt1.patch b/gnu/packages/patches/glibc-CVE-2017-1000366-pt1.patch
deleted file mode 100644
index 71e80968be..0000000000
--- a/gnu/packages/patches/glibc-CVE-2017-1000366-pt1.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From f6110a8fee2ca36f8e2d2abecf3cba9fa7b8ea7d Mon Sep 17 00:00:00 2001
-From: Florian Weimer <fweimer@redhat.com>
-Date: Mon, 19 Jun 2017 17:09:55 +0200
-Subject: [PATCH] CVE-2017-1000366: Ignore LD_LIBRARY_PATH for AT_SECURE=1
- programs [BZ #21624]
-
-LD_LIBRARY_PATH can only be used to reorder system search paths, which
-is not useful functionality.
-
-This makes an exploitable unbounded alloca in _dl_init_paths unreachable
-for AT_SECURE=1 programs.
-
-patch from:
-https://sourceware.org/git/?p=glibc.git;a=commit;h=f6110a8fee2ca36f8e2d2abecf3cba9fa7b8ea7d
----
- ChangeLog  | 7 +++++++
- elf/rtld.c | 3 ++-
- 2 files changed, 9 insertions(+), 1 deletion(-)
-
-diff --git a/elf/rtld.c b/elf/rtld.c
-index 2446a87..2269dbe 100644
---- a/elf/rtld.c
-+++ b/elf/rtld.c
-@@ -2422,7 +2422,8 @@ process_envvars (enum mode *modep)
- 
- 	case 12:
- 	  /* The library search path.  */
--	  if (memcmp (envline, "LIBRARY_PATH", 12) == 0)
-+	  if (!__libc_enable_secure
-+	      && memcmp (envline, "LIBRARY_PATH", 12) == 0)
- 	    {
- 	      library_path = &envline[13];
- 	      break;
--- 
-2.9.3
-
diff --git a/gnu/packages/patches/glibc-CVE-2017-1000366-pt2.patch b/gnu/packages/patches/glibc-CVE-2017-1000366-pt2.patch
deleted file mode 100644
index 4b859c4bfd..0000000000
--- a/gnu/packages/patches/glibc-CVE-2017-1000366-pt2.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From 6d0ba622891bed9d8394eef1935add53003b12e8 Mon Sep 17 00:00:00 2001
-From: Florian Weimer <fweimer@redhat.com>
-Date: Mon, 19 Jun 2017 22:31:04 +0200
-Subject: [PATCH] ld.so: Reject overly long LD_PRELOAD path elements
-
-patch from:
-https://sourceware.org/git/?p=glibc.git;a=patch;h=6d0ba622891bed9d8394eef1935add53003b12e8
-
----
- ChangeLog  |  7 ++++++
- elf/rtld.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++------------
- 2 files changed, 73 insertions(+), 16 deletions(-)
-
-diff --git a/elf/rtld.c b/elf/rtld.c
-index 2269dbe..86ae20c 100644
---- a/elf/rtld.c
-+++ b/elf/rtld.c
-@@ -99,6 +99,35 @@ uintptr_t __pointer_chk_guard_local
- strong_alias (__pointer_chk_guard_local, __pointer_chk_guard)
- #endif
- 
-+/* Length limits for names and paths, to protect the dynamic linker,
-+   particularly when __libc_enable_secure is active.  */
-+#ifdef NAME_MAX
-+# define SECURE_NAME_LIMIT NAME_MAX
-+#else
-+# define SECURE_NAME_LIMIT 255
-+#endif
-+#ifdef PATH_MAX
-+# define SECURE_PATH_LIMIT PATH_MAX
-+#else
-+# define SECURE_PATH_LIMIT 1024
-+#endif
-+
-+/* Check that AT_SECURE=0, or that the passed name does not contain
-+   directories and is not overly long.  Reject empty names
-+   unconditionally.  */
-+static bool
-+dso_name_valid_for_suid (const char *p)
-+{
-+  if (__glibc_unlikely (__libc_enable_secure))
-+    {
-+      /* Ignore pathnames with directories for AT_SECURE=1
-+	 programs, and also skip overlong names.  */
-+      size_t len = strlen (p);
-+      if (len >= SECURE_NAME_LIMIT || memchr (p, '/', len) != NULL)
-+	return false;
-+    }
-+  return *p != '\0';
-+}
- 
- /* List of auditing DSOs.  */
- static struct audit_list
-@@ -718,6 +747,42 @@ static const char *preloadlist attribute_relro;
- /* Nonzero if information about versions has to be printed.  */
- static int version_info attribute_relro;
- 
-+/* The LD_PRELOAD environment variable gives list of libraries
-+   separated by white space or colons that are loaded before the
-+   executable's dependencies and prepended to the global scope list.
-+   (If the binary is running setuid all elements containing a '/' are
-+   ignored since it is insecure.)  Return the number of preloads
-+   performed.  */
-+unsigned int
-+handle_ld_preload (const char *preloadlist, struct link_map *main_map)
-+{
-+  unsigned int npreloads = 0;
-+  const char *p = preloadlist;
-+  char fname[SECURE_PATH_LIMIT];
-+
-+  while (*p != '\0')
-+    {
-+      /* Split preload list at space/colon.  */
-+      size_t len = strcspn (p, " :");
-+      if (len > 0 && len < sizeof (fname))
-+	{
-+	  memcpy (fname, p, len);
-+	  fname[len] = '\0';
-+	}
-+      else
-+	fname[0] = '\0';
-+
-+      /* Skip over the substring and the following delimiter.  */
-+      p += len;
-+      if (*p != '\0')
-+	++p;
-+
-+      if (dso_name_valid_for_suid (fname))
-+	npreloads += do_preload (fname, main_map, "LD_PRELOAD");
-+    }
-+  return npreloads;
-+}
-+
- static void
- dl_main (const ElfW(Phdr) *phdr,
- 	 ElfW(Word) phnum,
-@@ -1464,23 +1529,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
- 
-   if (__glibc_unlikely (preloadlist != NULL))
-     {
--      /* The LD_PRELOAD environment variable gives list of libraries
--	 separated by white space or colons that are loaded before the
--	 executable's dependencies and prepended to the global scope
--	 list.  If the binary is running setuid all elements
--	 containing a '/' are ignored since it is insecure.  */
--      char *list = strdupa (preloadlist);
--      char *p;
--
-       HP_TIMING_NOW (start);
--
--      /* Prevent optimizing strsep.  Speed is not important here.  */
--      while ((p = (strsep) (&list, " :")) != NULL)
--	if (p[0] != '\0'
--	    && (__builtin_expect (! __libc_enable_secure, 1)
--		|| strchr (p, '/') == NULL))
--	  npreloads += do_preload (p, main_map, "LD_PRELOAD");
--
-+      npreloads += handle_ld_preload (preloadlist, main_map);
-       HP_TIMING_NOW (stop);
-       HP_TIMING_DIFF (diff, start, stop);
-       HP_TIMING_ACCUM_NT (load_time, diff);
--- 
-2.9.3
-
diff --git a/gnu/packages/patches/glibc-CVE-2017-1000366-pt3.patch b/gnu/packages/patches/glibc-CVE-2017-1000366-pt3.patch
deleted file mode 100644
index 3d8f6d2bf8..0000000000
--- a/gnu/packages/patches/glibc-CVE-2017-1000366-pt3.patch
+++ /dev/null
@@ -1,206 +0,0 @@
-From 81b82fb966ffbd94353f793ad17116c6088dedd9 Mon Sep 17 00:00:00 2001
-From: Florian Weimer <fweimer@redhat.com>
-Date: Mon, 19 Jun 2017 22:32:12 +0200
-Subject: [PATCH] ld.so: Reject overly long LD_AUDIT path elements
-
-Also only process the last LD_AUDIT entry.
-
-patch from:
-https://sourceware.org/git/?p=glibc.git;a=commit;h=81b82fb966ffbd94353f793ad17116c6088dedd9
-
----
- ChangeLog  |  11 +++++++
- elf/rtld.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------
- 2 files changed, 106 insertions(+), 15 deletions(-)
-
-diff --git a/elf/rtld.c b/elf/rtld.c
-index 86ae20c..65647fb 100644
---- a/elf/rtld.c
-+++ b/elf/rtld.c
-@@ -129,13 +129,91 @@ dso_name_valid_for_suid (const char *p)
-   return *p != '\0';
- }
- 
--/* List of auditing DSOs.  */
-+/* LD_AUDIT variable contents.  Must be processed before the
-+   audit_list below.  */
-+const char *audit_list_string;
-+
-+/* Cyclic list of auditing DSOs.  audit_list->next is the first
-+   element.  */
- static struct audit_list
- {
-   const char *name;
-   struct audit_list *next;
- } *audit_list;
- 
-+/* Iterator for audit_list_string followed by audit_list.  */
-+struct audit_list_iter
-+{
-+  /* Tail of audit_list_string still needing processing, or NULL.  */
-+  const char *audit_list_tail;
-+
-+  /* The list element returned in the previous iteration.  NULL before
-+     the first element.  */
-+  struct audit_list *previous;
-+
-+  /* Scratch buffer for returning a name which is part of
-+     audit_list_string.  */
-+  char fname[SECURE_NAME_LIMIT];
-+};
-+
-+/* Initialize an audit list iterator.  */
-+static void
-+audit_list_iter_init (struct audit_list_iter *iter)
-+{
-+  iter->audit_list_tail = audit_list_string;
-+  iter->previous = NULL;
-+}
-+
-+/* Iterate through both audit_list_string and audit_list.  */
-+static const char *
-+audit_list_iter_next (struct audit_list_iter *iter)
-+{
-+  if (iter->audit_list_tail != NULL)
-+    {
-+      /* First iterate over audit_list_string.  */
-+      while (*iter->audit_list_tail != '\0')
-+	{
-+	  /* Split audit list at colon.  */
-+	  size_t len = strcspn (iter->audit_list_tail, ":");
-+	  if (len > 0 && len < sizeof (iter->fname))
-+	    {
-+	      memcpy (iter->fname, iter->audit_list_tail, len);
-+	      iter->fname[len] = '\0';
-+	    }
-+	  else
-+	    /* Do not return this name to the caller.  */
-+	    iter->fname[0] = '\0';
-+
-+	  /* Skip over the substring and the following delimiter.  */
-+	  iter->audit_list_tail += len;
-+	  if (*iter->audit_list_tail == ':')
-+	    ++iter->audit_list_tail;
-+
-+	  /* If the name is valid, return it.  */
-+	  if (dso_name_valid_for_suid (iter->fname))
-+	    return iter->fname;
-+	  /* Otherwise, wrap around and try the next name.  */
-+	}
-+      /* Fall through to the procesing of audit_list.  */
-+    }
-+
-+  if (iter->previous == NULL)
-+    {
-+      if (audit_list == NULL)
-+	/* No pre-parsed audit list.  */
-+	return NULL;
-+      /* Start of audit list.  The first list element is at
-+	 audit_list->next (cyclic list).  */
-+      iter->previous = audit_list->next;
-+      return iter->previous->name;
-+    }
-+  if (iter->previous == audit_list)
-+    /* Cyclic list wrap-around.  */
-+    return NULL;
-+  iter->previous = iter->previous->next;
-+  return iter->previous->name;
-+}
-+
- #ifndef HAVE_INLINED_SYSCALLS
- /* Set nonzero during loading and initialization of executable and
-    libraries, cleared before the executable's entry point runs.  This
-@@ -1305,11 +1383,13 @@ of this helper program; chances are you did not intend to run this program.\n\
-     GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
- 
-   /* If we have auditing DSOs to load, do it now.  */
--  if (__glibc_unlikely (audit_list != NULL))
-+  bool need_security_init = true;
-+  if (__glibc_unlikely (audit_list != NULL)
-+      || __glibc_unlikely (audit_list_string != NULL))
-     {
--      /* Iterate over all entries in the list.  The order is important.  */
-       struct audit_ifaces *last_audit = NULL;
--      struct audit_list *al = audit_list->next;
-+      struct audit_list_iter al_iter;
-+      audit_list_iter_init (&al_iter);
- 
-       /* Since we start using the auditing DSOs right away we need to
- 	 initialize the data structures now.  */
-@@ -1320,9 +1400,14 @@ of this helper program; chances are you did not intend to run this program.\n\
- 	 use different values (especially the pointer guard) and will
- 	 fail later on.  */
-       security_init ();
-+      need_security_init = false;
- 
--      do
-+      while (true)
- 	{
-+	  const char *name = audit_list_iter_next (&al_iter);
-+	  if (name == NULL)
-+	    break;
-+
- 	  int tls_idx = GL(dl_tls_max_dtv_idx);
- 
- 	  /* Now it is time to determine the layout of the static TLS
-@@ -1331,7 +1416,7 @@ of this helper program; chances are you did not intend to run this program.\n\
- 	     no DF_STATIC_TLS bit is set.  The reason is that we know
- 	     glibc will use the static model.  */
- 	  struct dlmopen_args dlmargs;
--	  dlmargs.fname = al->name;
-+	  dlmargs.fname = name;
- 	  dlmargs.map = NULL;
- 
- 	  const char *objname;
-@@ -1344,7 +1429,7 @@ of this helper program; chances are you did not intend to run this program.\n\
- 	    not_loaded:
- 	      _dl_error_printf ("\
- ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
--				al->name, err_str);
-+				name, err_str);
- 	      if (malloced)
- 		free ((char *) err_str);
- 	    }
-@@ -1448,10 +1533,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
- 		  goto not_loaded;
- 		}
- 	    }
--
--	  al = al->next;
- 	}
--      while (al != audit_list->next);
- 
-       /* If we have any auditing modules, announce that we already
- 	 have two objects loaded.  */
-@@ -1715,7 +1797,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
-   if (tcbp == NULL)
-     tcbp = init_tls ();
- 
--  if (__glibc_likely (audit_list == NULL))
-+  if (__glibc_likely (need_security_init))
-     /* Initialize security features.  But only if we have not done it
-        earlier.  */
-     security_init ();
-@@ -2346,9 +2428,7 @@ process_dl_audit (char *str)
-   char *p;
- 
-   while ((p = (strsep) (&str, ":")) != NULL)
--    if (p[0] != '\0'
--	&& (__builtin_expect (! __libc_enable_secure, 1)
--	    || strchr (p, '/') == NULL))
-+    if (dso_name_valid_for_suid (p))
-       {
- 	/* This is using the local malloc, not the system malloc.  The
- 	   memory can never be freed.  */
-@@ -2412,7 +2492,7 @@ process_envvars (enum mode *modep)
- 	      break;
- 	    }
- 	  if (memcmp (envline, "AUDIT", 5) == 0)
--	    process_dl_audit (&envline[6]);
-+	    audit_list_string = &envline[6];
- 	  break;
- 
- 	case 7:
--- 
-2.9.3
-
diff --git a/gnu/packages/patches/glibc-o-largefile.patch b/gnu/packages/patches/glibc-o-largefile.patch
deleted file mode 100644
index 2b0ae8c8bb..0000000000
--- a/gnu/packages/patches/glibc-o-largefile.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-This fixes <https://sourceware.org/bugzilla/show_bug.cgi?id=18781>
-whereby, on 32-bit platforms, libc 2.22 would fail to pass O_LARGEFILE
-to 'openat'.  This was caught by 'tests/sparse03.at' in the tar
-test suite.
-
-commit eb32b0d40308166c4d8f6330cc2958cb1e545075
-Author: Andreas Schwab <schwab@suse.de>
-Date:   Mon Aug 10 14:12:47 2015 +0200
-
-    Readd O_LARGEFILE flag for openat64 (bug 18781)
-
---- a/sysdeps/unix/sysv/linux/openat.c
-+++ b/sysdeps/unix/sysv/linux/openat.c
-@@ -68,6 +68,11 @@ __OPENAT (int fd, const char *file, int oflag, ...)
-       va_end (arg);
-     }
- 
-+  /* We have to add the O_LARGEFILE flag for openat64.  */
-+#ifdef MORE_OFLAGS
-+  oflag |= MORE_OFLAGS;
-+#endif
-+
-   return SYSCALL_CANCEL (openat, fd, file, oflag, mode);
- }
- libc_hidden_def (__OPENAT)
diff --git a/gnu/packages/patches/glibc-vectorized-strcspn-guards.patch b/gnu/packages/patches/glibc-vectorized-strcspn-guards.patch
deleted file mode 100644
index 3d6c7749d4..0000000000
--- a/gnu/packages/patches/glibc-vectorized-strcspn-guards.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-Copied from Debian.
-
-2017-06-14  Florian Weimer  <fweimer@redhat.com>
-
-	* sysdeps/i386/i686/multiarch/strcspn-c.c: Add IS_IN (libc) guard.
-	* sysdeps/i386/i686/multiarch/varshift.c: Likewise.
-
---- a/sysdeps/i386/i686/multiarch/strcspn-c.c
-+++ b/sysdeps/i386/i686/multiarch/strcspn-c.c
-@@ -1,2 +1,4 @@
--#define __strcspn_sse2 __strcspn_ia32
--#include <sysdeps/x86_64/multiarch/strcspn-c.c>
-+#if IS_IN (libc)
-+# define __strcspn_sse2 __strcspn_ia32
-+# include <sysdeps/x86_64/multiarch/strcspn-c.c>
-+#endif
---- a/sysdeps/i386/i686/multiarch/varshift.c
-+++ b/sysdeps/i386/i686/multiarch/varshift.c
-@@ -1 +1,3 @@
--#include <sysdeps/x86_64/multiarch/varshift.c>
-+#if IS_IN (libc)
-+# include <sysdeps/x86_64/multiarch/varshift.c>
-+#endif