Your message dated Sat, 17 Sep 2016 13:08:06 +0100
with message-id <1474114086.2011.126.ca...@adam-barratt.org.uk>
and subject line Closing p-u bugs for updates in 8.6
has caused the Debian Bug report #834419,
regarding jessie-pu: package glibc/2.19-18+deb8u6
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact ow...@bugs.debian.org
immediately.)


-- 
834419: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=834419
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: jessie
User: release.debian....@packages.debian.org
Usertags: pu

Dear stable release managers,

I would like to upload a new glibc package for the next jessie release.
Here is the changelog:

 * Update from upstream stable branch:
   - Fix open and openat functions with O_TMPFILE.  Closes: #832521.
   - Drop debian/patches/any/cvs-ld_pointer_guard.diff (merged upstream).
   - Drop debian/patches/any/cvs-mangle-tls_dtor_list.diff (merged upstream).
   - Drop debian/patches/any/cvs-strxfrm-buffer-overflows.diff (merged
     upstream).
 * debian/patches/any/submitted-resolv-ipv6-nameservers.diff: replace by
   patch cvs-resolv-ipv6-nameservers.diff taken from upstream. This fixes
   mtr on systems using only IPv6 nameservers.  Closes: #818281.

The update from the stable branch fixes the O_TMPFILE support in the
open and openat functions. It has been request by the systemd
maintainers. It also brings 3 security fixes we already had using
individual patches (requested by the security team) which have been
backported in the upstream stable branch. Therefore there are dropped
from debian/patches and are added to debian/patches/git-updates.diff.

The last patch fixes an issue introduced by fixing another one in the
way IPv4 and IPv6 nameservers are rotated. It replaces a debian specific
patch by ones taken from upstream.

All these fixes are in testing/unstable for quite some time already. You
will find attached the full debdiff. For an easier review, I have also
attached the diff between the two versions when all the patches are
applied, excluding the debian/ directory.

Thanks,
Aurelien

