On 2016-08-15 15:29, Aurelien Jarno wrote: > 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.
In the meantime a new security issue (CVE-2016-6323) has been found and backported to the upstream 2.19 stable branch. I would like to also include this change into the jessie upload. You will find updated diff and debdiff attached. Thanks for considering, Aurelien -- Aurelien Jarno GPG: 4096R/1DDD8C9B aurel...@aurel32.net http://www.aurel32.net
diff --git a/debian/changelog b/debian/changelog index a7ff140..bf495d3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,19 @@ +glibc (2.19-18+deb8u6) UNRELEASED; urgency=medium + + * Update from upstream stable branch: + - Fix backtrace hang on armel/armhf, possibly causing a minor + denial-of-service vulnerability (CVE-2016-6323). Closes: #834752. + - 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..d2d83f7 100644 --- a/debian/patches/git-updates.diff +++ b/debian/patches/git-updates.diff @@ -1,10 +1,74 @@ 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..30da116 100644 --- a/ChangeLog +++ b/ChangeLog -@@ -1,3 +1,558 @@ +@@ -1,3 +1,622 @@ ++2016-08-15 Andreas Schwab <sch...@suse.de> ++ ++ [BZ #20435] ++ * ports/sysdeps/unix/sysv/linux/arm/setcontext.S (__startcontext): ++ Mark as .cantunwind. ++ ++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,10 +628,10 @@ index 81c393a..fb2d7ff 100644 [BZ #16529] diff --git a/NEWS b/NEWS -index 98b479e..937c618 100644 +index 98b479e..a1bb834 100644 --- a/NEWS +++ b/NEWS -@@ -5,6 +5,98 @@ See the end for copying conditions. +@@ -5,6 +5,104 @@ See the end for copying conditions. Please send GNU C library bug reports via <http://sourceware.org/bugzilla/> using `glibc' in the "product" field. @@ -575,11 +639,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 @@ -662,6 +726,12 @@ index 98b479e..937c618 100644 +* The Sun RPC UDP client could exhaust all available stack space when + flooded with crafted ICMP and UDP messages. Reported by Aldy Hernandez' + alloca plugin for GCC. (CVE-2016-4429) ++ ++* On ARM EABI (32-bit), generating a backtrace for execution contexts which ++ have been created with makecontext could fail to terminate due to a ++ missing .cantunwind annotation. This has been observed to lead to a hang ++ (denial of service) in some Go applications compiled with gccgo. Reported ++ by Andreas Schwab. (CVE-2016-6323) + Version 2.19 @@ -900,6 +970,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 +1453,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 +1955,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 +2186,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 +3368,81 @@ index f6903b5..fed1dcb 100644 # define SINGLE_THREAD_P_PIC(x) SINGLE_THREAD_P # endif # endif +diff --git a/ports/sysdeps/unix/sysv/linux/arm/setcontext.S b/ports/sysdeps/unix/sysv/linux/arm/setcontext.S +index 7b9b511..7da16a9 100644 +--- a/ports/sysdeps/unix/sysv/linux/arm/setcontext.S ++++ b/ports/sysdeps/unix/sysv/linux/arm/setcontext.S +@@ -86,12 +86,19 @@ weak_alias(__setcontext, setcontext) + + /* Called when a makecontext() context returns. Start the + context in R4 or fall through to exit(). */ ++ /* Unwind descriptors are looked up based on PC - 2, so we have to ++ make sure to mark the instruction preceding the __startcontext ++ label as .cantunwind. */ ++ .fnstart ++ .cantunwind ++ nop + ENTRY(__startcontext) + movs r0, r4 + bne PLTJMP(__setcontext) + + @ New context was 0 - exit + b PLTJMP(HIDDEN_JUMPTARGET(_exit)) ++ .fnend + END(__startcontext) + + #ifdef PIC +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 +5249,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 +5584,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 +6204,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 +6272,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 +6500,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 +7876,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 +7931,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-19 11:15:29.000000000 +0200 +++ glibc_2.19-18+deb8u6/ChangeLog 2016-08-19 11:17:29.000000000 +0200 @@ -1,3 +1,67 @@ +2016-08-15 Andreas Schwab <sch...@suse.de> + + [BZ #20435] + * ports/sysdeps/unix/sysv/linux/arm/setcontext.S (__startcontext): + Mark as .cantunwind. + +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/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 10:04:38.000000000 +0100 +++ glibc_2.19-18+deb8u6/io/bits/fcntl2.h 2016-08-19 11:17:29.000000000 +0200 @@ -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-19 11:15:29.000000000 +0200 +++ glibc_2.19-18+deb8u6/io/fcntl.h 2016-08-19 11:17:29.000000000 +0200 @@ -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_2.c glibc_2.19-18+deb8u6/io/open_2.c --- glibc_2.19-18+deb8u5/io/open_2.c 2014-02-07 10:04:38.000000000 +0100 +++ glibc_2.19-18+deb8u6/io/open_2.c 2016-08-19 11:17:29.000000000 +0200 @@ -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/open64_2.c glibc_2.19-18+deb8u6/io/open64_2.c --- glibc_2.19-18+deb8u5/io/open64_2.c 2014-02-07 10:04:38.000000000 +0100 +++ glibc_2.19-18+deb8u6/io/open64_2.c 2016-08-19 11:17:29.000000000 +0200 @@ -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/open64.c glibc_2.19-18+deb8u6/io/open64.c --- glibc_2.19-18+deb8u5/io/open64.c 2014-02-07 10:04:38.000000000 +0100 +++ glibc_2.19-18+deb8u6/io/open64.c 2016-08-19 11:17:29.000000000 +0200 @@ -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/openat_2.c glibc_2.19-18+deb8u6/io/openat_2.c --- glibc_2.19-18+deb8u5/io/openat_2.c 2014-02-07 10:04:38.000000000 +0100 +++ glibc_2.19-18+deb8u6/io/openat_2.c 2016-08-19 11:17:29.000000000 +0200 @@ -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/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 10:04:38.000000000 +0100 +++ glibc_2.19-18+deb8u6/io/openat64_2.c 2016-08-19 11:17:29.000000000 +0200 @@ -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/openat64.c glibc_2.19-18+deb8u6/io/openat64.c --- glibc_2.19-18+deb8u5/io/openat64.c 2014-02-07 10:04:38.000000000 +0100 +++ glibc_2.19-18+deb8u6/io/openat64.c 2016-08-19 11:17:29.000000000 +0200 @@ -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/openat.c glibc_2.19-18+deb8u6/io/openat.c --- glibc_2.19-18+deb8u5/io/openat.c 2014-02-07 10:04:38.000000000 +0100 +++ glibc_2.19-18+deb8u6/io/openat.c 2016-08-19 11:17:29.000000000 +0200 @@ -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/open.c glibc_2.19-18+deb8u6/io/open.c --- glibc_2.19-18+deb8u5/io/open.c 2014-02-07 10:04:38.000000000 +0100 +++ glibc_2.19-18+deb8u6/io/open.c 2016-08-19 11:17:29.000000000 +0200 @@ -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/localedata/sort-test.sh glibc_2.19-18+deb8u6/localedata/sort-test.sh --- glibc_2.19-18+deb8u5/localedata/sort-test.sh 2016-08-19 11:15:29.000000000 +0200 +++ glibc_2.19-18+deb8u6/localedata/sort-test.sh 2016-08-19 11:17:29.000000000 +0200 @@ -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/NEWS glibc_2.19-18+deb8u6/NEWS --- glibc_2.19-18+deb8u5/NEWS 2016-08-19 11:15:29.000000000 +0200 +++ glibc_2.19-18+deb8u6/NEWS 2016-08-19 11:17:29.000000000 +0200 @@ -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 @@ -96,6 +96,12 @@ * The Sun RPC UDP client could exhaust all available stack space when flooded with crafted ICMP and UDP messages. Reported by Aldy Hernandez' alloca plugin for GCC. (CVE-2016-4429) + +* On ARM EABI (32-bit), generating a backtrace for execution contexts which + have been created with makecontext could fail to terminate due to a + missing .cantunwind annotation. This has been observed to lead to a hang + (denial of service) in some Go applications compiled with gccgo. Reported + by Andreas Schwab. (CVE-2016-6323) Version 2.19 diff -Nurd glibc_2.19-18+deb8u5/ports/sysdeps/unix/sysv/linux/arm/setcontext.S glibc_2.19-18+deb8u6/ports/sysdeps/unix/sysv/linux/arm/setcontext.S --- glibc_2.19-18+deb8u5/ports/sysdeps/unix/sysv/linux/arm/setcontext.S 2014-02-07 10:04:38.000000000 +0100 +++ glibc_2.19-18+deb8u6/ports/sysdeps/unix/sysv/linux/arm/setcontext.S 2016-08-19 11:17:29.000000000 +0200 @@ -86,12 +86,19 @@ /* Called when a makecontext() context returns. Start the context in R4 or fall through to exit(). */ + /* Unwind descriptors are looked up based on PC - 2, so we have to + make sure to mark the instruction preceding the __startcontext + label as .cantunwind. */ + .fnstart + .cantunwind + nop ENTRY(__startcontext) movs r0, r4 bne PLTJMP(__setcontext) @ New context was 0 - exit b PLTJMP(HIDDEN_JUMPTARGET(_exit)) + .fnend END(__startcontext) #ifdef PIC 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 10:04:38.000000000 +0100 +++ glibc_2.19-18+deb8u6/ports/sysdeps/unix/sysv/linux/generic/open64.c 2016-08-19 11:17:29.000000000 +0200 @@ -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/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 10:04:38.000000000 +0100 +++ glibc_2.19-18+deb8u6/ports/sysdeps/unix/sysv/linux/generic/open.c 2016-08-19 11:17:29.000000000 +0200 @@ -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/resolv/res_init.c glibc_2.19-18+deb8u6/resolv/res_init.c --- glibc_2.19-18+deb8u5/resolv/res_init.c 2016-08-19 11:15:29.000000000 +0200 +++ glibc_2.19-18+deb8u6/resolv/res_init.c 2016-08-19 11:17:29.000000000 +0200 @@ -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-19 11:15:29.000000000 +0200 +++ glibc_2.19-18+deb8u6/resolv/res_send.c 2016-08-19 11:17:29.000000000 +0200 @@ -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-19 11:15:29.000000000 +0200 +++ glibc_2.19-18+deb8u6/stdlib/cxa_thread_atexit_impl.c 2016-08-19 11:17:29.000000000 +0200 @@ -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-19 11:15:29.000000000 +0200 +++ glibc_2.19-18+deb8u6/string/strxfrm_l.c 2016-08-19 11:17:29.000000000 +0200 @@ -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/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 10:04:38.000000000 +0100 +++ glibc_2.19-18+deb8u6/sysdeps/mach/hurd/openat.c 2016-08-19 11:17:29.000000000 +0200 @@ -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/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 10:04:38.000000000 +0100 +++ glibc_2.19-18+deb8u6/sysdeps/mach/hurd/open.c 2016-08-19 11:17:29.000000000 +0200 @@ -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/posix/open64.c glibc_2.19-18+deb8u6/sysdeps/posix/open64.c --- glibc_2.19-18+deb8u5/sysdeps/posix/open64.c 2014-02-07 10:04:38.000000000 +0100 +++ glibc_2.19-18+deb8u6/sysdeps/posix/open64.c 2016-08-19 11:17:29.000000000 +0200 @@ -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 10:04:38.000000000 +0100 +++ glibc_2.19-18+deb8u6/sysdeps/unix/sysv/linux/dl-openat64.c 2016-08-19 11:17:29.000000000 +0200 @@ -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 10:04:38.000000000 +0100 +++ glibc_2.19-18+deb8u6/sysdeps/unix/sysv/linux/open64.c 2016-08-19 11:17:29.000000000 +0200 @@ -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 10:04:38.000000000 +0100 +++ glibc_2.19-18+deb8u6/sysdeps/unix/sysv/linux/openat.c 2016-08-19 11:17:29.000000000 +0200 @@ -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);