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);

Reply via email to