-- System Information:
Debian Release: stretch/sid
  APT prefers testing
  APT policy: (990, 'testing'), (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.6.0-1-amd64 (SMP w/4 CPU cores)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
diff --git a/debian/changelog b/debian/changelog
index a7ff140..89fe119 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,17 @@
+glibc (2.19-18+deb8u6) UNRELEASED; urgency=medium
+
+  * Update from upstream stable branch:
+    - Fix open and openat functions with O_TMPFILE.  Closes: #832521.
+    - Drop debian/patches/any/cvs-ld_pointer_guard.diff (merged upstream).
+    - Drop debian/patches/any/cvs-mangle-tls_dtor_list.diff (merged upstream).
+    - Drop debian/patches/any/cvs-strxfrm-buffer-overflows.diff (merged
+      upstream).
+  * debian/patches/any/submitted-resolv-ipv6-nameservers.diff: replace by
+    patch cvs-resolv-ipv6-nameservers.diff taken from upstream. This fixes
+    mtr on systems using only IPv6 nameservers.  Closes: #818281.
+
+ -- Aurelien Jarno <aure...@debian.org>  Sat, 13 Aug 2016 17:57:34 +0200
+
 glibc (2.19-18+deb8u5) stable; urgency=medium
 
   [ Aurelien Jarno ]
diff --git a/debian/patches/any/cvs-ld_pointer_guard.diff b/debian/patches/any/cvs-ld_pointer_guard.diff
deleted file mode 100644
index c3d8be4..0000000
--- a/debian/patches/any/cvs-ld_pointer_guard.diff
+++ /dev/null
@@ -1,62 +0,0 @@
-2015-10-15  Florian Weimer  <fwei...@redhat.com>
-
-	[BZ #18928]
-	* sysdeps/generic/ldsodefs.h (struct rtld_global_ro): Remove
-	_dl_pointer_guard member.
-	* elf/rtld.c (_rtld_global_ro): Remove _dl_pointer_guard
-	initializer.
-	(security_init): Always set up pointer guard.
-	(process_envvars): Do not process LD_POINTER_GUARD.
-
---- a/elf/rtld.c
-+++ b/elf/rtld.c
-@@ -162,7 +162,6 @@
-     ._dl_hwcap_mask = HWCAP_IMPORTANT,
-     ._dl_lazy = 1,
-     ._dl_fpu_control = _FPU_DEFAULT,
--    ._dl_pointer_guard = 1,
-     ._dl_pagesize = EXEC_PAGESIZE,
-     ._dl_inhibit_cache = 0,
- 
-@@ -857,15 +856,12 @@
- #endif
- 
-   /* Set up the pointer guard as well, if necessary.  */
--  if (GLRO(dl_pointer_guard))
--    {
--      uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random,
--							     stack_chk_guard);
-+  uintptr_t pointer_chk_guard
-+    = _dl_setup_pointer_guard (_dl_random, stack_chk_guard);
- #ifdef THREAD_SET_POINTER_GUARD
--      THREAD_SET_POINTER_GUARD (pointer_chk_guard);
-+  THREAD_SET_POINTER_GUARD (pointer_chk_guard);
- #endif
--      __pointer_chk_guard_local = pointer_chk_guard;
--    }
-+  __pointer_chk_guard_local = pointer_chk_guard;
- 
-   /* We do not need the _dl_random value anymore.  The less
-      information we leave behind, the better, so clear the
-@@ -2607,9 +2603,6 @@
- 	      GLRO(dl_use_load_bias) = envline[14] == '1' ? -1 : 0;
- 	      break;
- 	    }
--
--	  if (memcmp (envline, "POINTER_GUARD", 13) == 0)
--	    GLRO(dl_pointer_guard) = envline[14] != '0';
- 	  break;
- 
- 	case 14:
---- a/sysdeps/generic/ldsodefs.h
-+++ b/sysdeps/generic/ldsodefs.h
-@@ -591,9 +591,6 @@
-   /* List of auditing interfaces.  */
-   struct audit_ifaces *_dl_audit;
-   unsigned int _dl_naudit;
--
--  /* 0 if internal pointer values should not be guarded, 1 if they should.  */
--  EXTERN int _dl_pointer_guard;
- };
- # define __rtld_global_attribute__
- # ifdef IS_IN_rtld
diff --git a/debian/patches/any/cvs-mangle-tls_dtor_list.diff b/debian/patches/any/cvs-mangle-tls_dtor_list.diff
deleted file mode 100644
index 169e10f..0000000
--- a/debian/patches/any/cvs-mangle-tls_dtor_list.diff
+++ /dev/null
@@ -1,35 +0,0 @@
-2015-10-06  Florian Weimer  <fwei...@redhat.com>
-
-	[BZ #19018]
-	* stdlib/cxa_thread_atexit_impl.c (__cxa_thread_atexit_impl):
-	Mangle function pointer before storing it.
-	(__call_tls_dtors): Demangle function pointer before calling it.
-
---- a/stdlib/cxa_thread_atexit_impl.c
-+++ b/stdlib/cxa_thread_atexit_impl.c
-@@ -42,6 +42,10 @@
- int
- __cxa_thread_atexit_impl (dtor_func func, void *obj, void *dso_symbol)
- {
-+#ifdef PTR_MANGLE
-+  PTR_MANGLE (func);
-+#endif
-+
-   /* Prepend.  */
-   struct dtor_list *new = calloc (1, sizeof (struct dtor_list));
-   new->func = func;
-@@ -83,9 +87,13 @@
-   while (tls_dtor_list)
-     {
-       struct dtor_list *cur = tls_dtor_list;
-+      dtor_func func = cur->func;
-+#ifdef PTR_DEMANGLE
-+      PTR_DEMANGLE (func);
-+#endif
-       tls_dtor_list = tls_dtor_list->next;
- 
--      cur->func (cur->obj);
-+      func (cur->obj);
- 
-       __rtld_lock_lock_recursive (GL(dl_load_lock));
- 
diff --git a/debian/patches/any/cvs-resolv-ipv6-nameservers.diff b/debian/patches/any/cvs-resolv-ipv6-nameservers.diff
new file mode 100644
index 0000000..22ff5d3
--- /dev/null
+++ b/debian/patches/any/cvs-resolv-ipv6-nameservers.diff
@@ -0,0 +1,418 @@
+2015-05-21  Andreas Schwab  <sch...@suse.de>
+
+	[BZ #13028]
+	[BZ #17053]
+	* resolv/res_init.c (__res_vinit): Remove use of ext.nsmap member
+	of struct __res_state.
+	* resolv/res_send.c (__libc_res_nsend): Likewise.
+	(get_nsaddr): New function.
+	(res_ourserver_p, send_vc, reopen): Use it instead of accessing
+	statp directly.
+
+2015-01-06  Aurelien Jarno  <aurel...@aurel32.net>
+
+	[BZ #17806]
+	* resolv/res_init.c (__res_vinit): Improve comments about nserv
+	and nservall.
+
+2015-01-06  Aurelien Jarno  <aurel...@aurel32.net>
+
+	* resolv/res_init.c (__res_iclose): Only clear nsinit if the
+	addresses have been freed.
+
+--- a/resolv/res_init.c
++++ b/resolv/res_init.c
+@@ -153,10 +153,8 @@
+ 	char *cp, **pp;
+ 	int n;
+ 	char buf[BUFSIZ];
+-	int nserv = 0;    /* number of nameserver records read from file */
+-#ifdef _LIBC
+-	int nservall = 0; /* number of NS records read, nserv IPv4 only */
+-#endif
++	int nserv = 0;    /* number of nameservers read from file */
++	int have_serv6 = 0;
+ 	int haveenv = 0;
+ 	int havesearch = 0;
+ #ifdef RESOLVSORT
+@@ -184,15 +182,9 @@
+ 	statp->_flags = 0;
+ 	statp->qhook = NULL;
+ 	statp->rhook = NULL;
+-	statp->_u._ext.nsinit = 0;
+ 	statp->_u._ext.nscount = 0;
+-#ifdef _LIBC
+-	statp->_u._ext.nscount6 = 0;
+-	for (n = 0; n < MAXNS; n++) {
+-		statp->_u._ext.nsaddrs[n] = NULL;
+-		statp->_u._ext.nsmap[n] = MAXNS;
+-	}
+-#endif
++	for (n = 0; n < MAXNS; n++)
++	    statp->_u._ext.nsaddrs[n] = NULL;
+ 
+ 	/* Allow user to override the local domain definition */
+ 	if ((cp = getenv("LOCALDOMAIN")) != NULL) {
+@@ -296,11 +288,7 @@
+ 		    continue;
+ 		}
+ 		/* read nameservers to query */
+-#ifdef _LIBC
+-		if (MATCH(buf, "nameserver") && nservall < MAXNS) {
+-#else
+ 		if (MATCH(buf, "nameserver") && nserv < MAXNS) {
+-#endif
+ 		    struct in_addr a;
+ 
+ 		    cp = buf + sizeof("nameserver") - 1;
+@@ -308,13 +296,12 @@
+ 			cp++;
+ 		    if ((*cp != '\0') && (*cp != '\n')
+ 			&& __inet_aton(cp, &a)) {
+-			statp->nsaddr_list[nservall].sin_addr = a;
+-			statp->nsaddr_list[nservall].sin_family = AF_INET;
+-			statp->nsaddr_list[nservall].sin_port =
++			statp->nsaddr_list[nserv].sin_addr = a;
++			statp->nsaddr_list[nserv].sin_family = AF_INET;
++			statp->nsaddr_list[nserv].sin_port =
+ 				htons(NAMESERVER_PORT);
+ 			nserv++;
+ #ifdef _LIBC
+-			nservall++;
+ 		    } else {
+ 			struct in6_addr a6;
+ 			char *el;
+@@ -356,10 +343,11 @@
+ 				    }
+ 				}
+ 
+-				statp->_u._ext.nsaddrs[nservall] = sa6;
+-				statp->_u._ext.nssocks[nservall] = -1;
+-				statp->_u._ext.nsmap[nservall] = MAXNS + 1;
+-				nservall++;
++				statp->nsaddr_list[nserv].sin_family = 0;
++				statp->_u._ext.nsaddrs[nserv] = sa6;
++				statp->_u._ext.nssocks[nserv] = -1;
++				have_serv6 = 1;
++				nserv++;
+ 			    }
+ 			}
+ #endif
+@@ -414,10 +402,9 @@
+ 		    continue;
+ 		}
+ 	    }
+-	    statp->nscount = nservall;
++	    statp->nscount = nserv;
+ #ifdef _LIBC
+-	    if (nservall - nserv > 0) {
+-		statp->_u._ext.nscount6 = nservall - nserv;
++	    if (have_serv6) {
+ 		/* We try IPv6 servers again.  */
+ 		statp->ipv6_unavail = false;
+ 	    }
+@@ -606,11 +593,7 @@
+ 		statp->_vcsock = -1;
+ 		statp->_flags &= ~(RES_F_VC | RES_F_CONN);
+ 	}
+-#ifdef _LIBC
+-	for (ns = 0; ns < MAXNS; ns++)
+-#else
+ 	for (ns = 0; ns < statp->_u._ext.nscount; ns++)
+-#endif
+ 		if (statp->_u._ext.nsaddrs[ns]) {
+ 			if (statp->_u._ext.nssocks[ns] != -1) {
+ 				close_not_cancel_no_status(statp->_u._ext.nssocks[ns]);
+@@ -621,7 +604,6 @@
+ 				statp->_u._ext.nsaddrs[ns] = NULL;
+ 			}
+ 		}
+-	statp->_u._ext.nsinit = 0;
+ }
+ libc_hidden_def (__res_iclose)
+ 
+--- a/resolv/res_send.c
++++ b/resolv/res_send.c
+@@ -200,6 +200,7 @@
+ 
+ /* Forward. */
+ 
++static struct sockaddr *get_nsaddr (res_state, int);
+ static int		send_vc(res_state, const u_char *, int,
+ 				const u_char *, int,
+ 				u_char **, int *, int *, int, u_char **,
+@@ -237,20 +238,21 @@
+ 	    in_port_t port = in4p->sin_port;
+ 	    in_addr_t addr = in4p->sin_addr.s_addr;
+ 
+-	    for (ns = 0;  ns < MAXNS;  ns++) {
++	    for (ns = 0;  ns < statp->nscount;  ns++) {
+ 		const struct sockaddr_in *srv =
+-		    (struct sockaddr_in *)EXT(statp).nsaddrs[ns];
++		    (struct sockaddr_in *) get_nsaddr (statp, ns);
+ 
+-		if ((srv != NULL) && (srv->sin_family == AF_INET) &&
++		if ((srv->sin_family == AF_INET) &&
+ 		    (srv->sin_port == port) &&
+ 		    (srv->sin_addr.s_addr == INADDR_ANY ||
+ 		     srv->sin_addr.s_addr == addr))
+ 		    return (1);
+ 	    }
+ 	} else if (inp->sin6_family == AF_INET6) {
+-	    for (ns = 0;  ns < MAXNS;  ns++) {
+-		const struct sockaddr_in6 *srv = EXT(statp).nsaddrs[ns];
+-		if ((srv != NULL) && (srv->sin6_family == AF_INET6) &&
++	    for (ns = 0;  ns < statp->nscount;  ns++) {
++		const struct sockaddr_in6 *srv
++		  = (struct sockaddr_in6 *) get_nsaddr (statp, ns);
++		if ((srv->sin6_family == AF_INET6) &&
+ 		    (srv->sin6_port == inp->sin6_port) &&
+ 		    !(memcmp(&srv->sin6_addr, &in6addr_any,
+ 			     sizeof (struct in6_addr)) &&
+@@ -402,74 +404,48 @@
+ 	 * If the ns_addr_list in the resolver context has changed, then
+ 	 * invalidate our cached copy and the associated timing data.
+ 	 */
+-	if (EXT(statp).nsinit) {
++	if (EXT(statp).nscount != 0) {
+ 		int needclose = 0;
+ 
+ 		if (EXT(statp).nscount != statp->nscount)
+ 			needclose++;
+ 		else
+-			for (ns = 0; ns < MAXNS; ns++) {
+-				unsigned int map = EXT(statp).nsmap[ns];
+-				if (map < MAXNS
++			for (ns = 0; ns < statp->nscount; ns++) {
++				if (statp->nsaddr_list[ns].sin_family != 0
+ 				    && !sock_eq((struct sockaddr_in6 *)
+-						&statp->nsaddr_list[map],
++						&statp->nsaddr_list[ns],
+ 						EXT(statp).nsaddrs[ns]))
+ 				{
+ 					needclose++;
+ 					break;
+ 				}
+ 			}
+-		if (needclose)
++		if (needclose) {
+ 			__res_iclose(statp, false);
++			EXT(statp).nscount = 0;
++		}
+ 	}
+ 
+ 	/*
+ 	 * Maybe initialize our private copy of the ns_addr_list.
+ 	 */
+-	if (EXT(statp).nsinit == 0) {
+-		unsigned char map[MAXNS];
+-
+-		memset (map, MAXNS, sizeof (map));
+-		for (n = 0; n < MAXNS; n++) {
+-			ns = EXT(statp).nsmap[n];
+-			if (ns < statp->nscount)
+-				map[ns] = n;
+-			else if (ns < MAXNS) {
+-				free(EXT(statp).nsaddrs[n]);
+-				EXT(statp).nsaddrs[n] = NULL;
+-				EXT(statp).nsmap[n] = MAXNS;
+-			}
+-		}
+-		n = statp->nscount;
+-		if (statp->nscount > EXT(statp).nscount)
+-			for (n = EXT(statp).nscount, ns = 0;
+-			     n < statp->nscount; n++) {
+-				while (ns < MAXNS
+-				       && EXT(statp).nsmap[ns] != MAXNS)
+-					ns++;
+-				if (ns == MAXNS)
+-					break;
+-				EXT(statp).nsmap[ns] = n;
+-				map[n] = ns++;
+-			}
+-		EXT(statp).nscount = n;
+-		for (ns = 0; ns < EXT(statp).nscount; ns++) {
+-			n = map[ns];
+-			if (EXT(statp).nsaddrs[n] == NULL)
+-				EXT(statp).nsaddrs[n] =
++	if (EXT(statp).nscount == 0) {
++		for (ns = 0; ns < statp->nscount; ns++) {
++			EXT(statp).nssocks[ns] = -1;
++			if (statp->nsaddr_list[ns].sin_family == 0)
++				continue;
++			if (EXT(statp).nsaddrs[ns] == NULL)
++				EXT(statp).nsaddrs[ns] =
+ 				    malloc(sizeof (struct sockaddr_in6));
+-			if (EXT(statp).nsaddrs[n] != NULL) {
+-				memset (mempcpy(EXT(statp).nsaddrs[n],
++			if (EXT(statp).nsaddrs[ns] != NULL)
++				memset (mempcpy(EXT(statp).nsaddrs[ns],
+ 						&statp->nsaddr_list[ns],
+ 						sizeof (struct sockaddr_in)),
+ 					'\0',
+ 					sizeof (struct sockaddr_in6)
+ 					- sizeof (struct sockaddr_in));
+-				EXT(statp).nssocks[n] = -1;
+-				n++;
+-			}
+ 		}
+-		EXT(statp).nsinit = 1;
++		EXT(statp).nscount = statp->nscount;
+ 	}
+ 
+ 	/*
+@@ -478,44 +454,37 @@
+ 	 */
+ 	if (__builtin_expect ((statp->options & RES_ROTATE) != 0, 0) &&
+ 	    (statp->options & RES_BLAST) == 0) {
+-		struct sockaddr_in6 *ina;
+-		unsigned int map;
+-
+-		n = 0;
+-		while (n < MAXNS && EXT(statp).nsmap[n] == MAXNS)
+-			n++;
+-		if (n < MAXNS) {
+-			ina = EXT(statp).nsaddrs[n];
+-			map = EXT(statp).nsmap[n];
+-			for (;;) {
+-				ns = n + 1;
+-				while (ns < MAXNS
+-				       && EXT(statp).nsmap[ns] == MAXNS)
+-					ns++;
+-				if (ns == MAXNS)
+-					break;
+-				EXT(statp).nsaddrs[n] = EXT(statp).nsaddrs[ns];
+-				EXT(statp).nsmap[n] = EXT(statp).nsmap[ns];
+-				n = ns;
+-			}
+-			EXT(statp).nsaddrs[n] = ina;
+-			EXT(statp).nsmap[n] = map;
+-		}
++		struct sockaddr_in ina;
++		struct sockaddr_in6 *inp;
++		int lastns = statp->nscount - 1;
++		int fd;
++
++		inp = EXT(statp).nsaddrs[0];
++		ina = statp->nsaddr_list[0];
++		fd = EXT(statp).nssocks[0];
++		for (ns = 0; ns < lastns; ns++) {
++		    EXT(statp).nsaddrs[ns] = EXT(statp).nsaddrs[ns + 1];
++		    statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
++		    EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1];
++		}
++		EXT(statp).nsaddrs[lastns] = inp;
++		statp->nsaddr_list[lastns] = ina;
++		EXT(statp).nssocks[lastns] = fd;
+ 	}
+ 
+ 	/*
+ 	 * Send request, RETRY times, or until successful.
+ 	 */
+ 	for (try = 0; try < statp->retry; try++) {
+-	    for (ns = 0; ns < MAXNS; ns++)
++	    for (ns = 0; ns < statp->nscount; ns++)
+ 	    {
+ #ifdef DEBUG
+ 		char tmpbuf[40];
+ #endif
+-		struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns];
++#if defined USE_HOOKS || defined DEBUG
++		struct sockaddr *nsap = get_nsaddr (statp, ns);
++#endif
+ 
+-		if (nsap == NULL)
+-			goto next_ns;
+ 	    same_ns:
+ #ifdef USE_HOOKS
+ 		if (__builtin_expect (statp->qhook != NULL, 0)) {
+@@ -554,9 +523,9 @@
+ 
+ 		Dprint(statp->options & RES_DEBUG,
+ 		       (stdout, ";; Querying server (# %d) address = %s\n",
+-			ns + 1, inet_ntop(nsap->sin6_family,
+-					  (nsap->sin6_family == AF_INET6
+-					   ? &nsap->sin6_addr
++			ns + 1, inet_ntop(nsap->sa_family,
++					  (nsap->sa_family == AF_INET6
++					   ? &((struct sockaddr_in6 *) nsap)->sin6_addr
+ 					   : &((struct sockaddr_in *) nsap)->sin_addr),
+ 					  tmpbuf, sizeof (tmpbuf))));
+ 
+@@ -672,6 +641,21 @@
+ 
+ /* Private */
+ 
++static struct sockaddr *
++get_nsaddr (res_state statp, int n)
++{
++
++  if (statp->nsaddr_list[n].sin_family == 0 && EXT(statp).nsaddrs[n] != NULL)
++    /* EXT(statp).nsaddrs[n] holds an address that is larger than
++       struct sockaddr, and user code did not update
++       statp->nsaddr_list[n].  */
++    return (struct sockaddr *) EXT(statp).nsaddrs[n];
++  else
++    /* User code updated statp->nsaddr_list[n], or statp->nsaddr_list[n]
++       has the same content as EXT(statp).nsaddrs[n].  */
++    return (struct sockaddr *) (void *) &statp->nsaddr_list[n];
++}
++
+ /* Close the resolver structure, assign zero to *RESPLEN2 if RESPLEN2
+    is not NULL, and return zero.  */
+ static int
+@@ -765,7 +749,7 @@
+ 	const HEADER *hp = (HEADER *) buf;
+ 	const HEADER *hp2 = (HEADER *) buf2;
+ 	HEADER *anhp = (HEADER *) *ansp;
+-	struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns];
++	struct sockaddr *nsap = get_nsaddr (statp, ns);
+ 	int truncating, connreset, resplen, n;
+ 	struct iovec iov[4];
+ 	u_short len;
+@@ -785,8 +769,8 @@
+ 
+ 		if (getpeername(statp->_vcsock,
+ 				(struct sockaddr *)&peer, &size) < 0 ||
+-		    !sock_eq(&peer, nsap)) {
+-		  __res_iclose(statp, false);
++		    !sock_eq(&peer, (struct sockaddr_in6 *) nsap)) {
++			__res_iclose(statp, false);
+ 			statp->_flags &= ~RES_F_VC;
+ 		}
+ 	}
+@@ -795,20 +779,19 @@
+ 		if (statp->_vcsock >= 0)
+ 		  __res_iclose(statp, false);
+ 
+-		statp->_vcsock = socket(nsap->sin6_family, SOCK_STREAM, 0);
++		statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM, 0);
+ 		if (statp->_vcsock < 0) {
+ 			*terrno = errno;
+ 			Perror(statp, stderr, "socket(vc)", errno);
+ 			return (-1);
+ 		}
+ 		__set_errno (0);
+-		if (connect(statp->_vcsock, (struct sockaddr *)nsap,
+-			    nsap->sin6_family == AF_INET
++		if (connect(statp->_vcsock, nsap,
++			    nsap->sa_family == AF_INET
+ 			    ? sizeof (struct sockaddr_in)
+ 			    : sizeof (struct sockaddr_in6)) < 0) {
+ 			*terrno = errno;
+-			Aerror(statp, stderr, "connect/vc", errno,
+-			       (struct sockaddr *) nsap);
++			Aerror(statp, stderr, "connect/vc", errno, nsap);
+ 			__res_iclose(statp, false);
+ 			return (0);
+ 		}
+@@ -1002,8 +985,7 @@
+ reopen (res_state statp, int *terrno, int ns)
+ {
+ 	if (EXT(statp).nssocks[ns] == -1) {
+-		struct sockaddr *nsap
+-		  = (struct sockaddr *) EXT(statp).nsaddrs[ns];
++		struct sockaddr *nsap = get_nsaddr (statp, ns);
+ 		socklen_t slen;
+ 
+ 		/* only try IPv6 if IPv6 NS and if not failed before */
diff --git a/debian/patches/any/cvs-strxfrm-buffer-overflows.diff b/debian/patches/any/cvs-strxfrm-buffer-overflows.diff
deleted file mode 100644
index 3b72407..0000000
--- a/debian/patches/any/cvs-strxfrm-buffer-overflows.diff
+++ /dev/null
@@ -1,670 +0,0 @@
-2015-01-13  Leonhard Holz  <leonhard.h...@web.de>
-
-	[BZ #16009]
-	* string/strxfrm_l.c (STRXFRM): Allocate fixed size cache for
-	weights and rules. Use do_xfrm_cached if data fits in cache,
-	do_xfrm otherwise.  Moved former main loop to...
-	* (do_xfrm_cached): New function.
-	* (do_xfrm): Non-caching version of do_xfrm_cached. Uses
-	find_idx, find_position and stack_push.
-	* (find_idx): New function.
-	* (find_position): Likewise.
-	* localedata/sort-test.sh: Added test run for do_xfrm.
-	* localedata/xfrm-test.c (main): Added command line option
-	-nocache to run the test with strings that are too large for
-	the STRXFRM cache.
-
---- a/localedata/sort-test.sh
-+++ b/localedata/sort-test.sh
-@@ -49,11 +49,17 @@
-    ${common_objpfx}localedata/xfrm-test $id < $cns.in \
-    > ${common_objpfx}localedata/$cns.xout || here=1
-   cmp -s $cns.in ${common_objpfx}localedata/$cns.xout || here=1
-+  LOCPATH=${common_objpfx}localedata GCONV_PATH=${common_objpfx}/iconvdata \
-+   LC_ALL=$l ${run_program_prefix} \
-+   ${common_objpfx}localedata/xfrm-test $id -nocache < $cns.in \
-+   > ${common_objpfx}localedata/$cns.nocache.xout || here=1
-+  cmp -s $cns.in ${common_objpfx}localedata/$cns.nocache.xout || here=1
-   if test $here -eq 0; then
-     echo "$l xfrm-test OK"
-   else
-     echo "$l xfrm-test FAIL"
-     diff -u $cns.in ${common_objpfx}localedata/$cns.xout | sed 's/^/  /'
-+    diff -u $cns.in ${common_objpfx}localedata/$cns.nocache.xout | sed 's/^/  /'
-     status=1
-   fi
- done
---- a/localedata/xfrm-test.c
-+++ b/localedata/xfrm-test.c
-@@ -23,7 +23,10 @@
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-+#include <stdbool.h>
- 
-+/* Keep in sync with string/strxfrm_l.c.  */
-+#define SMALL_STR_SIZE 4095
- 
- struct lines
- {
-@@ -37,6 +40,7 @@
- main (int argc, char *argv[])
- {
-   int result = 0;
-+  bool nocache = false;
-   size_t nstrings, nstrings_max;
-   struct lines *strings;
-   char *line = NULL;
-@@ -44,7 +48,18 @@
-   size_t n;
- 
-   if (argc < 2)
--    error (1, 0, "usage: %s <random seed>", argv[0]);
-+    error (1, 0, "usage: %s <random seed> [-nocache]", argv[0]);
-+
-+  if (argc == 3)
-+    {
-+      if (strcmp (argv[2], "-nocache") == 0)
-+	nocache = true;
-+      else
-+	{
-+	  printf ("Unknown option %s!\n", argv[2]);
-+	  exit (1);
-+	}
-+    }
- 
-   setlocale (LC_ALL, "");
- 
-@@ -59,9 +74,9 @@
- 
-   while (1)
-     {
--      char saved, *newp;
--      int needed;
--      int l;
-+      char saved, *word, *newp;
-+      size_t l, line_len, needed;
-+
-       if (getline (&line, &len, stdin) < 0)
- 	break;
- 
-@@ -83,10 +98,35 @@
- 
-       saved = line[l];
-       line[l] = '\0';
--      needed = strxfrm (NULL, line, 0);
-+
-+      if (nocache)
-+	{
-+	  line_len = strlen (line);
-+	  word = malloc (line_len + SMALL_STR_SIZE + 1);
-+	  if (word == NULL)
-+	    {
-+	      printf ("malloc failed: %m\n");
-+	      exit (1);
-+	    }
-+	  memset (word, ' ', SMALL_STR_SIZE);
-+	  memcpy (word + SMALL_STR_SIZE, line, line_len);
-+	  word[line_len + SMALL_STR_SIZE] = '\0';
-+	}
-+      else
-+        word = line;
-+
-+      needed = strxfrm (NULL, word, 0);
-       newp = malloc (needed + 1);
--      strxfrm (newp, line, needed + 1);
-+      if (newp == NULL)
-+	{
-+	  printf ("malloc failed: %m\n");
-+	  exit (1);
-+	}
-+      strxfrm (newp, word, needed + 1);
-       strings[nstrings].xfrm = newp;
-+
-+      if (nocache)
-+	free (word);
-       line[l] = saved;
-       ++nstrings;
-     }
---- a/string/strxfrm_l.c
-+++ b/string/strxfrm_l.c
-@@ -40,8 +40,23 @@
- #define CONCAT(a,b) CONCAT1(a,b)
- #define CONCAT1(a,b) a##b
- 
-+/* Maximum string size that is calculated with cached indices.  Right now this
-+   is an arbitrary value open to optimizations.  SMALL_STR_SIZE * 4 has to be
-+   lower than __MAX_ALLOCA_CUTOFF.  Keep localedata/xfrm-test.c in sync.  */
-+#define SMALL_STR_SIZE 4095
-+
- #include "../locale/localeinfo.h"
- 
-+/* Group locale data for shorter parameter lists.  */
-+typedef struct
-+{
-+  uint_fast32_t nrules;
-+  unsigned char *rulesets;
-+  USTRING_TYPE *weights;
-+  int32_t *table;
-+  USTRING_TYPE *extra;
-+  int32_t *indirect;
-+} locale_data_t;
- 
- #ifndef WIDE_CHAR_VERSION
- 
-@@ -80,115 +95,328 @@
- }
- #endif
- 
-+/* Find next weight and rule index.  Inlined since called for every char.  */
-+static __always_inline size_t
-+find_idx (const USTRING_TYPE **us, int32_t *weight_idx,
-+	  unsigned char *rule_idx, const locale_data_t *l_data, const int pass)
-+{
-+  const int32_t *table = l_data->table;
-+  const int32_t *indirect = l_data->indirect;
-+  const USTRING_TYPE *extra = l_data->extra;
-+#include WEIGHT_H
-+  int32_t tmp = findidx (us, -1);
-+  *rule_idx = tmp >> 24;
-+  int32_t idx = tmp & 0xffffff;
-+  size_t len = l_data->weights[idx++];
- 
--size_t
--STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
-+  /* Skip over indices of previous levels.  */
-+  for (int i = 0; i < pass; i++)
-+    {
-+      idx += len;
-+      len = l_data->weights[idx++];
-+    }
-+
-+  *weight_idx = idx;
-+  return len;
-+}
-+
-+static int
-+find_position (const USTRING_TYPE *us, const locale_data_t *l_data,
-+	       const int pass)
- {
--  struct __locale_data *current = l->__locales[LC_COLLATE];
--  uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
--  /* We don't assign the following values right away since it might be
--     unnecessary in case there are no rules.  */
--  const unsigned char *rulesets;
--  const int32_t *table;
--  const USTRING_TYPE *weights;
--  const USTRING_TYPE *extra;
--  const int32_t *indirect;
-+  int32_t weight_idx;
-+  unsigned char rule_idx;
-+  const USTRING_TYPE *usrc = us;
-+
-+  find_idx (&usrc, &weight_idx, &rule_idx, l_data, pass);
-+  return l_data->rulesets[rule_idx * l_data->nrules + pass] & sort_position;
-+}
-+
-+/* Do the transformation.  */
-+static size_t
-+do_xfrm (const USTRING_TYPE *usrc, STRING_TYPE *dest, size_t n,
-+	 const locale_data_t *l_data)
-+{
-+  int32_t weight_idx;
-+  unsigned char rule_idx;
-   uint_fast32_t pass;
--  size_t needed;
-+  size_t needed = 0;
-   size_t last_needed;
--  const USTRING_TYPE *usrc;
--  size_t srclen = STRLEN (src);
--  int32_t *idxarr;
--  unsigned char *rulearr;
--  size_t idxmax;
--  size_t idxcnt;
--  int use_malloc;
- 
--#include WEIGHT_H
--
--  if (nrules == 0)
-+  /* Now the passes over the weights.  */
-+  for (pass = 0; pass < l_data->nrules; ++pass)
-     {
--      if (n != 0)
--	STPNCPY (dest, src, MIN (srclen + 1, n));
-+      size_t backw_len = 0;
-+      last_needed = needed;
-+      const USTRING_TYPE *cur = usrc;
-+      const USTRING_TYPE *backw_start = NULL;
- 
--      return srclen;
--    }
-+       /* We assume that if a rule has defined `position' in one section
-+         this is true for all of them.  */
-+      int position = find_position (cur, l_data, pass);
- 
--  rulesets = (const unsigned char *)
--    current->values[_NL_ITEM_INDEX (_NL_COLLATE_RULESETS)].string;
--  table = (const int32_t *)
--    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_TABLE,SUFFIX))].string;
--  weights = (const USTRING_TYPE *)
--    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_WEIGHT,SUFFIX))].string;
--  extra = (const USTRING_TYPE *)
--    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_EXTRA,SUFFIX))].string;
--  indirect = (const int32_t *)
--    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_INDIRECT,SUFFIX))].string;
--  use_malloc = 0;
-+      if (position == 0)
-+	{
-+	  while (*cur != L('\0'))
-+	    {
-+	      const USTRING_TYPE *pos = cur;
-+	      size_t len = find_idx (&cur, &weight_idx, &rule_idx, l_data,
-+				     pass);
-+	      int rule = l_data->rulesets[rule_idx * l_data->nrules + pass];
- 
--  assert (((uintptr_t) table) % __alignof__ (table[0]) == 0);
--  assert (((uintptr_t) weights) % __alignof__ (weights[0]) == 0);
--  assert (((uintptr_t) extra) % __alignof__ (extra[0]) == 0);
--  assert (((uintptr_t) indirect) % __alignof__ (indirect[0]) == 0);
-+	      if ((rule & sort_forward) != 0)
-+		{
-+		  /* Handle the pushed backward sequence.  */
-+		  if (backw_start != NULL)
-+		    {
-+		      for (size_t i = backw_len; i > 0; )
-+			{
-+			  int32_t weight_idx;
-+			  unsigned char rule_idx;
-+			  size_t len = find_idx (&backw_start, &weight_idx,
-+						 &rule_idx, l_data, pass);
-+			  if (needed + i < n)
-+			    for (size_t j = len; j > 0; j--)
-+			      dest[needed + i - j] =
-+				l_data->weights[weight_idx++];
- 
--  /* Handle an empty string as a special case.  */
--  if (srclen == 0)
--    {
--      if (n != 0)
--	*dest = L('\0');
--      return 0;
--    }
-+			  i -= len;
-+			}
- 
--  /* We need the elements of the string as unsigned values since they
--     are used as indeces.  */
--  usrc = (const USTRING_TYPE *) src;
-+		      needed += backw_len;
-+		      backw_start = NULL;
-+		      backw_len = 0;
-+		    }
- 
--  /* Perform the first pass over the string and while doing this find
--     and store the weights for each character.  Since we want this to
--     be as fast as possible we are using `alloca' to store the temporary
--     values.  But since there is no limit on the length of the string
--     we have to use `malloc' if the string is too long.  We should be
--     very conservative here.  */
--  if (! __libc_use_alloca ((srclen + 1) * (sizeof (int32_t) + 1)))
--    {
--      idxarr = (int32_t *) malloc ((srclen + 1) * (sizeof (int32_t) + 1));
--      rulearr = (unsigned char *) &idxarr[srclen];
-+		  /* Now handle the forward element.  */
-+		  if (needed + len < n)
-+		    while (len-- > 0)
-+		      dest[needed++] = l_data->weights[weight_idx++];
-+		  else
-+		    /* No more characters fit into the buffer.  */
-+		    needed += len;
-+		}
-+	      else
-+		{
-+		  /* Remember start of the backward sequence & track length.  */
-+		  if (backw_start == NULL)
-+		    backw_start = pos;
-+		  backw_len += len;
-+		}
-+	    }
- 
--      if (idxarr == NULL)
--	/* No memory.  Well, go with the stack then.
- 
--	   XXX Once this implementation is stable we will handle this
--	   differently.  Instead of precomputing the indeces we will
--	   do this in time.  This means, though, that this happens for
--	   every pass again.  */
--	goto try_stack;
--      use_malloc = 1;
--    }
--  else
--    {
--    try_stack:
--      idxarr = (int32_t *) alloca (srclen * sizeof (int32_t));
--      rulearr = (unsigned char *) alloca (srclen + 1);
-+	  /* Handle the pushed backward sequence.  */
-+	  if (backw_start != NULL)
-+	    {
-+	      for (size_t i = backw_len; i > 0; )
-+		{
-+		  size_t len = find_idx (&backw_start, &weight_idx, &rule_idx,
-+					 l_data, pass);
-+		  if (needed + i < n)
-+		    for (size_t j = len; j > 0; j--)
-+		      dest[needed + i - j] =
-+			l_data->weights[weight_idx++];
-+
-+		  i -= len;
-+		}
-+
-+	      needed += backw_len;
-+	    }
-+	}
-+      else
-+	{
-+	  int val = 1;
-+#ifndef WIDE_CHAR_VERSION
-+	  char buf[7];
-+	  size_t buflen;
-+#endif
-+	  size_t i;
-+
-+	  while (*cur != L('\0'))
-+	    {
-+	      const USTRING_TYPE *pos = cur;
-+	      size_t len = find_idx (&cur, &weight_idx, &rule_idx, l_data,
-+				     pass);
-+	      int rule = l_data->rulesets[rule_idx * l_data->nrules + pass];
-+
-+	      if ((rule & sort_forward) != 0)
-+		{
-+		  /* Handle the pushed backward sequence.  */
-+		  if (backw_start != NULL)
-+		    {
-+		      for (size_t p = backw_len; p > 0; p--)
-+			{
-+			  size_t len;
-+			  int32_t weight_idx;
-+			  unsigned char rule_idx;
-+			  const USTRING_TYPE *backw_cur = backw_start;
-+
-+			  /* To prevent a warning init the used vars.  */
-+			  len = find_idx (&backw_cur, &weight_idx,
-+					  &rule_idx, l_data, pass);
-+
-+			  for (i = 1; i < p; i++)
-+			    len = find_idx (&backw_cur, &weight_idx,
-+					    &rule_idx, l_data, pass);
-+
-+			  if (len != 0)
-+			    {
-+#ifdef WIDE_CHAR_VERSION
-+			      if (needed + 1 + len < n)
-+				{
-+				  dest[needed] = val;
-+				  for (i = 0; i < len; ++i)
-+				    dest[needed + 1 + i] =
-+				      l_data->weights[weight_idx + i];
-+				}
-+			      needed += 1 + len;
-+#else
-+			      buflen = utf8_encode (buf, val);
-+			      if (needed + buflen + len < n)
-+				{
-+				  for (i = 0; i < buflen; ++i)
-+				    dest[needed + i] = buf[i];
-+				  for (i = 0; i < len; ++i)
-+				    dest[needed + buflen + i] =
-+				      l_data->weights[weight_idx + i];
-+				}
-+			      needed += buflen + len;
-+#endif
-+			      val = 1;
-+			    }
-+			  else
-+			    ++val;
-+			}
-+
-+		      backw_start = NULL;
-+		      backw_len = 0;
-+		    }
-+
-+		  /* Now handle the forward element.  */
-+		  if (len != 0)
-+		    {
-+#ifdef WIDE_CHAR_VERSION
-+		      if (needed + 1 + len < n)
-+			{
-+			  dest[needed] = val;
-+			  for (i = 0; i < len; ++i)
-+			    dest[needed + 1 + i] =
-+			      l_data->weights[weight_idx + i];
-+			}
-+		      needed += 1 + len;
-+#else
-+		      buflen = utf8_encode (buf, val);
-+		      if (needed + buflen + len < n)
-+			{
-+			  for (i = 0; i < buflen; ++i)
-+			    dest[needed + i] = buf[i];
-+			  for (i = 0; i < len; ++i)
-+			    dest[needed + buflen + i] =
-+			      l_data->weights[weight_idx + i];
-+			}
-+		      needed += buflen + len;
-+#endif
-+		      val = 1;
-+		    }
-+		  else
-+		    ++val;
-+		}
-+	      else
-+		{
-+		  /* Remember start of the backward sequence & track length.  */
-+		  if (backw_start == NULL)
-+		    backw_start = pos;
-+		  backw_len++;
-+		}
-+	    }
-+
-+	  /* Handle the pushed backward sequence.  */
-+	  if (backw_start != NULL)
-+	    {
-+	      for (size_t p = backw_len; p > 0; p--)
-+		{
-+		  size_t len;
-+		  int32_t weight_idx;
-+		  unsigned char rule_idx;
-+		  const USTRING_TYPE *backw_cur = backw_start;
-+
-+		  /* To prevent a warning init the used vars.  */
-+		  len = find_idx (&backw_cur, &weight_idx,
-+				  &rule_idx, l_data, pass);
-+
-+		  for (i = 1; i < p; i++)
-+		    len = find_idx (&backw_cur, &weight_idx,
-+				    &rule_idx, l_data, pass);
-+
-+		  if (len != 0)
-+		    {
-+#ifdef WIDE_CHAR_VERSION
-+		      if (needed + 1 + len < n)
-+			{
-+			  dest[needed] = val;
-+			  for (i = 0; i < len; ++i)
-+			    dest[needed + 1 + i] =
-+			      l_data->weights[weight_idx + i];
-+			}
-+		      needed += 1 + len;
-+#else
-+		      buflen = utf8_encode (buf, val);
-+		      if (needed + buflen + len < n)
-+			{
-+			  for (i = 0; i < buflen; ++i)
-+			    dest[needed + i] = buf[i];
-+			  for (i = 0; i < len; ++i)
-+			    dest[needed + buflen + i] =
-+			      l_data->weights[weight_idx + i];
-+			}
-+		      needed += buflen + len;
-+#endif
-+		      val = 1;
-+		    }
-+		  else
-+		    ++val;
-+		}
-+	    }
-+	}
-+
-+      /* Finally store the byte to separate the passes or terminate
-+	 the string.  */
-+      if (needed < n)
-+	dest[needed] = pass + 1 < l_data->nrules ? L('\1') : L('\0');
-+      ++needed;
-     }
- 
--  idxmax = 0;
--  do
-+  /* This is a little optimization: many collation specifications have
-+     a `position' rule at the end and if no non-ignored character
-+     is found the last \1 byte is immediately followed by a \0 byte
-+     signalling this.  We can avoid the \1 byte(s).  */
-+  if (needed > 2 && needed == last_needed + 1)
-     {
--      int32_t tmp = findidx (&usrc, -1);
--      rulearr[idxmax] = tmp >> 24;
--      idxarr[idxmax] = tmp & 0xffffff;
--
--      ++idxmax;
-+      /* Remove the \1 byte.  */
-+      if (--needed <= n)
-+	dest[needed - 1] = L('\0');
-     }
--  while (*usrc != L('\0'));
- 
--  /* This element is only read, the value never used but to determine
--     another value which then is ignored.  */
--  rulearr[idxmax] = '\0';
-+  /* Return the number of bytes/words we need, but don't count the NUL
-+     byte/word at the end.  */
-+  return needed - 1;
-+}
-+
-+/* Do the transformation using weight-index and rule cache.  */
-+static size_t
-+do_xfrm_cached (STRING_TYPE *dest, size_t n, const locale_data_t *l_data,
-+		size_t idxmax, int32_t *idxarr, const unsigned char *rulearr)
-+{
-+  uint_fast32_t nrules = l_data->nrules;
-+  unsigned char *rulesets = l_data->rulesets;
-+  USTRING_TYPE *weights = l_data->weights;
-+  uint_fast32_t pass;
-+  size_t needed = 0;
-+  size_t last_needed;
-+  size_t idxcnt;
- 
--  /* Now the passes over the weights.  We now use the indeces we found
--     before.  */
--  needed = 0;
-+  /* Now the passes over the weights.  */
-   for (pass = 0; pass < nrules; ++pass)
-     {
-       size_t backw_stop = ~0ul;
-@@ -434,14 +662,93 @@
- 	dest[needed - 1] = L('\0');
-     }
- 
--  /* Free the memory if needed.  */
--  if (use_malloc)
--    free (idxarr);
--
-   /* Return the number of bytes/words we need, but don't count the NUL
-      byte/word at the end.  */
-   return needed - 1;
- }
-+
-+size_t
-+STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
-+{
-+  locale_data_t l_data;
-+  struct __locale_data *current = l->__locales[LC_COLLATE];
-+  const int32_t *table;
-+  const int32_t *indirect;
-+  const USTRING_TYPE *extra;
-+#include WEIGHT_H
-+  l_data.nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
-+
-+  /* Handle byte comparison case.  */
-+  if (l_data.nrules == 0)
-+    {
-+      size_t srclen = STRLEN (src);
-+
-+      if (n != 0)
-+	STPNCPY (dest, src, MIN (srclen + 1, n));
-+
-+      return srclen;
-+    }
-+
-+  /* Handle an empty string, code hereafter relies on strlen (src) > 0.  */
-+  if (*src == L('\0'))
-+    {
-+      if (n != 0)
-+	*dest = L('\0');
-+      return 0;
-+    }
-+
-+  /* Get the locale data.  */
-+  l_data.rulesets = (unsigned char *)
-+    current->values[_NL_ITEM_INDEX (_NL_COLLATE_RULESETS)].string;
-+  l_data.table = (int32_t *)
-+    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_TABLE,SUFFIX))].string;
-+  l_data.weights = (USTRING_TYPE *)
-+    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_WEIGHT,SUFFIX))].string;
-+  l_data.extra = (USTRING_TYPE *)
-+    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_EXTRA,SUFFIX))].string;
-+  l_data.indirect = (int32_t *)
-+    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_INDIRECT,SUFFIX))].string;
-+  table = l_data.table;
-+  indirect = l_data.indirect;
-+  extra = l_data.extra;
-+
-+  assert (((uintptr_t) l_data.table) % __alignof__ (l_data.table[0]) == 0);
-+  assert (((uintptr_t) l_data.weights) % __alignof__ (l_data.weights[0]) == 0);
-+  assert (((uintptr_t) l_data.extra) % __alignof__ (l_data.extra[0]) == 0);
-+  assert (((uintptr_t) l_data.indirect) % __alignof__ (l_data.indirect[0]) == 0);
-+
-+  /* We need the elements of the string as unsigned values since they
-+     are used as indeces.  */
-+  const USTRING_TYPE *usrc = (const USTRING_TYPE *) src;
-+
-+  /* Allocate cache for small strings on the stack and fill it with weight and
-+     rule indices.  If the cache size is not sufficient, continue with the
-+     uncached xfrm version.  */
-+  size_t idxmax = 0;
-+  const USTRING_TYPE *cur = usrc;
-+  int32_t *idxarr = alloca (SMALL_STR_SIZE * sizeof (int32_t));
-+  unsigned char *rulearr = alloca (SMALL_STR_SIZE + 1);
-+
-+  do
-+    {
-+      int32_t tmp = findidx (&cur, -1);
-+      rulearr[idxmax] = tmp >> 24;
-+      idxarr[idxmax] = tmp & 0xffffff;
-+
-+      ++idxmax;
-+    }
-+  while (*cur != L('\0') && idxmax < SMALL_STR_SIZE);
-+
-+  /* This element is only read, the value never used but to determine
-+     another value which then is ignored.  */
-+  rulearr[idxmax] = '\0';
-+
-+  /* Do the transformation.  */
-+  if (*cur == L('\0'))
-+    return do_xfrm_cached (dest, n, &l_data, idxmax, idxarr, rulearr);
-+  else
-+    return do_xfrm (usrc, dest, n, &l_data);
-+}
- libc_hidden_def (STRXFRM)
- 
- #ifndef WIDE_CHAR_VERSION
diff --git a/debian/patches/any/submitted-resolv-ipv6-nameservers.diff b/debian/patches/any/submitted-resolv-ipv6-nameservers.diff
deleted file mode 100644
index 14a5264..0000000
--- a/debian/patches/any/submitted-resolv-ipv6-nameservers.diff
+++ /dev/null
@@ -1,96 +0,0 @@
-2014-06-13  Aurelien Jarno  <aurel...@aurel32.net>
-
-        [BZ #17053]
-	* resolv/res_init.c (__res_vinit): Improve comments
-	about nserv and nservall.
-	* resolv/res_init.c (__res_vinit): Fill in IPv4 name server
-	information using the nserv index. Only count IPv4 name servers
-	in statp->nscount.
-	* resolv/res_init.c (__res_vinit): Check for both IPv4 and IPv6
-	name servers before adding a localhost name server entry.
-	* resolv/res_send.c (__libc_res_nsend): Check for both IPv4 and
-	IPv6 name servers before ignoring the request.
-	(send_dg): Check for both IPv4 and IPv6 name servers to compute
-	time for the total operation.
-	* resolv/res_init.c (__res_iclose): Only clear nsinit if the
-	addresses have been freed.
-
-diff --git a/resolv/res_init.c b/resolv/res_init.c
-index ea133f8..42e16b6 100644
---- a/resolv/res_init.c
-+++ b/resolv/res_init.c
-@@ -153,9 +153,9 @@ __res_vinit(res_state statp, int preinit) {
- 	char *cp, **pp;
- 	int n;
- 	char buf[BUFSIZ];
--	int nserv = 0;    /* number of nameserver records read from file */
-+	int nserv = 0;    /* number of IPv4 nameservers read from file */
- #ifdef _LIBC
--	int nservall = 0; /* number of NS records read, nserv IPv4 only */
-+	int nservall = 0; /* number of (IPv4 + IPV6) nameservers read from file */
- #endif
- 	int haveenv = 0;
- 	int havesearch = 0;
-@@ -308,9 +308,9 @@ __res_vinit(res_state statp, int preinit) {
- 			cp++;
- 		    if ((*cp != '\0') && (*cp != '\n')
- 			&& __inet_aton(cp, &a)) {
--			statp->nsaddr_list[nservall].sin_addr = a;
--			statp->nsaddr_list[nservall].sin_family = AF_INET;
--			statp->nsaddr_list[nservall].sin_port =
-+			statp->nsaddr_list[nserv].sin_addr = a;
-+			statp->nsaddr_list[nserv].sin_family = AF_INET;
-+			statp->nsaddr_list[nserv].sin_port =
- 				htons(NAMESERVER_PORT);
- 			nserv++;
- #ifdef _LIBC
-@@ -414,7 +414,7 @@ __res_vinit(res_state statp, int preinit) {
- 		    continue;
- 		}
- 	    }
--	    statp->nscount = nservall;
-+	    statp->nscount = nserv;
- #ifdef _LIBC
- 	    if (nservall - nserv > 0) {
- 		statp->_u._ext.nscount6 = nservall - nserv;
-@@ -427,7 +427,7 @@ __res_vinit(res_state statp, int preinit) {
- #endif
- 	    (void) fclose(fp);
- 	}
--	if (__builtin_expect(statp->nscount == 0, 0)) {
-+	if (__builtin_expect(nservall == 0, 0)) {
- 	    statp->nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
- 	    statp->nsaddr.sin_family = AF_INET;
- 	    statp->nsaddr.sin_port = htons(NAMESERVER_PORT);
-@@ -621,7 +621,8 @@ __res_iclose(res_state statp, bool free_addr) {
- 				statp->_u._ext.nsaddrs[ns] = NULL;
- 			}
- 		}
--	statp->_u._ext.nsinit = 0;
-+	if (free_addr)
-+		statp->_u._ext.nsinit = 0;
- }
- libc_hidden_def (__res_iclose)
- 
-diff --git a/resolv/res_send.c b/resolv/res_send.c
-index af42b8a..82242bd 100644
---- a/resolv/res_send.c
-+++ b/resolv/res_send.c
-@@ -347,7 +347,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
- {
-   int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
- 
--	if (statp->nscount == 0) {
-+	if ((statp->nscount + EXT(statp).nscount6) == 0) {
- 		__set_errno (ESRCH);
- 		return (-1);
- 	}
-@@ -1013,7 +1013,7 @@ send_dg(res_state statp,
- 	 */
- 	int seconds = (statp->retrans << ns);
- 	if (ns > 0)
--		seconds /= statp->nscount;
-+		seconds /= (statp->nscount + EXT(statp).nscount6);
- 	if (seconds <= 0)
- 		seconds = 1;
- 	bool single_request_reopen = (statp->options & RES_SNGLKUPREOP) != 0;
diff --git a/debian/patches/git-updates.diff b/debian/patches/git-updates.diff
index d45102a..5e71afb 100644
--- a/debian/patches/git-updates.diff
+++ b/debian/patches/git-updates.diff
@@ -1,10 +1,68 @@
 GIT update of git://sourceware.org/git/glibc.git/release/2.19/master from glibc-2.19
 
 diff --git a/ChangeLog b/ChangeLog
-index 81c393a..fb2d7ff 100644
+index 81c393a..3d2063b 100644
 --- a/ChangeLog
 +++ b/ChangeLog
-@@ -1,3 +1,558 @@
+@@ -1,3 +1,616 @@
++2015-02-24  Eric Rannaud  <e...@nanocritical.com>
++
++	[BZ #17523]
++	* io/fcntl.h (__OPEN_NEEDS_MODE): New macro.
++	* io/bits/fcntl2.h (open): Use it.
++	(openat): Likewise.
++	* io/open.c (__libc_open): Likewise.
++	* io/open64.c (__libc_open64): Likewise.
++	* io/open64_2.c (__open64_2): Likewise.
++	* io/open_2.c (__open_2): Likewise.
++	* io/openat.c (__openat): Likewise.
++	* io/openat64.c (__openat64): Likewise.
++	* io/openat64_2.c (__openat64_2): Likewise.
++	* io/openat_2.c (__openat_2): Likewise.
++	* sysdeps/mach/hurd/open.c (__libc_open): Likewise.
++	* sysdeps/mach/hurd/openat.c (__openat): Likewise.
++	* sysdeps/posix/open64.c (__libc_open64): Likewise.
++	* sysdeps/unix/sysv/linux/dl-openat64.c (openat64): Likewise.
++	* ports/sysdeps/unix/sysv/linux/generic/open.c (__libc_open): Likewise.
++	(__open_nocancel): Likewise.
++	* ports/sysdeps/unix/sysv/linux/generic/open64.c (__libc_open64):
++	Likewise.
++	* sysdeps/unix/sysv/linux/open64.c (__libc_open64): Likewise.
++	* sysdeps/unix/sysv/linux/openat.c (__OPENAT): Likewise.
++
++2016-07-11  Florian Weimer  <fwei...@redhat.com>
++
++	[BZ #19018]
++	* stdlib/cxa_thread_atexit_impl.c (__cxa_thread_atexit_impl):
++	Mangle function pointer before storing it.
++	(__call_tls_dtors): Demangle function pointer before calling it.
++
++2016-07-11  Florian Weimer  <fwei...@redhat.com>
++
++	[BZ #18928]
++	* sysdeps/generic/ldsodefs.h (struct rtld_global_ro): Remove
++	_dl_pointer_guard member.
++	* elf/rtld.c (_rtld_global_ro): Remove _dl_pointer_guard
++	initializer.
++	(security_init): Always set up pointer guard.
++	(process_envvars): Do not process LD_POINTER_GUARD.
++
++2016-07-11  Leonhard Holz  <leonhard.h...@web.de>
++
++	[BZ #16009]
++	* string/strxfrm_l.c (STRXFRM): Allocate fixed size cache for
++	weights and rules. Use do_xfrm_cached if data fits in cache,
++	do_xfrm otherwise.  Moved former main loop to...
++	* (do_xfrm_cached): New function.
++	* (do_xfrm): Non-caching version of do_xfrm_cached. Uses
++	find_idx, find_position and stack_push.
++	* (find_idx): New function.
++	* (find_position): Likewise.
++	* localedata/sort-test.sh: Added test run for do_xfrm.
++	* localedata/xfrm-test.c (main): Added command line option
++	-nocache to run the test with strings that are too large for
++	the STRXFRM cache.
++
 +2016-05-23  Florian Weimer  <fwei...@redhat.com>
 +
 +	CVE-2016-4429
@@ -564,7 +622,7 @@ index 81c393a..fb2d7ff 100644
  
  	[BZ #16529]
 diff --git a/NEWS b/NEWS
-index 98b479e..937c618 100644
+index 98b479e..473e35a 100644
 --- a/NEWS
 +++ b/NEWS
 @@ -5,6 +5,98 @@ See the end for copying conditions.
@@ -575,11 +633,11 @@ index 98b479e..937c618 100644
 +
 +* The following bugs are resolved with this release:
 +
-+  15946, 16545, 16574, 16623, 16657, 16695, 16743, 16758, 16759, 16760,
-+  16878, 16882, 16885, 16916, 16932, 16943, 16958, 17048, 17062, 17069,
-+  17079, 17137, 17153, 17213, 17263, 17269, 17325, 17555, 17905, 18007,
-+  18032, 18080, 18240, 18287, 18508, 18665, 18905, 19779, 19791, 19879,
-+  20010, 20112.
++  15946, 16009, 16545, 16574, 16623, 16657, 16695, 16743, 16758, 16759,
++  16760, 16878, 16882, 16885, 16916, 16932, 16943, 16958, 17048, 17062,
++  17069, 17079, 17137, 17153, 17213, 17263, 17269, 17325, 17523, 17555,
++  17905, 18007, 18032, 18080, 18240, 18287, 18508, 18665, 18905, 18928,
++  19018, 19779, 19791, 19879, 20010, 20112.
 +
 +* A buffer overflow in gethostbyname_r and related functions performing DNS
 +  requests has been fixed.  If the NSS functions were called with a
@@ -900,6 +958,48 @@ index 40e87b2..78815e8 100644
  
  /* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry.  */
  #define PPC64_OPT_TLS		1
+diff --git a/elf/rtld.c b/elf/rtld.c
+index 6dcbabc..375c47d 100644
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -162,7 +162,6 @@ struct rtld_global_ro _rtld_global_ro attribute_relro =
+     ._dl_hwcap_mask = HWCAP_IMPORTANT,
+     ._dl_lazy = 1,
+     ._dl_fpu_control = _FPU_DEFAULT,
+-    ._dl_pointer_guard = 1,
+     ._dl_pagesize = EXEC_PAGESIZE,
+     ._dl_inhibit_cache = 0,
+ 
+@@ -857,15 +856,12 @@ security_init (void)
+ #endif
+ 
+   /* Set up the pointer guard as well, if necessary.  */
+-  if (GLRO(dl_pointer_guard))
+-    {
+-      uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random,
+-							     stack_chk_guard);
++  uintptr_t pointer_chk_guard
++    = _dl_setup_pointer_guard (_dl_random, stack_chk_guard);
+ #ifdef THREAD_SET_POINTER_GUARD
+-      THREAD_SET_POINTER_GUARD (pointer_chk_guard);
++  THREAD_SET_POINTER_GUARD (pointer_chk_guard);
+ #endif
+-      __pointer_chk_guard_local = pointer_chk_guard;
+-    }
++  __pointer_chk_guard_local = pointer_chk_guard;
+ 
+   /* We do not need the _dl_random value anymore.  The less
+      information we leave behind, the better, so clear the
+@@ -2605,9 +2601,6 @@ process_envvars (enum mode *modep)
+ 	      GLRO(dl_use_load_bias) = envline[14] == '1' ? -1 : 0;
+ 	      break;
+ 	    }
+-
+-	  if (memcmp (envline, "POINTER_GUARD", 13) == 0)
+-	    GLRO(dl_pointer_guard) = envline[14] != '0';
+ 	  break;
+ 
+ 	case 14:
 diff --git a/elf/tst-dl-iter-static.c b/elf/tst-dl-iter-static.c
 new file mode 100644
 index 0000000..7303d7c
@@ -1341,6 +1441,271 @@ index 62cdfda..f6d064d 100644
    datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1;
  
    return NSS_STATUS_SUCCESS;
+diff --git a/io/bits/fcntl2.h b/io/bits/fcntl2.h
+index 4f13b10..bb8d233 100644
+--- a/io/bits/fcntl2.h
++++ b/io/bits/fcntl2.h
+@@ -20,7 +20,7 @@
+ # error "Never include <bits/fcntl2.h> directly; use <fcntl.h> instead."
+ #endif
+ 
+-/* Check that calls to open and openat with O_CREAT set have an
++/* Check that calls to open and openat with O_CREAT or O_TMPFILE set have an
+    appropriate third/fourth parameter.  */
+ #ifndef __USE_FILE_OFFSET64
+ extern int __open_2 (const char *__path, int __oflag) __nonnull ((1));
+@@ -35,7 +35,7 @@ extern int __REDIRECT (__open_alias, (const char *__path, int __oflag, ...),
+ __errordecl (__open_too_many_args,
+ 	     "open can be called either with 2 or 3 arguments, not more");
+ __errordecl (__open_missing_mode,
+-	     "open with O_CREAT in second argument needs 3 arguments");
++	     "open with O_CREAT or O_TMPFILE in second argument needs 3 arguments");
+ 
+ __fortify_function int
+ open (const char *__path, int __oflag, ...)
+@@ -45,7 +45,7 @@ open (const char *__path, int __oflag, ...)
+ 
+   if (__builtin_constant_p (__oflag))
+     {
+-      if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1)
++      if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
+ 	{
+ 	  __open_missing_mode ();
+ 	  return __open_2 (__path, __oflag);
+@@ -67,7 +67,7 @@ extern int __REDIRECT (__open64_alias, (const char *__path, int __oflag,
+ __errordecl (__open64_too_many_args,
+ 	     "open64 can be called either with 2 or 3 arguments, not more");
+ __errordecl (__open64_missing_mode,
+-	     "open64 with O_CREAT in second argument needs 3 arguments");
++	     "open64 with O_CREAT or O_TMPFILE in second argument needs 3 arguments");
+ 
+ __fortify_function int
+ open64 (const char *__path, int __oflag, ...)
+@@ -77,7 +77,7 @@ open64 (const char *__path, int __oflag, ...)
+ 
+   if (__builtin_constant_p (__oflag))
+     {
+-      if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1)
++      if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
+ 	{
+ 	  __open64_missing_mode ();
+ 	  return __open64_2 (__path, __oflag);
+@@ -111,7 +111,7 @@ extern int __REDIRECT (__openat_alias, (int __fd, const char *__path,
+ __errordecl (__openat_too_many_args,
+ 	     "openat can be called either with 3 or 4 arguments, not more");
+ __errordecl (__openat_missing_mode,
+-	     "openat with O_CREAT in third argument needs 4 arguments");
++	     "openat with O_CREAT or O_TMPFILE in third argument needs 4 arguments");
+ 
+ __fortify_function int
+ openat (int __fd, const char *__path, int __oflag, ...)
+@@ -121,7 +121,7 @@ openat (int __fd, const char *__path, int __oflag, ...)
+ 
+   if (__builtin_constant_p (__oflag))
+     {
+-      if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1)
++      if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
+ 	{
+ 	  __openat_missing_mode ();
+ 	  return __openat_2 (__fd, __path, __oflag);
+@@ -145,7 +145,7 @@ extern int __REDIRECT (__openat64_alias, (int __fd, const char *__path,
+ __errordecl (__openat64_too_many_args,
+ 	     "openat64 can be called either with 3 or 4 arguments, not more");
+ __errordecl (__openat64_missing_mode,
+-	     "openat64 with O_CREAT in third argument needs 4 arguments");
++	     "openat64 with O_CREAT or O_TMPFILE in third argument needs 4 arguments");
+ 
+ __fortify_function int
+ openat64 (int __fd, const char *__path, int __oflag, ...)
+@@ -155,7 +155,7 @@ openat64 (int __fd, const char *__path, int __oflag, ...)
+ 
+   if (__builtin_constant_p (__oflag))
+     {
+-      if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1)
++      if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
+ 	{
+ 	  __openat64_missing_mode ();
+ 	  return __openat64_2 (__fd, __path, __oflag);
+diff --git a/io/fcntl.h b/io/fcntl.h
+index 28d83ae..16f792e 100644
+--- a/io/fcntl.h
++++ b/io/fcntl.h
+@@ -34,6 +34,15 @@ __BEGIN_DECLS
+    numbers and flag bits for `open', `fcntl', et al.  */
+ #include <bits/fcntl.h>
+ 
++/* Detect if open needs mode as a third argument (or for openat as a fourth
++   argument).  */
++#ifdef __O_TMPFILE
++# define __OPEN_NEEDS_MODE(oflag) \
++  (((oflag) & O_CREAT) != 0 || ((oflag) & __O_TMPFILE) == __O_TMPFILE)
++#else
++# define __OPEN_NEEDS_MODE(oflag) (((oflag) & O_CREAT) != 0)
++#endif
++
+ /* POSIX.1-2001 specifies that these types are defined by <fcntl.h>.
+    Earlier POSIX standards permitted any type ending in `_t' to be defined
+    by any POSIX header, so we don't conditionalize the definitions here.  */
+@@ -160,8 +169,9 @@ typedef __pid_t pid_t;
+ extern int fcntl (int __fd, int __cmd, ...);
+ 
+ /* Open FILE and return a new file descriptor for it, or -1 on error.
+-   OFLAG determines the type of access used.  If O_CREAT is on OFLAG,
+-   the third argument is taken as a `mode_t', the mode of the created file.
++   OFLAG determines the type of access used.  If O_CREAT or O_TMPFILE is set
++   in OFLAG, the third argument is taken as a `mode_t', the mode of the
++   created file.
+ 
+    This function is a cancellation point and therefore not marked with
+    __THROW.  */
+diff --git a/io/open.c b/io/open.c
+index 24aa380..d1df5c3 100644
+--- a/io/open.c
++++ b/io/open.c
+@@ -23,7 +23,7 @@
+ #include <stdio.h>
+ 
+ 
+-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
++/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
+    a third argument is the file protection.  */
+ int
+ __libc_open (file, oflag)
+@@ -38,7 +38,7 @@ __libc_open (file, oflag)
+       return -1;
+     }
+ 
+-  if (oflag & O_CREAT)
++  if (__OPEN_NEEDS_MODE (oflag))
+     {
+       va_list arg;
+       va_start(arg, oflag);
+diff --git a/io/open64.c b/io/open64.c
+index 3f3d2e8..def4e0b 100644
+--- a/io/open64.c
++++ b/io/open64.c
+@@ -21,7 +21,7 @@
+ #include <stddef.h>
+ #include <stdio.h>
+ 
+-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
++/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
+    a third argument is the file protection.  */
+ int
+ __libc_open64 (file, oflag)
+@@ -36,7 +36,7 @@ __libc_open64 (file, oflag)
+       return -1;
+     }
+ 
+-  if (oflag & O_CREAT)
++  if (__OPEN_NEEDS_MODE (oflag))
+     {
+       va_list arg;
+       va_start (arg, oflag);
+diff --git a/io/open64_2.c b/io/open64_2.c
+index 7cafbba..dced8ab 100644
+--- a/io/open64_2.c
++++ b/io/open64_2.c
+@@ -22,8 +22,8 @@
+ int
+ __open64_2 (const char *file, int oflag)
+ {
+-  if (oflag & O_CREAT)
+-    __fortify_fail ("invalid open64 call: O_CREAT without mode");
++  if (__OPEN_NEEDS_MODE (oflag))
++    __fortify_fail ("invalid open64 call: O_CREAT or O_TMPFILE without mode");
+ 
+   return __open64 (file, oflag);
+ }
+diff --git a/io/open_2.c b/io/open_2.c
+index 65d2c1c..d5b3afe 100644
+--- a/io/open_2.c
++++ b/io/open_2.c
+@@ -22,8 +22,8 @@
+ int
+ __open_2 (const char *file, int oflag)
+ {
+-  if (oflag & O_CREAT)
+-    __fortify_fail ("invalid open call: O_CREAT without mode");
++  if (__OPEN_NEEDS_MODE (oflag))
++    __fortify_fail ("invalid open call: O_CREAT or O_TMPFILE without mode");
+ 
+   return __open (file, oflag);
+ }
+diff --git a/io/openat.c b/io/openat.c
+index 2d82270..f3ac8a7 100644
+--- a/io/openat.c
++++ b/io/openat.c
+@@ -30,7 +30,7 @@ int __have_atfcts;
+ #endif
+ 
+ /* Open FILE with access OFLAG.  Interpret relative paths relative to
+-   the directory associated with FD.  If OFLAG includes O_CREAT, a
++   the directory associated with FD.  If O_CREAT or O_TMPFILE is in OFLAG, a
+    third argument is the file protection.  */
+ int
+ __openat (fd, file, oflag)
+@@ -60,7 +60,7 @@ __openat (fd, file, oflag)
+ 	}
+     }
+ 
+-  if (oflag & O_CREAT)
++  if (__OPEN_NEEDS_MODE (oflag))
+     {
+       va_list arg;
+       va_start (arg, oflag);
+diff --git a/io/openat64.c b/io/openat64.c
+index c0c4e19..d104bc1 100644
+--- a/io/openat64.c
++++ b/io/openat64.c
+@@ -23,7 +23,7 @@
+ #include <sys/stat.h>
+ 
+ /* Open FILE with access OFLAG.  Interpret relative paths relative to
+-   the directory associated with FD.  If OFLAG includes O_CREAT, a
++   the directory associated with FD.  If O_CREAT or O_TMPFILE is in OFLAG, a
+    third argument is the file protection.  */
+ int
+ __openat64 (fd, file, oflag)
+@@ -53,7 +53,7 @@ __openat64 (fd, file, oflag)
+ 	}
+     }
+ 
+-  if (oflag & O_CREAT)
++  if (__OPEN_NEEDS_MODE (oflag))
+     {
+       va_list arg;
+       va_start (arg, oflag);
+diff --git a/io/openat64_2.c b/io/openat64_2.c
+index 6cfea6a..9c22a28 100644
+--- a/io/openat64_2.c
++++ b/io/openat64_2.c
+@@ -22,8 +22,8 @@
+ int
+ __openat64_2 (int fd, const char *file, int oflag)
+ {
+-  if (oflag & O_CREAT)
+-    __fortify_fail ("invalid openat64 call: O_CREAT without mode");
++  if (__OPEN_NEEDS_MODE (oflag))
++    __fortify_fail ("invalid openat64 call: O_CREAT or O_TMPFILE without mode");
+ 
+   return __openat64 (fd, file, oflag);
+ }
+diff --git a/io/openat_2.c b/io/openat_2.c
+index 9e38c14..d15d1e9 100644
+--- a/io/openat_2.c
++++ b/io/openat_2.c
+@@ -22,8 +22,8 @@
+ int
+ __openat_2 (int fd, const char *file, int oflag)
+ {
+-  if (oflag & O_CREAT)
+-    __fortify_fail ("invalid openat call: O_CREAT without mode");
++  if (__OPEN_NEEDS_MODE (oflag))
++    __fortify_fail ("invalid openat call: O_CREAT or O_TMPFILE without mode");
+ 
+   return __openat (fd, file, oflag);
+ }
 diff --git a/libio/wstrops.c b/libio/wstrops.c
 index 399a377..9218d4a 100644
 --- a/libio/wstrops.c
@@ -1578,6 +1943,28 @@ index 7d157bf..d179765 100644
  
  $(objdir)/iconvdata/gconv-modules:
  	$(MAKE) -C ../iconvdata subdir=iconvdata $@
+diff --git a/localedata/sort-test.sh b/localedata/sort-test.sh
+index 8a7ca89..b01a78e 100644
+--- a/localedata/sort-test.sh
++++ b/localedata/sort-test.sh
+@@ -49,11 +49,17 @@ for l in $lang; do
+    ${common_objpfx}localedata/xfrm-test $id < $cns.in \
+    > ${common_objpfx}localedata/$cns.xout || here=1
+   cmp -s $cns.in ${common_objpfx}localedata/$cns.xout || here=1
++  LOCPATH=${common_objpfx}localedata GCONV_PATH=${common_objpfx}/iconvdata \
++   LC_ALL=$l ${test_program_prefix} \
++   ${common_objpfx}localedata/xfrm-test $id -nocache < $cns.in \
++   > ${common_objpfx}localedata/$cns.nocache.xout || here=1
++  cmp -s $cns.in ${common_objpfx}localedata/$cns.nocache.xout || here=1
+   if test $here -eq 0; then
+     echo "$l xfrm-test OK"
+   else
+     echo "$l xfrm-test FAIL"
+     diff -u $cns.in ${common_objpfx}localedata/$cns.xout | sed 's/^/  /'
++    diff -u $cns.in ${common_objpfx}localedata/$cns.nocache.xout | sed 's/^/  /'
+     status=1
+   fi
+ done
 diff --git a/localedata/tst-setlocale3.c b/localedata/tst-setlocale3.c
 new file mode 100644
 index 0000000..e3b21a9
@@ -1787,6 +2174,100 @@ index 0000000..e3b21a9
 +
 +#define TEST_FUNCTION do_test ()
 +#include "../test-skeleton.c"
+diff --git a/localedata/xfrm-test.c b/localedata/xfrm-test.c
+index d2aba7d..5cf29f6 100644
+--- a/localedata/xfrm-test.c
++++ b/localedata/xfrm-test.c
+@@ -23,7 +23,10 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <stdbool.h>
+ 
++/* Keep in sync with string/strxfrm_l.c.  */
++#define SMALL_STR_SIZE 4095
+ 
+ struct lines
+ {
+@@ -37,6 +40,7 @@ int
+ main (int argc, char *argv[])
+ {
+   int result = 0;
++  bool nocache = false;
+   size_t nstrings, nstrings_max;
+   struct lines *strings;
+   char *line = NULL;
+@@ -44,7 +48,18 @@ main (int argc, char *argv[])
+   size_t n;
+ 
+   if (argc < 2)
+-    error (1, 0, "usage: %s <random seed>", argv[0]);
++    error (1, 0, "usage: %s <random seed> [-nocache]", argv[0]);
++
++  if (argc == 3)
++    {
++      if (strcmp (argv[2], "-nocache") == 0)
++	nocache = true;
++      else
++	{
++	  printf ("Unknown option %s!\n", argv[2]);
++	  exit (1);
++	}
++    }
+ 
+   setlocale (LC_ALL, "");
+ 
+@@ -59,9 +74,9 @@ main (int argc, char *argv[])
+ 
+   while (1)
+     {
+-      char saved, *newp;
+-      int needed;
+-      int l;
++      char saved, *word, *newp;
++      size_t l, line_len, needed;
++
+       if (getline (&line, &len, stdin) < 0)
+ 	break;
+ 
+@@ -83,10 +98,35 @@ main (int argc, char *argv[])
+ 
+       saved = line[l];
+       line[l] = '\0';
+-      needed = strxfrm (NULL, line, 0);
++
++      if (nocache)
++	{
++	  line_len = strlen (line);
++	  word = malloc (line_len + SMALL_STR_SIZE + 1);
++	  if (word == NULL)
++	    {
++	      printf ("malloc failed: %m\n");
++	      exit (1);
++	    }
++	  memset (word, ' ', SMALL_STR_SIZE);
++	  memcpy (word + SMALL_STR_SIZE, line, line_len);
++	  word[line_len + SMALL_STR_SIZE] = '\0';
++	}
++      else
++        word = line;
++
++      needed = strxfrm (NULL, word, 0);
+       newp = malloc (needed + 1);
+-      strxfrm (newp, line, needed + 1);
++      if (newp == NULL)
++	{
++	  printf ("malloc failed: %m\n");
++	  exit (1);
++	}
++      strxfrm (newp, word, needed + 1);
+       strings[nstrings].xfrm = newp;
++
++      if (nocache)
++	free (word);
+       line[l] = saved;
+       ++nstrings;
+     }
 diff --git a/manual/examples/mkdirent.c b/manual/examples/mkdirent.c
 new file mode 100644
 index 0000000..f8400f4
@@ -2875,6 +3356,57 @@ index f6903b5..fed1dcb 100644
  #   define SINGLE_THREAD_P_PIC(x) SINGLE_THREAD_P
  #  endif
  # endif
+diff --git a/ports/sysdeps/unix/sysv/linux/generic/open.c b/ports/sysdeps/unix/sysv/linux/generic/open.c
+index 4f73fa0..b4c6834 100644
+--- a/ports/sysdeps/unix/sysv/linux/generic/open.c
++++ b/ports/sysdeps/unix/sysv/linux/generic/open.c
+@@ -22,14 +22,14 @@
+ #include <stdio.h>
+ #include <sysdep-cancel.h>
+ 
+-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
++/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
+    a third argument is the file protection.  */
+ int
+ __libc_open (const char *file, int oflag, ...)
+ {
+   int mode = 0;
+ 
+-  if (oflag & O_CREAT)
++  if (__OPEN_NEEDS_MODE (oflag))
+     {
+       va_list arg;
+       va_start (arg, oflag);
+@@ -59,7 +59,7 @@ __open_nocancel (const char *file, int oflag, ...)
+ {
+   int mode = 0;
+ 
+-  if (oflag & O_CREAT)
++  if (__OPEN_NEEDS_MODE (oflag))
+     {
+       va_list arg;
+       va_start (arg, oflag);
+diff --git a/ports/sysdeps/unix/sysv/linux/generic/open64.c b/ports/sysdeps/unix/sysv/linux/generic/open64.c
+index 93d79e3..faea4df 100644
+--- a/ports/sysdeps/unix/sysv/linux/generic/open64.c
++++ b/ports/sysdeps/unix/sysv/linux/generic/open64.c
+@@ -22,14 +22,14 @@
+ #include <stdio.h>
+ #include <sysdep-cancel.h>
+ 
+-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
++/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
+    a third argument is the file protection.  */
+ int
+ __libc_open64 (const char *file, int oflag, ...)
+ {
+   int mode = 0;
+ 
+-  if (oflag & O_CREAT)
++  if (__OPEN_NEEDS_MODE (oflag))
+     {
+       va_list arg;
+       va_start (arg, oflag);
 diff --git a/posix/Makefile b/posix/Makefile
 index 6709900..8f6e6b5 100644
 --- a/posix/Makefile
@@ -4681,6 +5213,37 @@ index 1be16eb..8a34b83 100644
  $(objpfx)tst-tls-atexit.out: $(objpfx)tst-tls-atexit-lib.so
 +
 +$(objpfx)tst-makecontext: $(libdl)
+diff --git a/stdlib/cxa_thread_atexit_impl.c b/stdlib/cxa_thread_atexit_impl.c
+index d2f88d3..6030e5f 100644
+--- a/stdlib/cxa_thread_atexit_impl.c
++++ b/stdlib/cxa_thread_atexit_impl.c
+@@ -42,6 +42,10 @@ static __thread struct link_map *lm_cache;
+ int
+ __cxa_thread_atexit_impl (dtor_func func, void *obj, void *dso_symbol)
+ {
++#ifdef PTR_MANGLE
++  PTR_MANGLE (func);
++#endif
++
+   /* Prepend.  */
+   struct dtor_list *new = calloc (1, sizeof (struct dtor_list));
+   new->func = func;
+@@ -83,9 +87,13 @@ __call_tls_dtors (void)
+   while (tls_dtor_list)
+     {
+       struct dtor_list *cur = tls_dtor_list;
+-      tls_dtor_list = tls_dtor_list->next;
++      dtor_func func = cur->func;
++#ifdef PTR_DEMANGLE
++      PTR_DEMANGLE (func);
++#endif
+ 
+-      cur->func (cur->obj);
++      tls_dtor_list = tls_dtor_list->next;
++      func (cur->obj);
+ 
+       __rtld_lock_lock_recursive (GL(dl_load_lock));
+ 
 diff --git a/stdlib/tst-makecontext.c b/stdlib/tst-makecontext.c
 index 7968a6d..ef1e27a 100644
 --- a/stdlib/tst-makecontext.c
@@ -4985,6 +5548,553 @@ index 0000000..8582cc0
 +
 +#define TEST_FUNCTION do_test ()
 +#include "../test-skeleton.c"
+diff --git a/string/strxfrm_l.c b/string/strxfrm_l.c
+index 04b9338..e496550 100644
+--- a/string/strxfrm_l.c
++++ b/string/strxfrm_l.c
+@@ -40,8 +40,23 @@
+ #define CONCAT(a,b) CONCAT1(a,b)
+ #define CONCAT1(a,b) a##b
+ 
++/* Maximum string size that is calculated with cached indices.  Right now this
++   is an arbitrary value open to optimizations.  SMALL_STR_SIZE * 4 has to be
++   lower than __MAX_ALLOCA_CUTOFF.  Keep localedata/xfrm-test.c in sync.  */
++#define SMALL_STR_SIZE 4095
++
+ #include "../locale/localeinfo.h"
+ 
++/* Group locale data for shorter parameter lists.  */
++typedef struct
++{
++  uint_fast32_t nrules;
++  unsigned char *rulesets;
++  USTRING_TYPE *weights;
++  int32_t *table;
++  USTRING_TYPE *extra;
++  int32_t *indirect;
++} locale_data_t;
+ 
+ #ifndef WIDE_CHAR_VERSION
+ 
+@@ -80,115 +95,330 @@ utf8_encode (char *buf, int val)
+ }
+ #endif
+ 
+-
+-size_t
+-STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
++/* Find next weight and rule index.  Inlined since called for every char.  */
++static __always_inline size_t
++find_idx (const USTRING_TYPE **us, int32_t *weight_idx,
++	  unsigned char *rule_idx, const locale_data_t *l_data, const int pass)
+ {
+-  struct __locale_data *current = l->__locales[LC_COLLATE];
+-  uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
+-  /* We don't assign the following values right away since it might be
+-     unnecessary in case there are no rules.  */
+-  const unsigned char *rulesets;
+-  const int32_t *table;
+-  const USTRING_TYPE *weights;
+-  const USTRING_TYPE *extra;
+-  const int32_t *indirect;
+-  uint_fast32_t pass;
+-  size_t needed;
+-  size_t last_needed;
+-  const USTRING_TYPE *usrc;
+-  size_t srclen = STRLEN (src);
+-  int32_t *idxarr;
+-  unsigned char *rulearr;
+-  size_t idxmax;
+-  size_t idxcnt;
+-  int use_malloc;
++  /* Prepare variables required by findidx().  */
++  int32_t *table = l_data->table;
++  int32_t *indirect = l_data->indirect;
++  USTRING_TYPE *extra = l_data->extra;
+ 
+ #include WEIGHT_H
++  int32_t tmp = findidx (us, -1);
++  *rule_idx = tmp >> 24;
++  int32_t idx = tmp & 0xffffff;
++  size_t len = l_data->weights[idx++];
+ 
+-  if (nrules == 0)
++  /* Skip over indices of previous levels.  */
++  for (int i = 0; i < pass; i++)
+     {
+-      if (n != 0)
+-	STPNCPY (dest, src, MIN (srclen + 1, n));
+-
+-      return srclen;
++      idx += len;
++      len = l_data->weights[idx++];
+     }
+ 
+-  rulesets = (const unsigned char *)
+-    current->values[_NL_ITEM_INDEX (_NL_COLLATE_RULESETS)].string;
+-  table = (const int32_t *)
+-    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_TABLE,SUFFIX))].string;
+-  weights = (const USTRING_TYPE *)
+-    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_WEIGHT,SUFFIX))].string;
+-  extra = (const USTRING_TYPE *)
+-    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_EXTRA,SUFFIX))].string;
+-  indirect = (const int32_t *)
+-    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_INDIRECT,SUFFIX))].string;
+-  use_malloc = 0;
++  *weight_idx = idx;
++  return len;
++}
+ 
+-  assert (((uintptr_t) table) % __alignof__ (table[0]) == 0);
+-  assert (((uintptr_t) weights) % __alignof__ (weights[0]) == 0);
+-  assert (((uintptr_t) extra) % __alignof__ (extra[0]) == 0);
+-  assert (((uintptr_t) indirect) % __alignof__ (indirect[0]) == 0);
++static int
++find_position (const USTRING_TYPE *us, const locale_data_t *l_data,
++	       const int pass)
++{
++  int32_t weight_idx;
++  unsigned char rule_idx;
++  const USTRING_TYPE *usrc = us;
+ 
+-  /* Handle an empty string as a special case.  */
+-  if (srclen == 0)
+-    {
+-      if (n != 0)
+-	*dest = L('\0');
+-      return 0;
+-    }
++  find_idx (&usrc, &weight_idx, &rule_idx, l_data, pass);
++  return l_data->rulesets[rule_idx * l_data->nrules + pass] & sort_position;
++}
+ 
+-  /* We need the elements of the string as unsigned values since they
+-     are used as indeces.  */
+-  usrc = (const USTRING_TYPE *) src;
+-
+-  /* Perform the first pass over the string and while doing this find
+-     and store the weights for each character.  Since we want this to
+-     be as fast as possible we are using `alloca' to store the temporary
+-     values.  But since there is no limit on the length of the string
+-     we have to use `malloc' if the string is too long.  We should be
+-     very conservative here.  */
+-  if (! __libc_use_alloca ((srclen + 1) * (sizeof (int32_t) + 1)))
+-    {
+-      idxarr = (int32_t *) malloc ((srclen + 1) * (sizeof (int32_t) + 1));
+-      rulearr = (unsigned char *) &idxarr[srclen];
+-
+-      if (idxarr == NULL)
+-	/* No memory.  Well, go with the stack then.
+-
+-	   XXX Once this implementation is stable we will handle this
+-	   differently.  Instead of precomputing the indeces we will
+-	   do this in time.  This means, though, that this happens for
+-	   every pass again.  */
+-	goto try_stack;
+-      use_malloc = 1;
+-    }
+-  else
++/* Do the transformation.  */
++static size_t
++do_xfrm (const USTRING_TYPE *usrc, STRING_TYPE *dest, size_t n,
++	 const locale_data_t *l_data)
++{
++  int32_t weight_idx;
++  unsigned char rule_idx;
++  uint_fast32_t pass;
++  size_t needed = 0;
++  size_t last_needed;
++
++  /* Now the passes over the weights.  */
++  for (pass = 0; pass < l_data->nrules; ++pass)
+     {
+-    try_stack:
+-      idxarr = (int32_t *) alloca (srclen * sizeof (int32_t));
+-      rulearr = (unsigned char *) alloca (srclen + 1);
++      size_t backw_len = 0;
++      last_needed = needed;
++      const USTRING_TYPE *cur = usrc;
++      const USTRING_TYPE *backw_start = NULL;
++
++       /* We assume that if a rule has defined `position' in one section
++         this is true for all of them.  */
++      int position = find_position (cur, l_data, pass);
++
++      if (position == 0)
++	{
++	  while (*cur != L('\0'))
++	    {
++	      const USTRING_TYPE *pos = cur;
++	      size_t len = find_idx (&cur, &weight_idx, &rule_idx, l_data,
++				     pass);
++	      int rule = l_data->rulesets[rule_idx * l_data->nrules + pass];
++
++	      if ((rule & sort_forward) != 0)
++		{
++		  /* Handle the pushed backward sequence.  */
++		  if (backw_start != NULL)
++		    {
++		      for (size_t i = backw_len; i > 0; )
++			{
++			  int32_t weight_idx;
++			  unsigned char rule_idx;
++			  size_t len = find_idx (&backw_start, &weight_idx,
++						 &rule_idx, l_data, pass);
++			  if (needed + i < n)
++			    for (size_t j = len; j > 0; j--)
++			      dest[needed + i - j] =
++				l_data->weights[weight_idx++];
++
++			  i -= len;
++			}
++
++		      needed += backw_len;
++		      backw_start = NULL;
++		      backw_len = 0;
++		    }
++
++		  /* Now handle the forward element.  */
++		  if (needed + len < n)
++		    while (len-- > 0)
++		      dest[needed++] = l_data->weights[weight_idx++];
++		  else
++		    /* No more characters fit into the buffer.  */
++		    needed += len;
++		}
++	      else
++		{
++		  /* Remember start of the backward sequence & track length.  */
++		  if (backw_start == NULL)
++		    backw_start = pos;
++		  backw_len += len;
++		}
++	    }
++
++
++	  /* Handle the pushed backward sequence.  */
++	  if (backw_start != NULL)
++	    {
++	      for (size_t i = backw_len; i > 0; )
++		{
++		  size_t len = find_idx (&backw_start, &weight_idx, &rule_idx,
++					 l_data, pass);
++		  if (needed + i < n)
++		    for (size_t j = len; j > 0; j--)
++		      dest[needed + i - j] =
++			l_data->weights[weight_idx++];
++
++		  i -= len;
++		}
++
++	      needed += backw_len;
++	    }
++	}
++      else
++	{
++	  int val = 1;
++#ifndef WIDE_CHAR_VERSION
++	  char buf[7];
++	  size_t buflen;
++#endif
++	  size_t i;
++
++	  while (*cur != L('\0'))
++	    {
++	      const USTRING_TYPE *pos = cur;
++	      size_t len = find_idx (&cur, &weight_idx, &rule_idx, l_data,
++				     pass);
++	      int rule = l_data->rulesets[rule_idx * l_data->nrules + pass];
++
++	      if ((rule & sort_forward) != 0)
++		{
++		  /* Handle the pushed backward sequence.  */
++		  if (backw_start != NULL)
++		    {
++		      for (size_t p = backw_len; p > 0; p--)
++			{
++			  size_t len;
++			  int32_t weight_idx;
++			  unsigned char rule_idx;
++			  const USTRING_TYPE *backw_cur = backw_start;
++
++			  /* To prevent a warning init the used vars.  */
++			  len = find_idx (&backw_cur, &weight_idx,
++					  &rule_idx, l_data, pass);
++
++			  for (i = 1; i < p; i++)
++			    len = find_idx (&backw_cur, &weight_idx,
++					    &rule_idx, l_data, pass);
++
++			  if (len != 0)
++			    {
++#ifdef WIDE_CHAR_VERSION
++			      if (needed + 1 + len < n)
++				{
++				  dest[needed] = val;
++				  for (i = 0; i < len; ++i)
++				    dest[needed + 1 + i] =
++				      l_data->weights[weight_idx + i];
++				}
++			      needed += 1 + len;
++#else
++			      buflen = utf8_encode (buf, val);
++			      if (needed + buflen + len < n)
++				{
++				  for (i = 0; i < buflen; ++i)
++				    dest[needed + i] = buf[i];
++				  for (i = 0; i < len; ++i)
++				    dest[needed + buflen + i] =
++				      l_data->weights[weight_idx + i];
++				}
++			      needed += buflen + len;
++#endif
++			      val = 1;
++			    }
++			  else
++			    ++val;
++			}
++
++		      backw_start = NULL;
++		      backw_len = 0;
++		    }
++
++		  /* Now handle the forward element.  */
++		  if (len != 0)
++		    {
++#ifdef WIDE_CHAR_VERSION
++		      if (needed + 1 + len < n)
++			{
++			  dest[needed] = val;
++			  for (i = 0; i < len; ++i)
++			    dest[needed + 1 + i] =
++			      l_data->weights[weight_idx + i];
++			}
++		      needed += 1 + len;
++#else
++		      buflen = utf8_encode (buf, val);
++		      if (needed + buflen + len < n)
++			{
++			  for (i = 0; i < buflen; ++i)
++			    dest[needed + i] = buf[i];
++			  for (i = 0; i < len; ++i)
++			    dest[needed + buflen + i] =
++			      l_data->weights[weight_idx + i];
++			}
++		      needed += buflen + len;
++#endif
++		      val = 1;
++		    }
++		  else
++		    ++val;
++		}
++	      else
++		{
++		  /* Remember start of the backward sequence & track length.  */
++		  if (backw_start == NULL)
++		    backw_start = pos;
++		  backw_len++;
++		}
++	    }
++
++	  /* Handle the pushed backward sequence.  */
++	  if (backw_start != NULL)
++	    {
++	      for (size_t p = backw_len; p > 0; p--)
++		{
++		  size_t len;
++		  int32_t weight_idx;
++		  unsigned char rule_idx;
++		  const USTRING_TYPE *backw_cur = backw_start;
++
++		  /* To prevent a warning init the used vars.  */
++		  len = find_idx (&backw_cur, &weight_idx,
++				  &rule_idx, l_data, pass);
++
++		  for (i = 1; i < p; i++)
++		    len = find_idx (&backw_cur, &weight_idx,
++				    &rule_idx, l_data, pass);
++
++		  if (len != 0)
++		    {
++#ifdef WIDE_CHAR_VERSION
++		      if (needed + 1 + len < n)
++			{
++			  dest[needed] = val;
++			  for (i = 0; i < len; ++i)
++			    dest[needed + 1 + i] =
++			      l_data->weights[weight_idx + i];
++			}
++		      needed += 1 + len;
++#else
++		      buflen = utf8_encode (buf, val);
++		      if (needed + buflen + len < n)
++			{
++			  for (i = 0; i < buflen; ++i)
++			    dest[needed + i] = buf[i];
++			  for (i = 0; i < len; ++i)
++			    dest[needed + buflen + i] =
++			      l_data->weights[weight_idx + i];
++			}
++		      needed += buflen + len;
++#endif
++		      val = 1;
++		    }
++		  else
++		    ++val;
++		}
++	    }
++	}
++
++      /* Finally store the byte to separate the passes or terminate
++	 the string.  */
++      if (needed < n)
++	dest[needed] = pass + 1 < l_data->nrules ? L('\1') : L('\0');
++      ++needed;
+     }
+ 
+-  idxmax = 0;
+-  do
++  /* This is a little optimization: many collation specifications have
++     a `position' rule at the end and if no non-ignored character
++     is found the last \1 byte is immediately followed by a \0 byte
++     signalling this.  We can avoid the \1 byte(s).  */
++  if (needed > 2 && needed == last_needed + 1)
+     {
+-      int32_t tmp = findidx (&usrc, -1);
+-      rulearr[idxmax] = tmp >> 24;
+-      idxarr[idxmax] = tmp & 0xffffff;
+-
+-      ++idxmax;
++      /* Remove the \1 byte.  */
++      if (--needed <= n)
++	dest[needed - 1] = L('\0');
+     }
+-  while (*usrc != L('\0'));
+ 
+-  /* This element is only read, the value never used but to determine
+-     another value which then is ignored.  */
+-  rulearr[idxmax] = '\0';
++  /* Return the number of bytes/words we need, but don't count the NUL
++     byte/word at the end.  */
++  return needed - 1;
++}
++
++/* Do the transformation using weight-index and rule cache.  */
++static size_t
++do_xfrm_cached (STRING_TYPE *dest, size_t n, const locale_data_t *l_data,
++		size_t idxmax, int32_t *idxarr, const unsigned char *rulearr)
++{
++  uint_fast32_t nrules = l_data->nrules;
++  unsigned char *rulesets = l_data->rulesets;
++  USTRING_TYPE *weights = l_data->weights;
++  uint_fast32_t pass;
++  size_t needed = 0;
++  size_t last_needed;
++  size_t idxcnt;
+ 
+-  /* Now the passes over the weights.  We now use the indeces we found
+-     before.  */
+-  needed = 0;
++  /* Now the passes over the weights.  */
+   for (pass = 0; pass < nrules; ++pass)
+     {
+       size_t backw_stop = ~0ul;
+@@ -434,14 +664,91 @@ STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
+ 	dest[needed - 1] = L('\0');
+     }
+ 
+-  /* Free the memory if needed.  */
+-  if (use_malloc)
+-    free (idxarr);
+-
+   /* Return the number of bytes/words we need, but don't count the NUL
+      byte/word at the end.  */
+   return needed - 1;
+ }
++
++size_t
++STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
++{
++  locale_data_t l_data;
++  struct __locale_data *current = l->__locales[LC_COLLATE];
++  l_data.nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
++
++  /* Handle byte comparison case.  */
++  if (l_data.nrules == 0)
++    {
++      size_t srclen = STRLEN (src);
++
++      if (n != 0)
++	STPNCPY (dest, src, MIN (srclen + 1, n));
++
++      return srclen;
++    }
++
++  /* Handle an empty string, code hereafter relies on strlen (src) > 0.  */
++  if (*src == L('\0'))
++    {
++      if (n != 0)
++	*dest = L('\0');
++      return 0;
++    }
++
++  /* Get the locale data.  */
++  l_data.rulesets = (unsigned char *)
++    current->values[_NL_ITEM_INDEX (_NL_COLLATE_RULESETS)].string;
++  l_data.table = (int32_t *)
++    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_TABLE,SUFFIX))].string;
++  l_data.weights = (USTRING_TYPE *)
++    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_WEIGHT,SUFFIX))].string;
++  l_data.extra = (USTRING_TYPE *)
++    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_EXTRA,SUFFIX))].string;
++  l_data.indirect = (int32_t *)
++    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_INDIRECT,SUFFIX))].string;
++
++  assert (((uintptr_t) l_data.table) % __alignof__ (l_data.table[0]) == 0);
++  assert (((uintptr_t) l_data.weights) % __alignof__ (l_data.weights[0]) == 0);
++  assert (((uintptr_t) l_data.extra) % __alignof__ (l_data.extra[0]) == 0);
++  assert (((uintptr_t) l_data.indirect) % __alignof__ (l_data.indirect[0]) == 0);
++
++  /* We need the elements of the string as unsigned values since they
++     are used as indeces.  */
++  const USTRING_TYPE *usrc = (const USTRING_TYPE *) src;
++
++  /* Allocate cache for small strings on the stack and fill it with weight and
++     rule indices.  If the cache size is not sufficient, continue with the
++     uncached xfrm version.  */
++  size_t idxmax = 0;
++  const USTRING_TYPE *cur = usrc;
++  int32_t *idxarr = alloca (SMALL_STR_SIZE * sizeof (int32_t));
++  unsigned char *rulearr = alloca (SMALL_STR_SIZE + 1);
++  /* Prepare variables required by findidx().  */
++  int32_t *table = l_data.table;
++  int32_t *indirect = l_data.indirect;
++  USTRING_TYPE *extra = l_data.extra;
++#include WEIGHT_H
++
++  do
++    {
++      int32_t tmp = findidx (&cur, -1);
++      rulearr[idxmax] = tmp >> 24;
++      idxarr[idxmax] = tmp & 0xffffff;
++
++      ++idxmax;
++    }
++  while (*cur != L('\0') && idxmax < SMALL_STR_SIZE);
++
++  /* This element is only read, the value never used but to determine
++     another value which then is ignored.  */
++  rulearr[idxmax] = '\0';
++
++  /* Do the transformation.  */
++  if (*cur == L('\0'))
++    return do_xfrm_cached (dest, n, &l_data, idxmax, idxarr, rulearr);
++  else
++    return do_xfrm (usrc, dest, n, &l_data);
++}
+ libc_hidden_def (STRXFRM)
+ 
+ #ifndef WIDE_CHAR_VERSION
 diff --git a/string/test-strcmp.c b/string/test-strcmp.c
 index b395dc7..fcd059f 100644
 --- a/string/test-strcmp.c
@@ -5058,6 +6168,20 @@ index 1b6a20b..81d5637 100644
  	}
  #endif
        do
+diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
+index ffeb093..9d767b6 100644
+--- a/sysdeps/generic/ldsodefs.h
++++ b/sysdeps/generic/ldsodefs.h
+@@ -590,9 +590,6 @@ struct rtld_global_ro
+   /* List of auditing interfaces.  */
+   struct audit_ifaces *_dl_audit;
+   unsigned int _dl_naudit;
+-
+-  /* 0 if internal pointer values should not be guarded, 1 if they should.  */
+-  EXTERN int _dl_pointer_guard;
+ };
+ # define __rtld_global_attribute__
+ # ifdef IS_IN_rtld
 diff --git a/sysdeps/ieee754/dbl-64/s_sin.c b/sysdeps/ieee754/dbl-64/s_sin.c
 index 6105e9f..50109b8 100644
 --- a/sysdeps/ieee754/dbl-64/s_sin.c
@@ -5112,6 +6236,50 @@ index 6105e9f..50109b8 100644
  	      res = do_sin (u, y, db, &cor);
  	      cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
  	      retval = ((res == res + cor) ? ((m) ? res : -res)
+diff --git a/sysdeps/mach/hurd/open.c b/sysdeps/mach/hurd/open.c
+index 7d9b2de..f003d03 100644
+--- a/sysdeps/mach/hurd/open.c
++++ b/sysdeps/mach/hurd/open.c
+@@ -22,7 +22,7 @@
+ #include <hurd.h>
+ #include <hurd/fd.h>
+ 
+-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
++/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
+    a third argument is the file protection.  */
+ int
+ __libc_open (const char *file, int oflag, ...)
+@@ -30,7 +30,7 @@ __libc_open (const char *file, int oflag, ...)
+   mode_t mode;
+   io_t port;
+ 
+-  if (oflag & O_CREAT)
++  if (__OPEN_NEEDS_MODE (oflag))
+     {
+       va_list arg;
+       va_start (arg, oflag);
+diff --git a/sysdeps/mach/hurd/openat.c b/sysdeps/mach/hurd/openat.c
+index 318cb22..83ffe13 100644
+--- a/sysdeps/mach/hurd/openat.c
++++ b/sysdeps/mach/hurd/openat.c
+@@ -26,7 +26,7 @@
+ #include <hurd/fd.h>
+ 
+ /* Open FILE with access OFLAG.  Interpret relative paths relative to
+-   the directory associated with FD.  If OFLAG includes O_CREAT, a
++   the directory associated with FD.  If O_CREAT or O_TMPFILE is in OFLAG, a
+    third argument is the file protection.  */
+ int
+ __openat (fd, file, oflag)
+@@ -37,7 +37,7 @@ __openat (fd, file, oflag)
+   mode_t mode;
+   io_t port;
+ 
+-  if (oflag & O_CREAT)
++  if (__OPEN_NEEDS_MODE (oflag))
+     {
+       va_list arg;
+       va_start (arg, oflag);
 diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
 index 8218237..df6ce8b 100644
 --- a/sysdeps/posix/getaddrinfo.c
@@ -5296,6 +6464,27 @@ index 8218237..df6ce8b 100644
  		      if (*pat == NULL)
  			{
  			  *pat = addrfree++;
+diff --git a/sysdeps/posix/open64.c b/sysdeps/posix/open64.c
+index 64d192a..4b7ec36 100644
+--- a/sysdeps/posix/open64.c
++++ b/sysdeps/posix/open64.c
+@@ -19,14 +19,14 @@
+ #include <stdarg.h>
+ #include <sysdep-cancel.h>
+ 
+-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
++/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
+    a third argument is the file protection.  */
+ int
+ __libc_open64 (const char *file, int oflag, ...)
+ {
+   int mode = 0;
+ 
+-  if (oflag & O_CREAT)
++  if (__OPEN_NEEDS_MODE (oflag))
+     {
+       va_list arg;
+       va_start (arg, oflag);
 diff --git a/sysdeps/powerpc/powerpc64/entry.h b/sysdeps/powerpc/powerpc64/entry.h
 index 76ead1d..30553c1 100644
 --- a/sysdeps/powerpc/powerpc64/entry.h
@@ -6651,6 +7840,19 @@ index 8925396..f32b0fc 100644
  	cmp	rTMP1, rSTRXOR
  	retl
  	 movgu	%xcc, 0, %o0
+diff --git a/sysdeps/unix/sysv/linux/dl-openat64.c b/sysdeps/unix/sysv/linux/dl-openat64.c
+index 9d00b45..5ac16a2 100644
+--- a/sysdeps/unix/sysv/linux/dl-openat64.c
++++ b/sysdeps/unix/sysv/linux/dl-openat64.c
+@@ -28,7 +28,7 @@ openat64 (dfd, file, oflag)
+      const char *file;
+      int oflag;
+ {
+-  assert ((oflag & O_CREAT) == 0);
++  assert (!__OPEN_NEEDS_MODE (oflag));
+ 
+ #ifdef __NR_openat
+   return INLINE_SYSCALL (openat, 3, dfd, file, oflag | O_LARGEFILE);
 diff --git a/sysdeps/unix/sysv/linux/i386/glob64.c b/sysdeps/unix/sysv/linux/i386/glob64.c
 index b4fcd1a..802c957 100644
 --- a/sysdeps/unix/sysv/linux/i386/glob64.c
@@ -6693,6 +7895,51 @@ index b4fcd1a..802c957 100644
  #define glob_in_dir __old_glob_in_dir
  #define GLOB_ATTRIBUTE attribute_compat_text_section
  
+diff --git a/sysdeps/unix/sysv/linux/open64.c b/sysdeps/unix/sysv/linux/open64.c
+index 0d63806..6d91b21 100644
+--- a/sysdeps/unix/sysv/linux/open64.c
++++ b/sysdeps/unix/sysv/linux/open64.c
+@@ -21,14 +21,14 @@
+ #include <stdio.h>
+ #include <sysdep-cancel.h>
+ 
+-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
++/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
+    a third argument is the file protection.  */
+ int
+ __libc_open64 (const char *file, int oflag, ...)
+ {
+   int mode = 0;
+ 
+-  if (oflag & O_CREAT)
++  if (__OPEN_NEEDS_MODE (oflag))
+     {
+       va_list arg;
+       va_start (arg, oflag);
+diff --git a/sysdeps/unix/sysv/linux/openat.c b/sysdeps/unix/sysv/linux/openat.c
+index 9bb8ace..5a75f52 100644
+--- a/sysdeps/unix/sysv/linux/openat.c
++++ b/sysdeps/unix/sysv/linux/openat.c
+@@ -148,8 +148,8 @@ OPENAT_NOT_CANCEL (fd, file, oflag, mode)
+ 
+ 
+ /* Open FILE with access OFLAG.  Interpret relative paths relative to
+-   the directory associated with FD.  If OFLAG includes O_CREAT, a
+-   third argument is the file protection.  */
++   the directory associated with FD.  If OFLAG includes O_CREAT or
++   O_TMPFILE, a fourth argument is the file protection.  */
+ int
+ __OPENAT (fd, file, oflag)
+      int fd;
+@@ -157,7 +157,7 @@ __OPENAT (fd, file, oflag)
+      int oflag;
+ {
+   mode_t mode = 0;
+-  if (oflag & O_CREAT)
++  if (__OPEN_NEEDS_MODE (oflag))
+     {
+       va_list arg;
+       va_start (arg, oflag);
 diff --git a/sysdeps/unix/sysv/linux/s390/Makefile b/sysdeps/unix/sysv/linux/s390/Makefile
 index f91179d..45b1922 100644
 --- a/sysdeps/unix/sysv/linux/s390/Makefile
diff --git a/debian/patches/series b/debian/patches/series
index 0ab9a1c..bbd2497 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -263,7 +263,7 @@ any/local-dynamic-resolvconf.diff
 any/local-libpic.diff
 any/local-bootstrap-headers.diff
 any/submitted-argp-attribute.diff
-any/submitted-resolv-ipv6-nameservers.diff
+any/cvs-resolv-ipv6-nameservers.diff
 any/cvs-check_pf-infinite-loop.diff
 any/local-static-dlopen-search-path.diff
 any/cvs-regex-alloca.diff
@@ -272,7 +272,4 @@ any/cvs-getnetbyname.diff
 any/cvs-vfprintf.diff
 any/cvs-wscanf.diff
 any/cvs-ldconfig-aux-cache.diff
-any/cvs-ld_pointer_guard.diff
-any/cvs-mangle-tls_dtor_list.diff
-any/cvs-strxfrm-buffer-overflows.diff
 any/cvs-grantpt-pty-owner.diff
diff -Nurd glibc_2.19-18+deb8u5/ChangeLog glibc_2.19-18+deb8u6/ChangeLog
--- glibc_2.19-18+deb8u5/ChangeLog	2016-08-15 13:03:06.000000000 +0000
+++ glibc_2.19-18+deb8u6/ChangeLog	2016-08-15 13:03:47.000000000 +0000
@@ -1,3 +1,61 @@
+2015-02-24  Eric Rannaud  <e...@nanocritical.com>
+
+	[BZ #17523]
+	* io/fcntl.h (__OPEN_NEEDS_MODE): New macro.
+	* io/bits/fcntl2.h (open): Use it.
+	(openat): Likewise.
+	* io/open.c (__libc_open): Likewise.
+	* io/open64.c (__libc_open64): Likewise.
+	* io/open64_2.c (__open64_2): Likewise.
+	* io/open_2.c (__open_2): Likewise.
+	* io/openat.c (__openat): Likewise.
+	* io/openat64.c (__openat64): Likewise.
+	* io/openat64_2.c (__openat64_2): Likewise.
+	* io/openat_2.c (__openat_2): Likewise.
+	* sysdeps/mach/hurd/open.c (__libc_open): Likewise.
+	* sysdeps/mach/hurd/openat.c (__openat): Likewise.
+	* sysdeps/posix/open64.c (__libc_open64): Likewise.
+	* sysdeps/unix/sysv/linux/dl-openat64.c (openat64): Likewise.
+	* ports/sysdeps/unix/sysv/linux/generic/open.c (__libc_open): Likewise.
+	(__open_nocancel): Likewise.
+	* ports/sysdeps/unix/sysv/linux/generic/open64.c (__libc_open64):
+	Likewise.
+	* sysdeps/unix/sysv/linux/open64.c (__libc_open64): Likewise.
+	* sysdeps/unix/sysv/linux/openat.c (__OPENAT): Likewise.
+
+2016-07-11  Florian Weimer  <fwei...@redhat.com>
+
+	[BZ #19018]
+	* stdlib/cxa_thread_atexit_impl.c (__cxa_thread_atexit_impl):
+	Mangle function pointer before storing it.
+	(__call_tls_dtors): Demangle function pointer before calling it.
+
+2016-07-11  Florian Weimer  <fwei...@redhat.com>
+
+	[BZ #18928]
+	* sysdeps/generic/ldsodefs.h (struct rtld_global_ro): Remove
+	_dl_pointer_guard member.
+	* elf/rtld.c (_rtld_global_ro): Remove _dl_pointer_guard
+	initializer.
+	(security_init): Always set up pointer guard.
+	(process_envvars): Do not process LD_POINTER_GUARD.
+
+2016-07-11  Leonhard Holz  <leonhard.h...@web.de>
+
+	[BZ #16009]
+	* string/strxfrm_l.c (STRXFRM): Allocate fixed size cache for
+	weights and rules. Use do_xfrm_cached if data fits in cache,
+	do_xfrm otherwise.  Moved former main loop to...
+	* (do_xfrm_cached): New function.
+	* (do_xfrm): Non-caching version of do_xfrm_cached. Uses
+	find_idx, find_position and stack_push.
+	* (find_idx): New function.
+	* (find_position): Likewise.
+	* localedata/sort-test.sh: Added test run for do_xfrm.
+	* localedata/xfrm-test.c (main): Added command line option
+	-nocache to run the test with strings that are too large for
+	the STRXFRM cache.
+
 2016-05-23  Florian Weimer  <fwei...@redhat.com>
 
 	CVE-2016-4429
diff -Nurd glibc_2.19-18+deb8u5/NEWS glibc_2.19-18+deb8u6/NEWS
--- glibc_2.19-18+deb8u5/NEWS	2016-08-15 13:03:06.000000000 +0000
+++ glibc_2.19-18+deb8u6/NEWS	2016-08-15 13:03:47.000000000 +0000
@@ -9,11 +9,11 @@
 
 * The following bugs are resolved with this release:
 
-  15946, 16545, 16574, 16623, 16657, 16695, 16743, 16758, 16759, 16760,
-  16878, 16882, 16885, 16916, 16932, 16943, 16958, 17048, 17062, 17069,
-  17079, 17137, 17153, 17213, 17263, 17269, 17325, 17555, 17905, 18007,
-  18032, 18080, 18240, 18287, 18508, 18665, 18905, 19779, 19791, 19879,
-  20010, 20112.
+  15946, 16009, 16545, 16574, 16623, 16657, 16695, 16743, 16758, 16759,
+  16760, 16878, 16882, 16885, 16916, 16932, 16943, 16958, 17048, 17062,
+  17069, 17079, 17137, 17153, 17213, 17263, 17269, 17325, 17523, 17555,
+  17905, 18007, 18032, 18080, 18240, 18287, 18508, 18665, 18905, 18928,
+  19018, 19779, 19791, 19879, 20010, 20112.
 
 * A buffer overflow in gethostbyname_r and related functions performing DNS
   requests has been fixed.  If the NSS functions were called with a
diff -Nurd glibc_2.19-18+deb8u5/io/bits/fcntl2.h glibc_2.19-18+deb8u6/io/bits/fcntl2.h
--- glibc_2.19-18+deb8u5/io/bits/fcntl2.h	2014-02-07 09:04:38.000000000 +0000
+++ glibc_2.19-18+deb8u6/io/bits/fcntl2.h	2016-08-15 13:03:47.000000000 +0000
@@ -20,7 +20,7 @@
 # error "Never include <bits/fcntl2.h> directly; use <fcntl.h> instead."
 #endif
 
-/* Check that calls to open and openat with O_CREAT set have an
+/* Check that calls to open and openat with O_CREAT or O_TMPFILE set have an
    appropriate third/fourth parameter.  */
 #ifndef __USE_FILE_OFFSET64
 extern int __open_2 (const char *__path, int __oflag) __nonnull ((1));
@@ -35,7 +35,7 @@
 __errordecl (__open_too_many_args,
 	     "open can be called either with 2 or 3 arguments, not more");
 __errordecl (__open_missing_mode,
-	     "open with O_CREAT in second argument needs 3 arguments");
+	     "open with O_CREAT or O_TMPFILE in second argument needs 3 arguments");
 
 __fortify_function int
 open (const char *__path, int __oflag, ...)
@@ -45,7 +45,7 @@
 
   if (__builtin_constant_p (__oflag))
     {
-      if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1)
+      if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
 	{
 	  __open_missing_mode ();
 	  return __open_2 (__path, __oflag);
@@ -67,7 +67,7 @@
 __errordecl (__open64_too_many_args,
 	     "open64 can be called either with 2 or 3 arguments, not more");
 __errordecl (__open64_missing_mode,
-	     "open64 with O_CREAT in second argument needs 3 arguments");
+	     "open64 with O_CREAT or O_TMPFILE in second argument needs 3 arguments");
 
 __fortify_function int
 open64 (const char *__path, int __oflag, ...)
@@ -77,7 +77,7 @@
 
   if (__builtin_constant_p (__oflag))
     {
-      if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1)
+      if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
 	{
 	  __open64_missing_mode ();
 	  return __open64_2 (__path, __oflag);
@@ -111,7 +111,7 @@
 __errordecl (__openat_too_many_args,
 	     "openat can be called either with 3 or 4 arguments, not more");
 __errordecl (__openat_missing_mode,
-	     "openat with O_CREAT in third argument needs 4 arguments");
+	     "openat with O_CREAT or O_TMPFILE in third argument needs 4 arguments");
 
 __fortify_function int
 openat (int __fd, const char *__path, int __oflag, ...)
@@ -121,7 +121,7 @@
 
   if (__builtin_constant_p (__oflag))
     {
-      if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1)
+      if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
 	{
 	  __openat_missing_mode ();
 	  return __openat_2 (__fd, __path, __oflag);
@@ -145,7 +145,7 @@
 __errordecl (__openat64_too_many_args,
 	     "openat64 can be called either with 3 or 4 arguments, not more");
 __errordecl (__openat64_missing_mode,
-	     "openat64 with O_CREAT in third argument needs 4 arguments");
+	     "openat64 with O_CREAT or O_TMPFILE in third argument needs 4 arguments");
 
 __fortify_function int
 openat64 (int __fd, const char *__path, int __oflag, ...)
@@ -155,7 +155,7 @@
 
   if (__builtin_constant_p (__oflag))
     {
-      if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1)
+      if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
 	{
 	  __openat64_missing_mode ();
 	  return __openat64_2 (__fd, __path, __oflag);
diff -Nurd glibc_2.19-18+deb8u5/io/fcntl.h glibc_2.19-18+deb8u6/io/fcntl.h
--- glibc_2.19-18+deb8u5/io/fcntl.h	2016-08-15 13:03:06.000000000 +0000
+++ glibc_2.19-18+deb8u6/io/fcntl.h	2016-08-15 13:03:47.000000000 +0000
@@ -34,6 +34,15 @@
    numbers and flag bits for `open', `fcntl', et al.  */
 #include <bits/fcntl.h>
 
+/* Detect if open needs mode as a third argument (or for openat as a fourth
+   argument).  */
+#ifdef __O_TMPFILE
+# define __OPEN_NEEDS_MODE(oflag) \
+  (((oflag) & O_CREAT) != 0 || ((oflag) & __O_TMPFILE) == __O_TMPFILE)
+#else
+# define __OPEN_NEEDS_MODE(oflag) (((oflag) & O_CREAT) != 0)
+#endif
+
 /* POSIX.1-2001 specifies that these types are defined by <fcntl.h>.
    Earlier POSIX standards permitted any type ending in `_t' to be defined
    by any POSIX header, so we don't conditionalize the definitions here.  */
@@ -137,8 +146,9 @@
 extern int fcntl (int __fd, int __cmd, ...);
 
 /* Open FILE and return a new file descriptor for it, or -1 on error.
-   OFLAG determines the type of access used.  If O_CREAT is on OFLAG,
-   the third argument is taken as a `mode_t', the mode of the created file.
+   OFLAG determines the type of access used.  If O_CREAT or O_TMPFILE is set
+   in OFLAG, the third argument is taken as a `mode_t', the mode of the
+   created file.
 
    This function is a cancellation point and therefore not marked with
    __THROW.  */
diff -Nurd glibc_2.19-18+deb8u5/io/open.c glibc_2.19-18+deb8u6/io/open.c
--- glibc_2.19-18+deb8u5/io/open.c	2014-02-07 09:04:38.000000000 +0000
+++ glibc_2.19-18+deb8u6/io/open.c	2016-08-15 13:03:47.000000000 +0000
@@ -23,7 +23,7 @@
 #include <stdio.h>
 
 
-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
    a third argument is the file protection.  */
 int
 __libc_open (file, oflag)
@@ -38,7 +38,7 @@
       return -1;
     }
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start(arg, oflag);
diff -Nurd glibc_2.19-18+deb8u5/io/open64.c glibc_2.19-18+deb8u6/io/open64.c
--- glibc_2.19-18+deb8u5/io/open64.c	2014-02-07 09:04:38.000000000 +0000
+++ glibc_2.19-18+deb8u6/io/open64.c	2016-08-15 13:03:47.000000000 +0000
@@ -21,7 +21,7 @@
 #include <stddef.h>
 #include <stdio.h>
 
-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
    a third argument is the file protection.  */
 int
 __libc_open64 (file, oflag)
@@ -36,7 +36,7 @@
       return -1;
     }
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff -Nurd glibc_2.19-18+deb8u5/io/open64_2.c glibc_2.19-18+deb8u6/io/open64_2.c
--- glibc_2.19-18+deb8u5/io/open64_2.c	2014-02-07 09:04:38.000000000 +0000
+++ glibc_2.19-18+deb8u6/io/open64_2.c	2016-08-15 13:03:47.000000000 +0000
@@ -22,8 +22,8 @@
 int
 __open64_2 (const char *file, int oflag)
 {
-  if (oflag & O_CREAT)
-    __fortify_fail ("invalid open64 call: O_CREAT without mode");
+  if (__OPEN_NEEDS_MODE (oflag))
+    __fortify_fail ("invalid open64 call: O_CREAT or O_TMPFILE without mode");
 
   return __open64 (file, oflag);
 }
diff -Nurd glibc_2.19-18+deb8u5/io/open_2.c glibc_2.19-18+deb8u6/io/open_2.c
--- glibc_2.19-18+deb8u5/io/open_2.c	2014-02-07 09:04:38.000000000 +0000
+++ glibc_2.19-18+deb8u6/io/open_2.c	2016-08-15 13:03:47.000000000 +0000
@@ -22,8 +22,8 @@
 int
 __open_2 (const char *file, int oflag)
 {
-  if (oflag & O_CREAT)
-    __fortify_fail ("invalid open call: O_CREAT without mode");
+  if (__OPEN_NEEDS_MODE (oflag))
+    __fortify_fail ("invalid open call: O_CREAT or O_TMPFILE without mode");
 
   return __open (file, oflag);
 }
diff -Nurd glibc_2.19-18+deb8u5/io/openat.c glibc_2.19-18+deb8u6/io/openat.c
--- glibc_2.19-18+deb8u5/io/openat.c	2014-02-07 09:04:38.000000000 +0000
+++ glibc_2.19-18+deb8u6/io/openat.c	2016-08-15 13:03:47.000000000 +0000
@@ -30,7 +30,7 @@
 #endif
 
 /* Open FILE with access OFLAG.  Interpret relative paths relative to
-   the directory associated with FD.  If OFLAG includes O_CREAT, a
+   the directory associated with FD.  If O_CREAT or O_TMPFILE is in OFLAG, a
    third argument is the file protection.  */
 int
 __openat (fd, file, oflag)
@@ -60,7 +60,7 @@
 	}
     }
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff -Nurd glibc_2.19-18+deb8u5/io/openat64.c glibc_2.19-18+deb8u6/io/openat64.c
--- glibc_2.19-18+deb8u5/io/openat64.c	2014-02-07 09:04:38.000000000 +0000
+++ glibc_2.19-18+deb8u6/io/openat64.c	2016-08-15 13:03:47.000000000 +0000
@@ -23,7 +23,7 @@
 #include <sys/stat.h>
 
 /* Open FILE with access OFLAG.  Interpret relative paths relative to
-   the directory associated with FD.  If OFLAG includes O_CREAT, a
+   the directory associated with FD.  If O_CREAT or O_TMPFILE is in OFLAG, a
    third argument is the file protection.  */
 int
 __openat64 (fd, file, oflag)
@@ -53,7 +53,7 @@
 	}
     }
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff -Nurd glibc_2.19-18+deb8u5/io/openat64_2.c glibc_2.19-18+deb8u6/io/openat64_2.c
--- glibc_2.19-18+deb8u5/io/openat64_2.c	2014-02-07 09:04:38.000000000 +0000
+++ glibc_2.19-18+deb8u6/io/openat64_2.c	2016-08-15 13:03:47.000000000 +0000
@@ -22,8 +22,8 @@
 int
 __openat64_2 (int fd, const char *file, int oflag)
 {
-  if (oflag & O_CREAT)
-    __fortify_fail ("invalid openat64 call: O_CREAT without mode");
+  if (__OPEN_NEEDS_MODE (oflag))
+    __fortify_fail ("invalid openat64 call: O_CREAT or O_TMPFILE without mode");
 
   return __openat64 (fd, file, oflag);
 }
diff -Nurd glibc_2.19-18+deb8u5/io/openat_2.c glibc_2.19-18+deb8u6/io/openat_2.c
--- glibc_2.19-18+deb8u5/io/openat_2.c	2014-02-07 09:04:38.000000000 +0000
+++ glibc_2.19-18+deb8u6/io/openat_2.c	2016-08-15 13:03:47.000000000 +0000
@@ -22,8 +22,8 @@
 int
 __openat_2 (int fd, const char *file, int oflag)
 {
-  if (oflag & O_CREAT)
-    __fortify_fail ("invalid openat call: O_CREAT without mode");
+  if (__OPEN_NEEDS_MODE (oflag))
+    __fortify_fail ("invalid openat call: O_CREAT or O_TMPFILE without mode");
 
   return __openat (fd, file, oflag);
 }
diff -Nurd glibc_2.19-18+deb8u5/localedata/sort-test.sh glibc_2.19-18+deb8u6/localedata/sort-test.sh
--- glibc_2.19-18+deb8u5/localedata/sort-test.sh	2016-08-15 13:03:06.000000000 +0000
+++ glibc_2.19-18+deb8u6/localedata/sort-test.sh	2016-08-15 13:03:47.000000000 +0000
@@ -50,7 +50,7 @@
    > ${common_objpfx}localedata/$cns.xout || here=1
   cmp -s $cns.in ${common_objpfx}localedata/$cns.xout || here=1
   LOCPATH=${common_objpfx}localedata GCONV_PATH=${common_objpfx}/iconvdata \
-   LC_ALL=$l ${run_program_prefix} \
+   LC_ALL=$l ${test_program_prefix} \
    ${common_objpfx}localedata/xfrm-test $id -nocache < $cns.in \
    > ${common_objpfx}localedata/$cns.nocache.xout || here=1
   cmp -s $cns.in ${common_objpfx}localedata/$cns.nocache.xout || here=1
diff -Nurd glibc_2.19-18+deb8u5/ports/sysdeps/unix/sysv/linux/generic/open.c glibc_2.19-18+deb8u6/ports/sysdeps/unix/sysv/linux/generic/open.c
--- glibc_2.19-18+deb8u5/ports/sysdeps/unix/sysv/linux/generic/open.c	2014-02-07 09:04:38.000000000 +0000
+++ glibc_2.19-18+deb8u6/ports/sysdeps/unix/sysv/linux/generic/open.c	2016-08-15 13:03:47.000000000 +0000
@@ -22,14 +22,14 @@
 #include <stdio.h>
 #include <sysdep-cancel.h>
 
-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
    a third argument is the file protection.  */
 int
 __libc_open (const char *file, int oflag, ...)
 {
   int mode = 0;
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
@@ -59,7 +59,7 @@
 {
   int mode = 0;
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff -Nurd glibc_2.19-18+deb8u5/ports/sysdeps/unix/sysv/linux/generic/open64.c glibc_2.19-18+deb8u6/ports/sysdeps/unix/sysv/linux/generic/open64.c
--- glibc_2.19-18+deb8u5/ports/sysdeps/unix/sysv/linux/generic/open64.c	2014-02-07 09:04:38.000000000 +0000
+++ glibc_2.19-18+deb8u6/ports/sysdeps/unix/sysv/linux/generic/open64.c	2016-08-15 13:03:47.000000000 +0000
@@ -22,14 +22,14 @@
 #include <stdio.h>
 #include <sysdep-cancel.h>
 
-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
    a third argument is the file protection.  */
 int
 __libc_open64 (const char *file, int oflag, ...)
 {
   int mode = 0;
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff -Nurd glibc_2.19-18+deb8u5/resolv/res_init.c glibc_2.19-18+deb8u6/resolv/res_init.c
--- glibc_2.19-18+deb8u5/resolv/res_init.c	2016-08-15 13:03:06.000000000 +0000
+++ glibc_2.19-18+deb8u6/resolv/res_init.c	2016-08-15 13:03:47.000000000 +0000
@@ -153,10 +153,8 @@
 	char *cp, **pp;
 	int n;
 	char buf[BUFSIZ];
-	int nserv = 0;    /* number of IPv4 nameservers read from file */
-#ifdef _LIBC
-	int nservall = 0; /* number of (IPv4 + IPV6) nameservers read from file */
-#endif
+	int nserv = 0;    /* number of nameservers read from file */
+	int have_serv6 = 0;
 	int haveenv = 0;
 	int havesearch = 0;
 #ifdef RESOLVSORT
@@ -184,15 +182,9 @@
 	statp->_flags = 0;
 	statp->qhook = NULL;
 	statp->rhook = NULL;
-	statp->_u._ext.nsinit = 0;
 	statp->_u._ext.nscount = 0;
-#ifdef _LIBC
-	statp->_u._ext.nscount6 = 0;
-	for (n = 0; n < MAXNS; n++) {
-		statp->_u._ext.nsaddrs[n] = NULL;
-		statp->_u._ext.nsmap[n] = MAXNS;
-	}
-#endif
+	for (n = 0; n < MAXNS; n++)
+	    statp->_u._ext.nsaddrs[n] = NULL;
 
 	/* Allow user to override the local domain definition */
 	if ((cp = getenv("LOCALDOMAIN")) != NULL) {
@@ -296,11 +288,7 @@
 		    continue;
 		}
 		/* read nameservers to query */
-#ifdef _LIBC
-		if (MATCH(buf, "nameserver") && nservall < MAXNS) {
-#else
 		if (MATCH(buf, "nameserver") && nserv < MAXNS) {
-#endif
 		    struct in_addr a;
 
 		    cp = buf + sizeof("nameserver") - 1;
@@ -314,7 +302,6 @@
 				htons(NAMESERVER_PORT);
 			nserv++;
 #ifdef _LIBC
-			nservall++;
 		    } else {
 			struct in6_addr a6;
 			char *el;
@@ -356,10 +343,11 @@
 				    }
 				}
 
-				statp->_u._ext.nsaddrs[nservall] = sa6;
-				statp->_u._ext.nssocks[nservall] = -1;
-				statp->_u._ext.nsmap[nservall] = MAXNS + 1;
-				nservall++;
+				statp->nsaddr_list[nserv].sin_family = 0;
+				statp->_u._ext.nsaddrs[nserv] = sa6;
+				statp->_u._ext.nssocks[nserv] = -1;
+				have_serv6 = 1;
+				nserv++;
 			    }
 			}
 #endif
@@ -416,8 +404,7 @@
 	    }
 	    statp->nscount = nserv;
 #ifdef _LIBC
-	    if (nservall - nserv > 0) {
-		statp->_u._ext.nscount6 = nservall - nserv;
+	    if (have_serv6) {
 		/* We try IPv6 servers again.  */
 		statp->ipv6_unavail = false;
 	    }
@@ -427,7 +414,7 @@
 #endif
 	    (void) fclose(fp);
 	}
-	if (__builtin_expect(nservall == 0, 0)) {
+	if (__builtin_expect(statp->nscount == 0, 0)) {
 	    statp->nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
 	    statp->nsaddr.sin_family = AF_INET;
 	    statp->nsaddr.sin_port = htons(NAMESERVER_PORT);
@@ -606,11 +593,7 @@
 		statp->_vcsock = -1;
 		statp->_flags &= ~(RES_F_VC | RES_F_CONN);
 	}
-#ifdef _LIBC
-	for (ns = 0; ns < MAXNS; ns++)
-#else
 	for (ns = 0; ns < statp->_u._ext.nscount; ns++)
-#endif
 		if (statp->_u._ext.nsaddrs[ns]) {
 			if (statp->_u._ext.nssocks[ns] != -1) {
 				close_not_cancel_no_status(statp->_u._ext.nssocks[ns]);
@@ -621,8 +604,6 @@
 				statp->_u._ext.nsaddrs[ns] = NULL;
 			}
 		}
-	if (free_addr)
-		statp->_u._ext.nsinit = 0;
 }
 libc_hidden_def (__res_iclose)
 
diff -Nurd glibc_2.19-18+deb8u5/resolv/res_send.c glibc_2.19-18+deb8u6/resolv/res_send.c
--- glibc_2.19-18+deb8u5/resolv/res_send.c	2016-08-15 13:03:06.000000000 +0000
+++ glibc_2.19-18+deb8u6/resolv/res_send.c	2016-08-15 13:03:47.000000000 +0000
@@ -200,6 +200,7 @@
 
 /* Forward. */
 
+static struct sockaddr *get_nsaddr (res_state, int);
 static int		send_vc(res_state, const u_char *, int,
 				const u_char *, int,
 				u_char **, int *, int *, int, u_char **,
@@ -237,20 +238,21 @@
 	    in_port_t port = in4p->sin_port;
 	    in_addr_t addr = in4p->sin_addr.s_addr;
 
-	    for (ns = 0;  ns < MAXNS;  ns++) {
+	    for (ns = 0;  ns < statp->nscount;  ns++) {
 		const struct sockaddr_in *srv =
-		    (struct sockaddr_in *)EXT(statp).nsaddrs[ns];
+		    (struct sockaddr_in *) get_nsaddr (statp, ns);
 
-		if ((srv != NULL) && (srv->sin_family == AF_INET) &&
+		if ((srv->sin_family == AF_INET) &&
 		    (srv->sin_port == port) &&
 		    (srv->sin_addr.s_addr == INADDR_ANY ||
 		     srv->sin_addr.s_addr == addr))
 		    return (1);
 	    }
 	} else if (inp->sin6_family == AF_INET6) {
-	    for (ns = 0;  ns < MAXNS;  ns++) {
-		const struct sockaddr_in6 *srv = EXT(statp).nsaddrs[ns];
-		if ((srv != NULL) && (srv->sin6_family == AF_INET6) &&
+	    for (ns = 0;  ns < statp->nscount;  ns++) {
+		const struct sockaddr_in6 *srv
+		  = (struct sockaddr_in6 *) get_nsaddr (statp, ns);
+		if ((srv->sin6_family == AF_INET6) &&
 		    (srv->sin6_port == inp->sin6_port) &&
 		    !(memcmp(&srv->sin6_addr, &in6addr_any,
 			     sizeof (struct in6_addr)) &&
@@ -364,7 +366,7 @@
 {
   int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
 
-	if ((statp->nscount + EXT(statp).nscount6) == 0) {
+	if (statp->nscount == 0) {
 		__set_errno (ESRCH);
 		return (-1);
 	}
@@ -402,74 +404,48 @@
 	 * If the ns_addr_list in the resolver context has changed, then
 	 * invalidate our cached copy and the associated timing data.
 	 */
-	if (EXT(statp).nsinit) {
+	if (EXT(statp).nscount != 0) {
 		int needclose = 0;
 
 		if (EXT(statp).nscount != statp->nscount)
 			needclose++;
 		else
-			for (ns = 0; ns < MAXNS; ns++) {
-				unsigned int map = EXT(statp).nsmap[ns];
-				if (map < MAXNS
+			for (ns = 0; ns < statp->nscount; ns++) {
+				if (statp->nsaddr_list[ns].sin_family != 0
 				    && !sock_eq((struct sockaddr_in6 *)
-						&statp->nsaddr_list[map],
+						&statp->nsaddr_list[ns],
 						EXT(statp).nsaddrs[ns]))
 				{
 					needclose++;
 					break;
 				}
 			}
-		if (needclose)
+		if (needclose) {
 			__res_iclose(statp, false);
+			EXT(statp).nscount = 0;
+		}
 	}
 
 	/*
 	 * Maybe initialize our private copy of the ns_addr_list.
 	 */
-	if (EXT(statp).nsinit == 0) {
-		unsigned char map[MAXNS];
-
-		memset (map, MAXNS, sizeof (map));
-		for (n = 0; n < MAXNS; n++) {
-			ns = EXT(statp).nsmap[n];
-			if (ns < statp->nscount)
-				map[ns] = n;
-			else if (ns < MAXNS) {
-				free(EXT(statp).nsaddrs[n]);
-				EXT(statp).nsaddrs[n] = NULL;
-				EXT(statp).nsmap[n] = MAXNS;
-			}
-		}
-		n = statp->nscount;
-		if (statp->nscount > EXT(statp).nscount)
-			for (n = EXT(statp).nscount, ns = 0;
-			     n < statp->nscount; n++) {
-				while (ns < MAXNS
-				       && EXT(statp).nsmap[ns] != MAXNS)
-					ns++;
-				if (ns == MAXNS)
-					break;
-				EXT(statp).nsmap[ns] = n;
-				map[n] = ns++;
-			}
-		EXT(statp).nscount = n;
-		for (ns = 0; ns < EXT(statp).nscount; ns++) {
-			n = map[ns];
-			if (EXT(statp).nsaddrs[n] == NULL)
-				EXT(statp).nsaddrs[n] =
+	if (EXT(statp).nscount == 0) {
+		for (ns = 0; ns < statp->nscount; ns++) {
+			EXT(statp).nssocks[ns] = -1;
+			if (statp->nsaddr_list[ns].sin_family == 0)
+				continue;
+			if (EXT(statp).nsaddrs[ns] == NULL)
+				EXT(statp).nsaddrs[ns] =
 				    malloc(sizeof (struct sockaddr_in6));
-			if (EXT(statp).nsaddrs[n] != NULL) {
-				memset (mempcpy(EXT(statp).nsaddrs[n],
+			if (EXT(statp).nsaddrs[ns] != NULL)
+				memset (mempcpy(EXT(statp).nsaddrs[ns],
 						&statp->nsaddr_list[ns],
 						sizeof (struct sockaddr_in)),
 					'\0',
 					sizeof (struct sockaddr_in6)
 					- sizeof (struct sockaddr_in));
-				EXT(statp).nssocks[n] = -1;
-				n++;
-			}
 		}
-		EXT(statp).nsinit = 1;
+		EXT(statp).nscount = statp->nscount;
 	}
 
 	/*
@@ -478,44 +454,37 @@
 	 */
 	if (__builtin_expect ((statp->options & RES_ROTATE) != 0, 0) &&
 	    (statp->options & RES_BLAST) == 0) {
-		struct sockaddr_in6 *ina;
-		unsigned int map;
+		struct sockaddr_in ina;
+		struct sockaddr_in6 *inp;
+		int lastns = statp->nscount - 1;
+		int fd;
 
-		n = 0;
-		while (n < MAXNS && EXT(statp).nsmap[n] == MAXNS)
-			n++;
-		if (n < MAXNS) {
-			ina = EXT(statp).nsaddrs[n];
-			map = EXT(statp).nsmap[n];
-			for (;;) {
-				ns = n + 1;
-				while (ns < MAXNS
-				       && EXT(statp).nsmap[ns] == MAXNS)
-					ns++;
-				if (ns == MAXNS)
-					break;
-				EXT(statp).nsaddrs[n] = EXT(statp).nsaddrs[ns];
-				EXT(statp).nsmap[n] = EXT(statp).nsmap[ns];
-				n = ns;
-			}
-			EXT(statp).nsaddrs[n] = ina;
-			EXT(statp).nsmap[n] = map;
+		inp = EXT(statp).nsaddrs[0];
+		ina = statp->nsaddr_list[0];
+		fd = EXT(statp).nssocks[0];
+		for (ns = 0; ns < lastns; ns++) {
+		    EXT(statp).nsaddrs[ns] = EXT(statp).nsaddrs[ns + 1];
+		    statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
+		    EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1];
 		}
+		EXT(statp).nsaddrs[lastns] = inp;
+		statp->nsaddr_list[lastns] = ina;
+		EXT(statp).nssocks[lastns] = fd;
 	}
 
 	/*
 	 * Send request, RETRY times, or until successful.
 	 */
 	for (try = 0; try < statp->retry; try++) {
-	    for (ns = 0; ns < MAXNS; ns++)
+	    for (ns = 0; ns < statp->nscount; ns++)
 	    {
 #ifdef DEBUG
 		char tmpbuf[40];
 #endif
-		struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns];
+#if defined USE_HOOKS || defined DEBUG
+		struct sockaddr *nsap = get_nsaddr (statp, ns);
+#endif
 
-		if (nsap == NULL)
-			goto next_ns;
 	    same_ns:
 #ifdef USE_HOOKS
 		if (__builtin_expect (statp->qhook != NULL, 0)) {
@@ -554,9 +523,9 @@
 
 		Dprint(statp->options & RES_DEBUG,
 		       (stdout, ";; Querying server (# %d) address = %s\n",
-			ns + 1, inet_ntop(nsap->sin6_family,
-					  (nsap->sin6_family == AF_INET6
-					   ? &nsap->sin6_addr
+			ns + 1, inet_ntop(nsap->sa_family,
+					  (nsap->sa_family == AF_INET6
+					   ? &((struct sockaddr_in6 *) nsap)->sin6_addr
 					   : &((struct sockaddr_in *) nsap)->sin_addr),
 					  tmpbuf, sizeof (tmpbuf))));
 
@@ -672,6 +641,21 @@
 
 /* Private */
 
+static struct sockaddr *
+get_nsaddr (res_state statp, int n)
+{
+
+  if (statp->nsaddr_list[n].sin_family == 0 && EXT(statp).nsaddrs[n] != NULL)
+    /* EXT(statp).nsaddrs[n] holds an address that is larger than
+       struct sockaddr, and user code did not update
+       statp->nsaddr_list[n].  */
+    return (struct sockaddr *) EXT(statp).nsaddrs[n];
+  else
+    /* User code updated statp->nsaddr_list[n], or statp->nsaddr_list[n]
+       has the same content as EXT(statp).nsaddrs[n].  */
+    return (struct sockaddr *) (void *) &statp->nsaddr_list[n];
+}
+
 /* Close the resolver structure, assign zero to *RESPLEN2 if RESPLEN2
    is not NULL, and return zero.  */
 static int
@@ -765,7 +749,7 @@
 	const HEADER *hp = (HEADER *) buf;
 	const HEADER *hp2 = (HEADER *) buf2;
 	HEADER *anhp = (HEADER *) *ansp;
-	struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns];
+	struct sockaddr *nsap = get_nsaddr (statp, ns);
 	int truncating, connreset, resplen, n;
 	struct iovec iov[4];
 	u_short len;
@@ -785,8 +769,8 @@
 
 		if (getpeername(statp->_vcsock,
 				(struct sockaddr *)&peer, &size) < 0 ||
-		    !sock_eq(&peer, nsap)) {
-		  __res_iclose(statp, false);
+		    !sock_eq(&peer, (struct sockaddr_in6 *) nsap)) {
+			__res_iclose(statp, false);
 			statp->_flags &= ~RES_F_VC;
 		}
 	}
@@ -795,20 +779,19 @@
 		if (statp->_vcsock >= 0)
 		  __res_iclose(statp, false);
 
-		statp->_vcsock = socket(nsap->sin6_family, SOCK_STREAM, 0);
+		statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM, 0);
 		if (statp->_vcsock < 0) {
 			*terrno = errno;
 			Perror(statp, stderr, "socket(vc)", errno);
 			return (-1);
 		}
 		__set_errno (0);
-		if (connect(statp->_vcsock, (struct sockaddr *)nsap,
-			    nsap->sin6_family == AF_INET
+		if (connect(statp->_vcsock, nsap,
+			    nsap->sa_family == AF_INET
 			    ? sizeof (struct sockaddr_in)
 			    : sizeof (struct sockaddr_in6)) < 0) {
 			*terrno = errno;
-			Aerror(statp, stderr, "connect/vc", errno,
-			       (struct sockaddr *) nsap);
+			Aerror(statp, stderr, "connect/vc", errno, nsap);
 			__res_iclose(statp, false);
 			return (0);
 		}
@@ -1002,8 +985,7 @@
 reopen (res_state statp, int *terrno, int ns)
 {
 	if (EXT(statp).nssocks[ns] == -1) {
-		struct sockaddr *nsap
-		  = (struct sockaddr *) EXT(statp).nsaddrs[ns];
+		struct sockaddr *nsap = get_nsaddr (statp, ns);
 		socklen_t slen;
 
 		/* only try IPv6 if IPv6 NS and if not failed before */
@@ -1167,7 +1149,7 @@
 	 */
 	int seconds = (statp->retrans << ns);
 	if (ns > 0)
-		seconds /= (statp->nscount + EXT(statp).nscount6);
+		seconds /= statp->nscount;
 	if (seconds <= 0)
 		seconds = 1;
 	bool single_request_reopen = (statp->options & RES_SNGLKUPREOP) != 0;
diff -Nurd glibc_2.19-18+deb8u5/stdlib/cxa_thread_atexit_impl.c glibc_2.19-18+deb8u6/stdlib/cxa_thread_atexit_impl.c
--- glibc_2.19-18+deb8u5/stdlib/cxa_thread_atexit_impl.c	2016-08-15 13:03:06.000000000 +0000
+++ glibc_2.19-18+deb8u6/stdlib/cxa_thread_atexit_impl.c	2016-08-15 13:03:47.000000000 +0000
@@ -91,8 +91,8 @@
 #ifdef PTR_DEMANGLE
       PTR_DEMANGLE (func);
 #endif
-      tls_dtor_list = tls_dtor_list->next;
 
+      tls_dtor_list = tls_dtor_list->next;
       func (cur->obj);
 
       __rtld_lock_lock_recursive (GL(dl_load_lock));
diff -Nurd glibc_2.19-18+deb8u5/string/strxfrm_l.c glibc_2.19-18+deb8u6/string/strxfrm_l.c
--- glibc_2.19-18+deb8u5/string/strxfrm_l.c	2016-08-15 13:03:06.000000000 +0000
+++ glibc_2.19-18+deb8u6/string/strxfrm_l.c	2016-08-15 13:03:47.000000000 +0000
@@ -100,9 +100,11 @@
 find_idx (const USTRING_TYPE **us, int32_t *weight_idx,
 	  unsigned char *rule_idx, const locale_data_t *l_data, const int pass)
 {
-  const int32_t *table = l_data->table;
-  const int32_t *indirect = l_data->indirect;
-  const USTRING_TYPE *extra = l_data->extra;
+  /* Prepare variables required by findidx().  */
+  int32_t *table = l_data->table;
+  int32_t *indirect = l_data->indirect;
+  USTRING_TYPE *extra = l_data->extra;
+
 #include WEIGHT_H
   int32_t tmp = findidx (us, -1);
   *rule_idx = tmp >> 24;
@@ -672,10 +674,6 @@
 {
   locale_data_t l_data;
   struct __locale_data *current = l->__locales[LC_COLLATE];
-  const int32_t *table;
-  const int32_t *indirect;
-  const USTRING_TYPE *extra;
-#include WEIGHT_H
   l_data.nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
 
   /* Handle byte comparison case.  */
@@ -708,9 +706,6 @@
     current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_EXTRA,SUFFIX))].string;
   l_data.indirect = (int32_t *)
     current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_INDIRECT,SUFFIX))].string;
-  table = l_data.table;
-  indirect = l_data.indirect;
-  extra = l_data.extra;
 
   assert (((uintptr_t) l_data.table) % __alignof__ (l_data.table[0]) == 0);
   assert (((uintptr_t) l_data.weights) % __alignof__ (l_data.weights[0]) == 0);
@@ -728,6 +723,11 @@
   const USTRING_TYPE *cur = usrc;
   int32_t *idxarr = alloca (SMALL_STR_SIZE * sizeof (int32_t));
   unsigned char *rulearr = alloca (SMALL_STR_SIZE + 1);
+  /* Prepare variables required by findidx().  */
+  int32_t *table = l_data.table;
+  int32_t *indirect = l_data.indirect;
+  USTRING_TYPE *extra = l_data.extra;
+#include WEIGHT_H
 
   do
     {
diff -Nurd glibc_2.19-18+deb8u5/sysdeps/mach/hurd/open.c glibc_2.19-18+deb8u6/sysdeps/mach/hurd/open.c
--- glibc_2.19-18+deb8u5/sysdeps/mach/hurd/open.c	2014-02-07 09:04:38.000000000 +0000
+++ glibc_2.19-18+deb8u6/sysdeps/mach/hurd/open.c	2016-08-15 13:03:47.000000000 +0000
@@ -22,7 +22,7 @@
 #include <hurd.h>
 #include <hurd/fd.h>
 
-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
    a third argument is the file protection.  */
 int
 __libc_open (const char *file, int oflag, ...)
@@ -30,7 +30,7 @@
   mode_t mode;
   io_t port;
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff -Nurd glibc_2.19-18+deb8u5/sysdeps/mach/hurd/openat.c glibc_2.19-18+deb8u6/sysdeps/mach/hurd/openat.c
--- glibc_2.19-18+deb8u5/sysdeps/mach/hurd/openat.c	2014-02-07 09:04:38.000000000 +0000
+++ glibc_2.19-18+deb8u6/sysdeps/mach/hurd/openat.c	2016-08-15 13:03:47.000000000 +0000
@@ -26,7 +26,7 @@
 #include <hurd/fd.h>
 
 /* Open FILE with access OFLAG.  Interpret relative paths relative to
-   the directory associated with FD.  If OFLAG includes O_CREAT, a
+   the directory associated with FD.  If O_CREAT or O_TMPFILE is in OFLAG, a
    third argument is the file protection.  */
 int
 __openat (fd, file, oflag)
@@ -37,7 +37,7 @@
   mode_t mode;
   io_t port;
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff -Nurd glibc_2.19-18+deb8u5/sysdeps/posix/open64.c glibc_2.19-18+deb8u6/sysdeps/posix/open64.c
--- glibc_2.19-18+deb8u5/sysdeps/posix/open64.c	2014-02-07 09:04:38.000000000 +0000
+++ glibc_2.19-18+deb8u6/sysdeps/posix/open64.c	2016-08-15 13:03:47.000000000 +0000
@@ -19,14 +19,14 @@
 #include <stdarg.h>
 #include <sysdep-cancel.h>
 
-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
    a third argument is the file protection.  */
 int
 __libc_open64 (const char *file, int oflag, ...)
 {
   int mode = 0;
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff -Nurd glibc_2.19-18+deb8u5/sysdeps/unix/sysv/linux/dl-openat64.c glibc_2.19-18+deb8u6/sysdeps/unix/sysv/linux/dl-openat64.c
--- glibc_2.19-18+deb8u5/sysdeps/unix/sysv/linux/dl-openat64.c	2014-02-07 09:04:38.000000000 +0000
+++ glibc_2.19-18+deb8u6/sysdeps/unix/sysv/linux/dl-openat64.c	2016-08-15 13:03:47.000000000 +0000
@@ -28,7 +28,7 @@
      const char *file;
      int oflag;
 {
-  assert ((oflag & O_CREAT) == 0);
+  assert (!__OPEN_NEEDS_MODE (oflag));
 
 #ifdef __NR_openat
   return INLINE_SYSCALL (openat, 3, dfd, file, oflag | O_LARGEFILE);
diff -Nurd glibc_2.19-18+deb8u5/sysdeps/unix/sysv/linux/open64.c glibc_2.19-18+deb8u6/sysdeps/unix/sysv/linux/open64.c
--- glibc_2.19-18+deb8u5/sysdeps/unix/sysv/linux/open64.c	2014-02-07 09:04:38.000000000 +0000
+++ glibc_2.19-18+deb8u6/sysdeps/unix/sysv/linux/open64.c	2016-08-15 13:03:47.000000000 +0000
@@ -21,14 +21,14 @@
 #include <stdio.h>
 #include <sysdep-cancel.h>
 
-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
    a third argument is the file protection.  */
 int
 __libc_open64 (const char *file, int oflag, ...)
 {
   int mode = 0;
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff -Nurd glibc_2.19-18+deb8u5/sysdeps/unix/sysv/linux/openat.c glibc_2.19-18+deb8u6/sysdeps/unix/sysv/linux/openat.c
--- glibc_2.19-18+deb8u5/sysdeps/unix/sysv/linux/openat.c	2014-02-07 09:04:38.000000000 +0000
+++ glibc_2.19-18+deb8u6/sysdeps/unix/sysv/linux/openat.c	2016-08-15 13:03:47.000000000 +0000
@@ -148,8 +148,8 @@
 
 
 /* Open FILE with access OFLAG.  Interpret relative paths relative to
-   the directory associated with FD.  If OFLAG includes O_CREAT, a
-   third argument is the file protection.  */
+   the directory associated with FD.  If OFLAG includes O_CREAT or
+   O_TMPFILE, a fourth argument is the file protection.  */
 int
 __OPENAT (fd, file, oflag)
      int fd;
@@ -157,7 +157,7 @@
      int oflag;
 {
   mode_t mode = 0;
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);

--- End Message ---
--- Begin Message ---
Version: 8.6

The updates referred to in each of these bugs were included in today's
stable point release.

Regards,

Adam

--- End Message ---

Reply via email to