diff options
author | Fredrik Rinnestam <fredrik@crux.nu> | 2016-07-05 20:34:12 +0200 |
---|---|---|
committer | Fredrik Rinnestam <fredrik@crux.nu> | 2016-07-05 20:36:20 +0200 |
commit | 5ac2fbdd419049d226ec6f0c43fed5918fc739c1 (patch) | |
tree | 51547a2963a78874566dad3fa0d141cd086fb054 /glibc | |
parent | 1b23e944cc50b6296d412c85148c17caa24e1ac5 (diff) | |
download | core-5ac2fbdd419049d226ec6f0c43fed5918fc739c1.tar.gz core-5ac2fbdd419049d226ec6f0c43fed5918fc739c1.tar.xz |
glibc: updated to 2.23-bbe472f
Diffstat (limited to 'glibc')
-rw-r--r-- | glibc/.md5sum | 2 | ||||
-rw-r--r-- | glibc/.signature | 6 | ||||
-rw-r--r-- | glibc/CVE-2015-7547.patch | 555 | ||||
-rw-r--r-- | glibc/CVE-2015-8776.patch | 121 | ||||
-rw-r--r-- | glibc/CVE-2015-8777.patch | 59 | ||||
-rw-r--r-- | glibc/CVE-2015-8778.patch | 29 | ||||
-rw-r--r-- | glibc/CVE-2015-8779.patch | 239 | ||||
-rw-r--r-- | glibc/Pkgfile | 10 | ||||
-rw-r--r-- | glibc/glibc-rh1252570.patch | 408 |
9 files changed, 9 insertions, 1420 deletions
diff --git a/glibc/.md5sum b/glibc/.md5sum index b7d7491a..25f9a0db 100644 --- a/glibc/.md5sum +++ b/glibc/.md5sum @@ -1,5 +1,5 @@ aaad345ff18993dafe3e44ac947f7157 glibc-2.20-multilib-dirs.patch -456995968f3acadbed39f5eba31678df glibc-2.23.tar.xz +9f7b4a05ba81a2b6304113ff99807626 glibc-2.23-bbe472f.tar.xz 96156bec8e05de67384dc93e72bdc313 host.conf fbbc215a9b15ba4846f326cc88108057 hosts 935f8c95a801d7b1675c487a144c6f17 kernel-headers-4.4.14.tar.xz diff --git a/glibc/.signature b/glibc/.signature index b640f9f8..97aa5bb0 100644 --- a/glibc/.signature +++ b/glibc/.signature @@ -1,8 +1,8 @@ untrusted comment: verify with /etc/ports/core.pub -RWRJc1FUaeVeqoiP5m35BJZ6PxlspPgDIUI3yuOM5zkYb1+4txfcwnLUxYzW6OSmxoGd5wjLRIbV0GeeyQWijuEu0nl481jdWwY= -SHA256 (Pkgfile) = ca9e672469c87307b1f234f2a5b90a7ab494e86ae06937fd1854d8ce03da9de2 +RWRJc1FUaeVeqpXVMCf1y1sYyW4/rsHnxul3xfwxu/9P3w62RbNlGhor37Hcj5uX0K4dWGbIAl/V/NZ/MZ2/VgyUhJFRyzEM4A4= +SHA256 (Pkgfile) = d9291310d65d31bb17a19d6dc1f13a7075c0946ecdd21db69cab2433cf18c71d SHA256 (.footprint) = 098f83d1ccce77a11f6f78a6769b3190a62b83e2bd5692d21e2b9399e08b4b83 -SHA256 (glibc-2.23.tar.xz) = 94efeb00e4603c8546209cefb3e1a50a5315c86fa9b078b6fad758e187ce13e9 +SHA256 (glibc-2.23-bbe472f.tar.xz) = 16fec9f9377d9b192456d344d5c910d2f294702d30782168e2fa3a6877f52428 SHA256 (kernel-headers-4.4.14.tar.xz) = 82ffcae06f60f54c47d79c891bcf487d6f770f49d0b4e33c73110af434600633 SHA256 (glibc-2.20-multilib-dirs.patch) = 9cf0fbbb0fbb19f29cc540240fbe9a2256cdde5e7395e30970df1a4f3d8292c3 SHA256 (hosts) = 5c02b256c105f1d4a12fb738d71c1bab9eb126533074d7a0c8a14b92670c9431 diff --git a/glibc/CVE-2015-7547.patch b/glibc/CVE-2015-7547.patch deleted file mode 100644 index 2a762890..00000000 --- a/glibc/CVE-2015-7547.patch +++ /dev/null @@ -1,555 +0,0 @@ -Index: b/resolv/nss_dns/dns-host.c -=================================================================== ---- a/resolv/nss_dns/dns-host.c -+++ b/resolv/nss_dns/dns-host.c -@@ -1031,7 +1031,10 @@ gaih_getanswer_slice (const querybuf *an - int h_namelen = 0; - - if (ancount == 0) -- return NSS_STATUS_NOTFOUND; -+ { -+ *h_errnop = HOST_NOT_FOUND; -+ return NSS_STATUS_NOTFOUND; -+ } - - while (ancount-- > 0 && cp < end_of_message && had_error == 0) - { -@@ -1208,7 +1211,14 @@ gaih_getanswer_slice (const querybuf *an - /* Special case here: if the resolver sent a result but it only - contains a CNAME while we are looking for a T_A or T_AAAA record, - we fail with NOTFOUND instead of TRYAGAIN. */ -- return canon == NULL ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND; -+ if (canon != NULL) -+ { -+ *h_errnop = HOST_NOT_FOUND; -+ return NSS_STATUS_NOTFOUND; -+ } -+ -+ *h_errnop = NETDB_INTERNAL; -+ return NSS_STATUS_TRYAGAIN; - } - - -@@ -1222,11 +1232,101 @@ gaih_getanswer (const querybuf *answer1, - - enum nss_status status = NSS_STATUS_NOTFOUND; - -+ /* Combining the NSS status of two distinct queries requires some -+ compromise and attention to symmetry (A or AAAA queries can be -+ returned in any order). What follows is a breakdown of how this -+ code is expected to work and why. We discuss only SUCCESS, -+ TRYAGAIN, NOTFOUND and UNAVAIL, since they are the only returns -+ that apply (though RETURN and MERGE exist). We make a distinction -+ between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable). -+ A recoverable TRYAGAIN is almost always due to buffer size issues -+ and returns ERANGE in errno and the caller is expected to retry -+ with a larger buffer. -+ -+ Lastly, you may be tempted to make significant changes to the -+ conditions in this code to bring about symmetry between responses. -+ Please don't change anything without due consideration for -+ expected application behaviour. Some of the synthesized responses -+ aren't very well thought out and sometimes appear to imply that -+ IPv4 responses are always answer 1, and IPv6 responses are always -+ answer 2, but that's not true (see the implemetnation of send_dg -+ and send_vc to see response can arrive in any order, particlarly -+ for UDP). However, we expect it holds roughly enough of the time -+ that this code works, but certainly needs to be fixed to make this -+ a more robust implementation. -+ -+ ---------------------------------------------- -+ | Answer 1 Status / | Synthesized | Reason | -+ | Answer 2 Status | Status | | -+ |--------------------------------------------| -+ | SUCCESS/SUCCESS | SUCCESS | [1] | -+ | SUCCESS/TRYAGAIN | TRYAGAIN | [5] | -+ | SUCCESS/TRYAGAIN' | SUCCESS | [1] | -+ | SUCCESS/NOTFOUND | SUCCESS | [1] | -+ | SUCCESS/UNAVAIL | SUCCESS | [1] | -+ | TRYAGAIN/SUCCESS | TRYAGAIN | [2] | -+ | TRYAGAIN/TRYAGAIN | TRYAGAIN | [2] | -+ | TRYAGAIN/TRYAGAIN' | TRYAGAIN | [2] | -+ | TRYAGAIN/NOTFOUND | TRYAGAIN | [2] | -+ | TRYAGAIN/UNAVAIL | TRYAGAIN | [2] | -+ | TRYAGAIN'/SUCCESS | SUCCESS | [3] | -+ | TRYAGAIN'/TRYAGAIN | TRYAGAIN | [3] | -+ | TRYAGAIN'/TRYAGAIN' | TRYAGAIN' | [3] | -+ | TRYAGAIN'/NOTFOUND | TRYAGAIN' | [3] | -+ | TRYAGAIN'/UNAVAIL | UNAVAIL | [3] | -+ | NOTFOUND/SUCCESS | SUCCESS | [3] | -+ | NOTFOUND/TRYAGAIN | TRYAGAIN | [3] | -+ | NOTFOUND/TRYAGAIN' | TRYAGAIN' | [3] | -+ | NOTFOUND/NOTFOUND | NOTFOUND | [3] | -+ | NOTFOUND/UNAVAIL | UNAVAIL | [3] | -+ | UNAVAIL/SUCCESS | UNAVAIL | [4] | -+ | UNAVAIL/TRYAGAIN | UNAVAIL | [4] | -+ | UNAVAIL/TRYAGAIN' | UNAVAIL | [4] | -+ | UNAVAIL/NOTFOUND | UNAVAIL | [4] | -+ | UNAVAIL/UNAVAIL | UNAVAIL | [4] | -+ ---------------------------------------------- -+ -+ [1] If the first response is a success we return success. -+ This ignores the state of the second answer and in fact -+ incorrectly sets errno and h_errno to that of the second -+ answer. However because the response is a success we ignore -+ *errnop and *h_errnop (though that means you touched errno on -+ success). We are being conservative here and returning the -+ likely IPv4 response in the first answer as a success. -+ -+ [2] If the first response is a recoverable TRYAGAIN we return -+ that instead of looking at the second response. The -+ expectation here is that we have failed to get an IPv4 response -+ and should retry both queries. -+ -+ [3] If the first response was not a SUCCESS and the second -+ response is not NOTFOUND (had a SUCCESS, need to TRYAGAIN, -+ or failed entirely e.g. TRYAGAIN' and UNAVAIL) then use the -+ result from the second response, otherwise the first responses -+ status is used. Again we have some odd side-effects when the -+ second response is NOTFOUND because we overwrite *errnop and -+ *h_errnop that means that a first answer of NOTFOUND might see -+ its *errnop and *h_errnop values altered. Whether it matters -+ in practice that a first response NOTFOUND has the wrong -+ *errnop and *h_errnop is undecided. -+ -+ [4] If the first response is UNAVAIL we return that instead of -+ looking at the second response. The expectation here is that -+ it will have failed similarly e.g. configuration failure. -+ -+ [5] Testing this code is complicated by the fact that truncated -+ second response buffers might be returned as SUCCESS if the -+ first answer is a SUCCESS. To fix this we add symmetry to -+ TRYAGAIN with the second response. If the second response -+ is a recoverable error we now return TRYAGIN even if the first -+ response was SUCCESS. */ -+ - if (anslen1 > 0) - status = gaih_getanswer_slice(answer1, anslen1, qname, - &pat, &buffer, &buflen, - errnop, h_errnop, ttlp, - &first); -+ - if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND - || (status == NSS_STATUS_TRYAGAIN - /* We want to look at the second answer in case of an -@@ -1242,8 +1342,15 @@ gaih_getanswer (const querybuf *answer1, - &pat, &buffer, &buflen, - errnop, h_errnop, ttlp, - &first); -+ /* Use the second response status in some cases. */ - if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND) - status = status2; -+ /* Do not return a truncated second response (unless it was -+ unavoidable e.g. unrecoverable TRYAGAIN). */ -+ if (status == NSS_STATUS_SUCCESS -+ && (status2 == NSS_STATUS_TRYAGAIN -+ && *errnop == ERANGE && *h_errnop != NO_RECOVERY)) -+ status = NSS_STATUS_TRYAGAIN; - } - - return status; -Index: b/resolv/res_query.c -=================================================================== ---- a/resolv/res_query.c -+++ b/resolv/res_query.c -@@ -396,6 +396,7 @@ __libc_res_nsearch(res_state statp, - { - free (*answerp2); - *answerp2 = NULL; -+ *nanswerp2 = 0; - *answerp2_malloced = 0; - } - } -@@ -447,6 +448,7 @@ __libc_res_nsearch(res_state statp, - { - free (*answerp2); - *answerp2 = NULL; -+ *nanswerp2 = 0; - *answerp2_malloced = 0; - } - -@@ -521,6 +523,7 @@ __libc_res_nsearch(res_state statp, - { - free (*answerp2); - *answerp2 = NULL; -+ *nanswerp2 = 0; - *answerp2_malloced = 0; - } - if (saved_herrno != -1) -Index: b/resolv/res_send.c -=================================================================== ---- a/resolv/res_send.c -+++ b/resolv/res_send.c -@@ -1,3 +1,20 @@ -+/* Copyright (C) 2016 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ <http://www.gnu.org/licenses/>. */ -+ - /* - * Copyright (c) 1985, 1989, 1993 - * The Regents of the University of California. All rights reserved. -@@ -361,6 +378,8 @@ __libc_res_nsend(res_state statp, const - #ifdef USE_HOOKS - if (__glibc_unlikely (statp->qhook || statp->rhook)) { - if (anssiz < MAXPACKET && ansp) { -+ /* Always allocate MAXPACKET, callers expect -+ this specific size. */ - u_char *buf = malloc (MAXPACKET); - if (buf == NULL) - return (-1); -@@ -660,6 +679,77 @@ libresolv_hidden_def (res_nsend) - - /* Private */ - -+/* The send_vc function is responsible for sending a DNS query over TCP -+ to the nameserver numbered NS from the res_state STATP i.e. -+ EXT(statp).nssocks[ns]. The function supports sending both IPv4 and -+ IPv6 queries at the same serially on the same socket. -+ -+ Please note that for TCP there is no way to disable sending both -+ queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP -+ and sends the queries serially and waits for the result after each -+ sent query. This implemetnation should be corrected to honour these -+ options. -+ -+ Please also note that for TCP we send both queries over the same -+ socket one after another. This technically violates best practice -+ since the server is allowed to read the first query, respond, and -+ then close the socket (to service another client). If the server -+ does this, then the remaining second query in the socket data buffer -+ will cause the server to send the client an RST which will arrive -+ asynchronously and the client's OS will likely tear down the socket -+ receive buffer resulting in a potentially short read and lost -+ response data. This will force the client to retry the query again, -+ and this process may repeat until all servers and connection resets -+ are exhausted and then the query will fail. It's not known if this -+ happens with any frequency in real DNS server implementations. This -+ implementation should be corrected to use two sockets by default for -+ parallel queries. -+ -+ The query stored in BUF of BUFLEN length is sent first followed by -+ the query stored in BUF2 of BUFLEN2 length. Queries are sent -+ serially on the same socket. -+ -+ Answers to the query are stored firstly in *ANSP up to a max of -+ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP -+ is non-NULL (to indicate that modifying the answer buffer is allowed) -+ then malloc is used to allocate a new response buffer and ANSCP and -+ ANSP will both point to the new buffer. If more than *ANSSIZP bytes -+ are needed but ANSCP is NULL, then as much of the response as -+ possible is read into the buffer, but the results will be truncated. -+ When truncation happens because of a small answer buffer the DNS -+ packets header feild TC will bet set to 1, indicating a truncated -+ message and the rest of the socket data will be read and discarded. -+ -+ Answers to the query are stored secondly in *ANSP2 up to a max of -+ *ANSSIZP2 bytes, with the actual response length stored in -+ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2 -+ is non-NULL (required for a second query) then malloc is used to -+ allocate a new response buffer, *ANSSIZP2 is set to the new buffer -+ size and *ANSP2_MALLOCED is set to 1. -+ -+ The ANSP2_MALLOCED argument will eventually be removed as the -+ change in buffer pointer can be used to detect the buffer has -+ changed and that the caller should use free on the new buffer. -+ -+ Note that the answers may arrive in any order from the server and -+ therefore the first and second answer buffers may not correspond to -+ the first and second queries. -+ -+ It is not supported to call this function with a non-NULL ANSP2 -+ but a NULL ANSCP. Put another way, you can call send_vc with a -+ single unmodifiable buffer or two modifiable buffers, but no other -+ combination is supported. -+ -+ It is the caller's responsibility to free the malloc allocated -+ buffers by detecting that the pointers have changed from their -+ original values i.e. *ANSCP or *ANSP2 has changed. -+ -+ If errors are encountered then *TERRNO is set to an appropriate -+ errno value and a zero result is returned for a recoverable error, -+ and a less-than zero result is returned for a non-recoverable error. -+ -+ If no errors are encountered then *TERRNO is left unmodified and -+ a the length of the first response in bytes is returned. */ - static int - send_vc(res_state statp, - const u_char *buf, int buflen, const u_char *buf2, int buflen2, -@@ -669,11 +759,7 @@ send_vc(res_state statp, - { - const HEADER *hp = (HEADER *) buf; - const HEADER *hp2 = (HEADER *) buf2; -- u_char *ans = *ansp; -- int orig_anssizp = *anssizp; -- // XXX REMOVE -- // int anssiz = *anssizp; -- HEADER *anhp = (HEADER *) ans; -+ HEADER *anhp = (HEADER *) *ansp; - struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns]; - int truncating, connreset, n; - /* On some architectures compiler might emit a warning indicating -@@ -766,6 +852,8 @@ send_vc(res_state statp, - * Receive length & response - */ - int recvresp1 = 0; -+ /* Skip the second response if there is no second query. -+ To do that we mark the second response as received. */ - int recvresp2 = buf2 == NULL; - uint16_t rlen16; - read_len: -@@ -802,40 +890,14 @@ send_vc(res_state statp, - u_char **thisansp; - int *thisresplenp; - if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) { -+ /* We have not received any responses -+ yet or we only have one response to -+ receive. */ - thisanssizp = anssizp; - thisansp = anscp ?: ansp; - assert (anscp != NULL || ansp2 == NULL); - thisresplenp = &resplen; - } else { -- if (*anssizp != MAXPACKET) { -- /* No buffer allocated for the first -- reply. We can try to use the rest -- of the user-provided buffer. */ --#if __GNUC_PREREQ (4, 7) -- DIAG_PUSH_NEEDS_COMMENT; -- DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized"); --#endif --#if _STRING_ARCH_unaligned -- *anssizp2 = orig_anssizp - resplen; -- *ansp2 = *ansp + resplen; --#else -- int aligned_resplen -- = ((resplen + __alignof__ (HEADER) - 1) -- & ~(__alignof__ (HEADER) - 1)); -- *anssizp2 = orig_anssizp - aligned_resplen; -- *ansp2 = *ansp + aligned_resplen; --#endif --#if __GNUC_PREREQ (4, 7) -- DIAG_POP_NEEDS_COMMENT; --#endif -- } else { -- /* The first reply did not fit into the -- user-provided buffer. Maybe the second -- answer will. */ -- *anssizp2 = orig_anssizp; -- *ansp2 = *ansp; -- } -- - thisanssizp = anssizp2; - thisansp = ansp2; - thisresplenp = resplen2; -@@ -843,10 +905,14 @@ send_vc(res_state statp, - anhp = (HEADER *) *thisansp; - - *thisresplenp = rlen; -- if (rlen > *thisanssizp) { -- /* Yes, we test ANSCP here. If we have two buffers -- both will be allocatable. */ -- if (__glibc_likely (anscp != NULL)) { -+ /* Is the answer buffer too small? */ -+ if (*thisanssizp < rlen) { -+ /* If the current buffer is non-NULL and it's not -+ pointing at the static user-supplied buffer then -+ we can reallocate it. */ -+ if (thisansp != NULL && thisansp != ansp) { -+ /* Always allocate MAXPACKET, callers expect -+ this specific size. */ - u_char *newp = malloc (MAXPACKET); - if (newp == NULL) { - *terrno = ENOMEM; -@@ -858,6 +924,9 @@ send_vc(res_state statp, - if (thisansp == ansp2) - *ansp2_malloced = 1; - anhp = (HEADER *) newp; -+ /* A uint16_t can't be larger than MAXPACKET -+ thus it's safe to allocate MAXPACKET but -+ read RLEN bytes instead. */ - len = rlen; - } else { - Dprint(statp->options & RES_DEBUG, -@@ -1021,6 +1090,66 @@ reopen (res_state statp, int *terrno, in - return 1; - } - -+/* The send_dg function is responsible for sending a DNS query over UDP -+ to the nameserver numbered NS from the res_state STATP i.e. -+ EXT(statp).nssocks[ns]. The function supports IPv4 and IPv6 queries -+ along with the ability to send the query in parallel for both stacks -+ (default) or serially (RES_SINGLKUP). It also supports serial lookup -+ with a close and reopen of the socket used to talk to the server -+ (RES_SNGLKUPREOP) to work around broken name servers. -+ -+ The query stored in BUF of BUFLEN length is sent first followed by -+ the query stored in BUF2 of BUFLEN2 length. Queries are sent -+ in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP). -+ -+ Answers to the query are stored firstly in *ANSP up to a max of -+ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP -+ is non-NULL (to indicate that modifying the answer buffer is allowed) -+ then malloc is used to allocate a new response buffer and ANSCP and -+ ANSP will both point to the new buffer. If more than *ANSSIZP bytes -+ are needed but ANSCP is NULL, then as much of the response as -+ possible is read into the buffer, but the results will be truncated. -+ When truncation happens because of a small answer buffer the DNS -+ packets header feild TC will bet set to 1, indicating a truncated -+ message, while the rest of the UDP packet is discarded. -+ -+ Answers to the query are stored secondly in *ANSP2 up to a max of -+ *ANSSIZP2 bytes, with the actual response length stored in -+ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2 -+ is non-NULL (required for a second query) then malloc is used to -+ allocate a new response buffer, *ANSSIZP2 is set to the new buffer -+ size and *ANSP2_MALLOCED is set to 1. -+ -+ The ANSP2_MALLOCED argument will eventually be removed as the -+ change in buffer pointer can be used to detect the buffer has -+ changed and that the caller should use free on the new buffer. -+ -+ Note that the answers may arrive in any order from the server and -+ therefore the first and second answer buffers may not correspond to -+ the first and second queries. -+ -+ It is not supported to call this function with a non-NULL ANSP2 -+ but a NULL ANSCP. Put another way, you can call send_vc with a -+ single unmodifiable buffer or two modifiable buffers, but no other -+ combination is supported. -+ -+ It is the caller's responsibility to free the malloc allocated -+ buffers by detecting that the pointers have changed from their -+ original values i.e. *ANSCP or *ANSP2 has changed. -+ -+ If an answer is truncated because of UDP datagram DNS limits then -+ *V_CIRCUIT is set to 1 and the return value non-zero to indicate to -+ the caller to retry with TCP. The value *GOTSOMEWHERE is set to 1 -+ if any progress was made reading a response from the nameserver and -+ is used by the caller to distinguish between ECONNREFUSED and -+ ETIMEDOUT (the latter if *GOTSOMEWHERE is 1). -+ -+ If errors are encountered then *TERRNO is set to an appropriate -+ errno value and a zero result is returned for a recoverable error, -+ and a less-than zero result is returned for a non-recoverable error. -+ -+ If no errors are encountered then *TERRNO is left unmodified and -+ a the length of the first response in bytes is returned. */ - static int - send_dg(res_state statp, - const u_char *buf, int buflen, const u_char *buf2, int buflen2, -@@ -1030,8 +1159,6 @@ send_dg(res_state statp, - { - const HEADER *hp = (HEADER *) buf; - const HEADER *hp2 = (HEADER *) buf2; -- u_char *ans = *ansp; -- int orig_anssizp = *anssizp; - struct timespec now, timeout, finish; - struct pollfd pfd[1]; - int ptimeout; -@@ -1064,6 +1191,8 @@ send_dg(res_state statp, - int need_recompute = 0; - int nwritten = 0; - int recvresp1 = 0; -+ /* Skip the second response if there is no second query. -+ To do that we mark the second response as received. */ - int recvresp2 = buf2 == NULL; - pfd[0].fd = EXT(statp).nssocks[ns]; - pfd[0].events = POLLOUT; -@@ -1227,55 +1356,56 @@ send_dg(res_state statp, - int *thisresplenp; - - if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) { -+ /* We have not received any responses -+ yet or we only have one response to -+ receive. */ - thisanssizp = anssizp; - thisansp = anscp ?: ansp; - assert (anscp != NULL || ansp2 == NULL); - thisresplenp = &resplen; - } else { -- if (*anssizp != MAXPACKET) { -- /* No buffer allocated for the first -- reply. We can try to use the rest -- of the user-provided buffer. */ --#if _STRING_ARCH_unaligned -- *anssizp2 = orig_anssizp - resplen; -- *ansp2 = *ansp + resplen; --#else -- int aligned_resplen -- = ((resplen + __alignof__ (HEADER) - 1) -- & ~(__alignof__ (HEADER) - 1)); -- *anssizp2 = orig_anssizp - aligned_resplen; -- *ansp2 = *ansp + aligned_resplen; --#endif -- } else { -- /* The first reply did not fit into the -- user-provided buffer. Maybe the second -- answer will. */ -- *anssizp2 = orig_anssizp; -- *ansp2 = *ansp; -- } -- - thisanssizp = anssizp2; - thisansp = ansp2; - thisresplenp = resplen2; - } - - if (*thisanssizp < MAXPACKET -- /* Yes, we test ANSCP here. If we have two buffers -- both will be allocatable. */ -- && anscp -+ /* If the current buffer is non-NULL and it's not -+ pointing at the static user-supplied buffer then -+ we can reallocate it. */ -+ && (thisansp != NULL && thisansp != ansp) - #ifdef FIONREAD -+ /* Is the size too small? */ - && (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0 - || *thisanssizp < *thisresplenp) - #endif - ) { -+ /* Always allocate MAXPACKET, callers expect -+ this specific size. */ - u_char *newp = malloc (MAXPACKET); - if (newp != NULL) { -- *anssizp = MAXPACKET; -- *thisansp = ans = newp; -+ *thisanssizp = MAXPACKET; -+ *thisansp = newp; - if (thisansp == ansp2) - *ansp2_malloced = 1; - } - } -+ /* We could end up with truncation if anscp was NULL -+ (not allowed to change caller's buffer) and the -+ response buffer size is too small. This isn't a -+ reliable way to detect truncation because the ioctl -+ may be an inaccurate report of the UDP message size. -+ Therefore we use this only to issue debug output. -+ To do truncation accurately with UDP we need -+ MSG_TRUNC which is only available on Linux. We -+ can abstract out the Linux-specific feature in the -+ future to detect truncation. */ -+ if (__glibc_unlikely (*thisanssizp < *thisresplenp)) { -+ Dprint(statp->options & RES_DEBUG, -+ (stdout, ";; response may be truncated (UDP)\n") -+ ); -+ } -+ - HEADER *anhp = (HEADER *) *thisansp; - socklen_t fromlen = sizeof(struct sockaddr_in6); - assert (sizeof(from) <= fromlen); - diff --git a/glibc/CVE-2015-8776.patch b/glibc/CVE-2015-8776.patch deleted file mode 100644 index ac202e61..00000000 --- a/glibc/CVE-2015-8776.patch +++ /dev/null @@ -1,121 +0,0 @@ -diff --git a/time/strftime_l.c b/time/strftime_l.c -index b48ef34..4eb647c 100644 ---- a/time/strftime_l.c -+++ b/time/strftime_l.c -@@ -510,13 +510,17 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument - only a few elements. Dereference the pointers only if the format - requires this. Then it is ok to fail if the pointers are invalid. */ - # define a_wkday \ -- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday)) -+ ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \ -+ ? "?" : _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))) - # define f_wkday \ -- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday)) -+ ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \ -+ ? "?" : _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))) - # define a_month \ -- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon)) -+ ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ -+ ? "?" : _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))) - # define f_month \ -- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon)) -+ ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ -+ ? "?" : _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))) - # define ampm \ - ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \ - ? NLW(PM_STR) : NLW(AM_STR))) -@@ -526,8 +530,10 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument - # define ap_len STRLEN (ampm) - #else - # if !HAVE_STRFTIME --# define f_wkday (weekday_name[tp->tm_wday]) --# define f_month (month_name[tp->tm_mon]) -+# define f_wkday (tp->tm_wday < 0 || tp->tm_wday > 6 \ -+ ? "?" : weekday_name[tp->tm_wday]) -+# define f_month (tp->tm_mon < 0 || tp->tm_mon > 11 \ -+ ? "?" : month_name[tp->tm_mon]) - # define a_wkday f_wkday - # define a_month f_month - # define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11)) -@@ -1321,7 +1327,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument - *tzset_called = true; - } - # endif -- zone = tzname[tp->tm_isdst]; -+ zone = tp->tm_isdst <= 1 ? tzname[tp->tm_isdst] : "?"; - } - #endif - if (! zone) -diff --git a/time/tst-strftime.c b/time/tst-strftime.c -index 374fba4..af3ff72 100644 ---- a/time/tst-strftime.c -+++ b/time/tst-strftime.c -@@ -4,6 +4,56 @@ - #include <time.h> - - -+static int -+do_bz18985 (void) -+{ -+ char buf[1000]; -+ struct tm ttm; -+ int rc, ret = 0; -+ -+ memset (&ttm, 1, sizeof (ttm)); -+ ttm.tm_zone = NULL; /* Dereferenced directly if non-NULL. */ -+ rc = strftime (buf, sizeof (buf), "%a %A %b %B %c %z %Z", &ttm); -+ -+ if (rc == 66) -+ { -+ const char expected[] -+ = "? ? ? ? ? ? 16843009 16843009:16843009:16843009 16844909 +467836 ?"; -+ if (0 != strcmp (buf, expected)) -+ { -+ printf ("expected:\n %s\ngot:\n %s\n", expected, buf); -+ ret += 1; -+ } -+ } -+ else -+ { -+ printf ("expected 66, got %d\n", rc); -+ ret += 1; -+ } -+ -+ /* Check negative values as well. */ -+ memset (&ttm, 0xFF, sizeof (ttm)); -+ ttm.tm_zone = NULL; /* Dereferenced directly if non-NULL. */ -+ rc = strftime (buf, sizeof (buf), "%a %A %b %B %c %z %Z", &ttm); -+ -+ if (rc == 30) -+ { -+ const char expected[] = "? ? ? ? ? ? -1 -1:-1:-1 1899 "; -+ if (0 != strcmp (buf, expected)) -+ { -+ printf ("expected:\n %s\ngot:\n %s\n", expected, buf); -+ ret += 1; -+ } -+ } -+ else -+ { -+ printf ("expected 30, got %d\n", rc); -+ ret += 1; -+ } -+ -+ return ret; -+} -+ - static struct - { - const char *fmt; -@@ -104,7 +154,7 @@ do_test (void) - } - } - -- return result; -+ return result + do_bz18985 (); - } - - #define TEST_FUNCTION do_test () --- -1.9.4 - diff --git a/glibc/CVE-2015-8777.patch b/glibc/CVE-2015-8777.patch deleted file mode 100644 index 0c01c257..00000000 --- a/glibc/CVE-2015-8777.patch +++ /dev/null @@ -1,59 +0,0 @@ -diff --git a/elf/rtld.c b/elf/rtld.c -index 69873c2..07e741c 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, - -@@ -709,15 +708,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 -@@ -2471,9 +2467,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/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h -index 7a0fe8d..78e3a97 100644 ---- a/sysdeps/generic/ldsodefs.h -+++ b/sysdeps/generic/ldsodefs.h -@@ -592,9 +592,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__ - # if IS_IN (rtld) --- -1.9.4 - diff --git a/glibc/CVE-2015-8778.patch b/glibc/CVE-2015-8778.patch deleted file mode 100644 index fd7f3fff..00000000 --- a/glibc/CVE-2015-8778.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff --git a/misc/hsearch_r.c b/misc/hsearch_r.c -index 9f55e84..559df29 100644 ---- a/misc/hsearch_r.c -+++ b/misc/hsearch_r.c -@@ -19,7 +19,7 @@ - #include <errno.h> - #include <malloc.h> - #include <string.h> -- -+#include <stdint.h> - #include <search.h> - - /* [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986 -@@ -73,6 +73,13 @@ __hcreate_r (nel, htab) - return 0; - } - -+ if (nel >= SIZE_MAX / sizeof (_ENTRY)) -+ { -+ __set_errno (ENOMEM); -+ return 0; -+ } -+ -+ - /* There is still another table active. Return with error. */ - if (htab->table != NULL) - return 0; --- -1.9.4 diff --git a/glibc/CVE-2015-8779.patch b/glibc/CVE-2015-8779.patch deleted file mode 100644 index 7f0f49b4..00000000 --- a/glibc/CVE-2015-8779.patch +++ /dev/null @@ -1,239 +0,0 @@ -diff --git a/catgets/Makefile b/catgets/Makefile -index 4624a88..56de38b 100644 ---- a/catgets/Makefile -+++ b/catgets/Makefile -@@ -34,6 +34,7 @@ test-srcs = test-gencat - ifeq ($(run-built-tests),yes) - tests-special += $(objpfx)de/libc.cat $(objpfx)test1.cat $(objpfx)test2.cat \ - $(objpfx)sample.SJIS.cat $(objpfx)test-gencat.out -+tests-special += $(objpfx)tst-catgets-mem.out - endif - - gencat-modules = xmalloc -@@ -50,9 +51,11 @@ catgets-CPPFLAGS := -DNLSPATH='"$(msgcatdir)/%L/%N:$(msgcatdir)/%L/LC_MESSAGES/% - - generated += de.msg test1.cat test1.h test2.cat test2.h sample.SJIS.cat \ - test-gencat.h -+generated += tst-catgets.mtrace tst-catgets-mem.out -+ - generated-dirs += de - --tst-catgets-ENV = NLSPATH="$(objpfx)%l/%N.cat" LANG=de -+tst-catgets-ENV = NLSPATH="$(objpfx)%l/%N.cat" LANG=de MALLOC_TRACE=$(objpfx)tst-catgets.mtrace - - ifeq ($(run-built-tests),yes) - # This test just checks whether the program produces any error or not. -@@ -86,4 +89,8 @@ $(objpfx)test-gencat.out: test-gencat.sh $(objpfx)test-gencat \ - $(objpfx)sample.SJIS.cat: sample.SJIS $(objpfx)gencat - $(built-program-cmd) -H $(objpfx)test-gencat.h < $(word 1,$^) > $@; \ - $(evaluate-test) -+ -+$(objpfx)tst-catgets-mem.out: $(objpfx)tst-catgets.out -+ $(common-objpfx)malloc/mtrace $(objpfx)tst-catgets.mtrace > $@; \ -+ $(evaluate-test) - endif -diff --git a/catgets/catgets.c b/catgets/catgets.c -index cf93d56..4be452d 100644 ---- a/catgets/catgets.c -+++ b/catgets/catgets.c -@@ -16,7 +16,6 @@ - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - --#include <alloca.h> - #include <errno.h> - #include <locale.h> - #include <nl_types.h> -@@ -35,6 +34,7 @@ catopen (const char *cat_name, int flag) - __nl_catd result; - const char *env_var = NULL; - const char *nlspath = NULL; -+ char *tmp = NULL; - - if (strchr (cat_name, '/') == NULL) - { -@@ -54,7 +54,10 @@ catopen (const char *cat_name, int flag) - { - /* Append the system dependent directory. */ - size_t len = strlen (nlspath) + 1 + sizeof NLSPATH; -- char *tmp = alloca (len); -+ tmp = malloc (len); -+ -+ if (__glibc_unlikely (tmp == NULL)) -+ return (nl_catd) -1; - - __stpcpy (__stpcpy (__stpcpy (tmp, nlspath), ":"), NLSPATH); - nlspath = tmp; -@@ -65,16 +68,18 @@ catopen (const char *cat_name, int flag) - - result = (__nl_catd) malloc (sizeof (*result)); - if (result == NULL) -- /* We cannot get enough memory. */ -- return (nl_catd) -1; -- -- if (__open_catalog (cat_name, nlspath, env_var, result) != 0) -+ { -+ /* We cannot get enough memory. */ -+ result = (nl_catd) -1; -+ } -+ else if (__open_catalog (cat_name, nlspath, env_var, result) != 0) - { - /* Couldn't open the file. */ - free ((void *) result); -- return (nl_catd) -1; -+ result = (nl_catd) -1; - } - -+ free (tmp); - return (nl_catd) result; - } - -diff --git a/catgets/open_catalog.c b/catgets/open_catalog.c -index e069416..9f4d776 100644 ---- a/catgets/open_catalog.c -+++ b/catgets/open_catalog.c -@@ -47,6 +47,7 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var, - size_t tab_size; - const char *lastp; - int result = -1; -+ char *buf = NULL; - - if (strchr (cat_name, '/') != NULL || nlspath == NULL) - fd = open_not_cancel_2 (cat_name, O_RDONLY); -@@ -57,23 +58,23 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var, - if (__glibc_unlikely (bufact + (n) >= bufmax)) \ - { \ - char *old_buf = buf; \ -- bufmax += 256 + (n); \ -- buf = (char *) alloca (bufmax); \ -- memcpy (buf, old_buf, bufact); \ -+ bufmax += (bufmax < 256 + (n)) ? 256 + (n) : bufmax; \ -+ buf = realloc (buf, bufmax); \ -+ if (__glibc_unlikely (buf == NULL)) \ -+ { \ -+ free (old_buf); \ -+ return -1; \ -+ } \ - } - - /* The RUN_NLSPATH variable contains a colon separated list of - descriptions where we expect to find catalogs. We have to - recognize certain % substitutions and stop when we found the - first existing file. */ -- char *buf; - size_t bufact; -- size_t bufmax; -+ size_t bufmax = 0; - size_t len; - -- buf = NULL; -- bufmax = 0; -- - fd = -1; - while (*run_nlspath != '\0') - { -@@ -188,7 +189,10 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var, - - /* Avoid dealing with directories and block devices */ - if (__builtin_expect (fd, 0) < 0) -- return -1; -+ { -+ free (buf); -+ return -1; -+ } - - if (__builtin_expect (__fxstat64 (_STAT_VER, fd, &st), 0) < 0) - goto close_unlock_return; -@@ -325,6 +329,7 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var, - /* Release the lock again. */ - close_unlock_return: - close_not_cancel_no_status (fd); -+ free (buf); - - return result; - } -diff --git a/catgets/tst-catgets.c b/catgets/tst-catgets.c -index a0a4089..140de72 100644 ---- a/catgets/tst-catgets.c -+++ b/catgets/tst-catgets.c -@@ -1,7 +1,10 @@ -+#include <assert.h> - #include <mcheck.h> - #include <nl_types.h> - #include <stdio.h> -+#include <stdlib.h> - #include <string.h> -+#include <sys/resource.h> - - - static const char *msgs[] = -@@ -12,6 +15,33 @@ static const char *msgs[] = - }; - #define nmsgs (sizeof (msgs) / sizeof (msgs[0])) - -+ -+/* Test for unbounded alloca. */ -+static int -+do_bz17905 (void) -+{ -+ char *buf; -+ struct rlimit rl; -+ nl_catd result; -+ -+ const int sz = 1024 * 1024; -+ -+ getrlimit (RLIMIT_STACK, &rl); -+ rl.rlim_cur = sz; -+ setrlimit (RLIMIT_STACK, &rl); -+ -+ buf = malloc (sz + 1); -+ memset (buf, 'A', sz); -+ buf[sz] = '\0'; -+ setenv ("NLSPATH", buf, 1); -+ -+ result = catopen (buf, NL_CAT_LOCALE); -+ assert (result == (nl_catd) -1); -+ -+ free (buf); -+ return 0; -+} -+ - #define ROUNDS 5 - - static int -@@ -62,6 +92,7 @@ do_test (void) - } - } - -+ result += do_bz17905 (); - return result; - } - --- -1.9.4 - -From 7565d2a862683a3c26ffb1f32351b8c5ab9f7b31 Mon Sep 17 00:00:00 2001 -From: Paul Pluzhnikov <ppluzhnikov@google.com> -Date: Sat, 8 Aug 2015 15:54:40 -0700 -Subject: [PATCH] Fix trailing space. - ---- - catgets/tst-catgets.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/catgets/tst-catgets.c b/catgets/tst-catgets.c -index 140de72..0886938 100644 ---- a/catgets/tst-catgets.c -+++ b/catgets/tst-catgets.c -@@ -30,7 +30,7 @@ do_bz17905 (void) - rl.rlim_cur = sz; - setrlimit (RLIMIT_STACK, &rl); - -- buf = malloc (sz + 1); -+ buf = malloc (sz + 1); - memset (buf, 'A', sz); - buf[sz] = '\0'; - setenv ("NLSPATH", buf, 1); --- -1.9.4 - diff --git a/glibc/Pkgfile b/glibc/Pkgfile index d259ba52..0b7b9e99 100644 --- a/glibc/Pkgfile +++ b/glibc/Pkgfile @@ -3,9 +3,9 @@ # Maintainer: CRUX System Team, core-ports at crux dot nu name=glibc -version=2.23 +version=2.23-bbe472f release=1 -source=(http://ftp.gnu.org/gnu/glibc/glibc-$version.tar.xz \ +source=(http://crux.nu/files/glibc/glibc-$version.tar.xz \ http://crux.nu/files/distfiles/kernel-headers-4.4.14.tar.xz \ $name-2.20-multilib-dirs.patch \ hosts resolv.conf nsswitch.conf host.conf ld.so.conf) @@ -16,11 +16,11 @@ build() { cp -r $SRC/kernel-headers-4.4.14/include $PKG/usr chown root:root $PKG/usr - patch -p1 -d $SRC/$name-$version -i $SRC/$name-2.20-multilib-dirs.patch + patch -p1 -d $SRC/$name-${version:0:4} -i $SRC/$name-2.20-multilib-dirs.patch mkdir $SRC/build cd $SRC/build - ../$name-$version/configure --prefix=/usr \ + ../$name-${version:0:4}/configure --prefix=/usr \ --libexecdir=/usr/lib \ --with-headers=$PKG/usr/include \ --enable-kernel=3.12 \ @@ -35,7 +35,7 @@ build() { #make check make install_root=$PKG install - install -m 0644 $SRC/$name-$version/nscd/nscd.conf $PKG/etc + install -m 0644 $SRC/$name-${version:0:4}/nscd/nscd.conf $PKG/etc install -d $PKG/var/{db,run}/nscd install -m 0644 $SRC/{hosts,resolv.conf,nsswitch.conf,host.conf,ld.so.conf} $PKG/etc diff --git a/glibc/glibc-rh1252570.patch b/glibc/glibc-rh1252570.patch deleted file mode 100644 index 5e69e9a0..00000000 --- a/glibc/glibc-rh1252570.patch +++ /dev/null @@ -1,408 +0,0 @@ -Revert this upstream commit: - -commit 2212c1420c92a33b0e0bd9a34938c9814a56c0f7 -Author: Andreas Schwab <schwab@suse.de> -Date: Thu Feb 19 15:52:08 2015 +0100 - - Simplify handling of nameserver configuration in resolver - - Remove use of ext.nsmap member of struct __res_state and always use - an identity mapping betwen the nsaddr_list array and the ext.nsaddrs - array. The fact that a nameserver has an IPv6 address is signalled by - setting nsaddr_list[].sin_family to zero. - -reverted: -Index: b/resolv/res_init.c -=================================================================== ---- a/resolv/res_init.c -+++ b/resolv/res_init.c -@@ -153,8 +153,10 @@ __res_vinit(res_state statp, int preinit - char *cp, **pp; - int n; - char buf[BUFSIZ]; -- int nserv = 0; /* number of nameservers read from file */ -- int have_serv6 = 0; -+ 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 haveenv = 0; - int havesearch = 0; - #ifdef RESOLVSORT -@@ -183,9 +185,15 @@ __res_vinit(res_state statp, int preinit - statp->_flags = 0; - statp->qhook = NULL; - statp->rhook = NULL; -+ statp->_u._ext.nsinit = 0; - statp->_u._ext.nscount = 0; -- for (n = 0; n < MAXNS; n++) -- statp->_u._ext.nsaddrs[n] = NULL; -+#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 - - /* Allow user to override the local domain definition */ - if ((cp = getenv("LOCALDOMAIN")) != NULL) { -@@ -289,7 +297,11 @@ __res_vinit(res_state statp, int preinit - 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; -@@ -297,12 +309,13 @@ __res_vinit(res_state statp, int preinit - cp++; - if ((*cp != '\0') && (*cp != '\n') - && __inet_aton(cp, &a)) { -- statp->nsaddr_list[nserv].sin_addr = a; -- statp->nsaddr_list[nserv].sin_family = AF_INET; -- statp->nsaddr_list[nserv].sin_port = -+ statp->nsaddr_list[nservall].sin_addr = a; -+ statp->nsaddr_list[nservall].sin_family = AF_INET; -+ statp->nsaddr_list[nservall].sin_port = - htons(NAMESERVER_PORT); - nserv++; - #ifdef _LIBC -+ nservall++; - } else { - struct in6_addr a6; - char *el; -@@ -344,11 +357,10 @@ __res_vinit(res_state statp, int preinit - } - } - -- statp->nsaddr_list[nserv].sin_family = 0; -- statp->_u._ext.nsaddrs[nserv] = sa6; -- statp->_u._ext.nssocks[nserv] = -1; -- have_serv6 = 1; -- nserv++; -+ statp->_u._ext.nsaddrs[nservall] = sa6; -+ statp->_u._ext.nssocks[nservall] = -1; -+ statp->_u._ext.nsmap[nservall] = MAXNS + 1; -+ nservall++; - } - } - #endif -@@ -403,9 +415,10 @@ __res_vinit(res_state statp, int preinit - continue; - } - } -- statp->nscount = nserv; -+ statp->nscount = nservall; - #ifdef _LIBC -- if (have_serv6) { -+ if (nservall - nserv > 0) { -+ statp->_u._ext.nscount6 = nservall - nserv; - /* We try IPv6 servers again. */ - statp->ipv6_unavail = false; - } -@@ -594,7 +607,11 @@ __res_iclose(res_state statp, bool free_ - 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]); -@@ -605,6 +622,8 @@ __res_iclose(res_state statp, bool free_ - statp->_u._ext.nsaddrs[ns] = NULL; - } - } -+ if (free_addr) -+ statp->_u._ext.nsinit = 0; - } - libc_hidden_def (__res_iclose) - -Index: b/resolv/res_send.c -=================================================================== ---- a/resolv/res_send.c -+++ b/resolv/res_send.c -@@ -176,7 +176,6 @@ evNowTime(struct timespec *res) { - - /* 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 **, -@@ -214,21 +213,20 @@ res_ourserver_p(const res_state statp, c - in_port_t port = in4p->sin_port; - in_addr_t addr = in4p->sin_addr.s_addr; - -- for (ns = 0; ns < statp->nscount; ns++) { -+ for (ns = 0; ns < MAXNS; ns++) { - const struct sockaddr_in *srv = -- (struct sockaddr_in *) get_nsaddr (statp, ns); -+ (struct sockaddr_in *)EXT(statp).nsaddrs[ns]; - -- if ((srv->sin_family == AF_INET) && -+ if ((srv != NULL) && (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 < statp->nscount; ns++) { -- const struct sockaddr_in6 *srv -- = (struct sockaddr_in6 *) get_nsaddr (statp, ns); -- if ((srv->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) && - (srv->sin6_port == inp->sin6_port) && - !(memcmp(&srv->sin6_addr, &in6addr_any, - sizeof (struct in6_addr)) && -@@ -378,48 +376,80 @@ __libc_res_nsend(res_state statp, const - * If the ns_addr_list in the resolver context has changed, then - * invalidate our cached copy and the associated timing data. - */ -- if (EXT(statp).nscount != 0) { -+ if (EXT(statp).nsinit) { - int needclose = 0; - - if (EXT(statp).nscount != statp->nscount) - needclose++; - else -- for (ns = 0; ns < statp->nscount; ns++) { -- if (statp->nsaddr_list[ns].sin_family != 0 -+ for (ns = 0; ns < MAXNS; ns++) { -+ unsigned int map = EXT(statp).nsmap[ns]; -+ if (map < MAXNS - && !sock_eq((struct sockaddr_in6 *) -- &statp->nsaddr_list[ns], -+ &statp->nsaddr_list[map], - 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).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] = -+ 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; -+ /* NS never exceeds MAXNS, but gcc 4.9 somehow -+ does not see this. */ -+ DIAG_PUSH_NEEDS_COMMENT; -+ DIAG_IGNORE_NEEDS_COMMENT (4.9, -+ "-Warray-bounds"); -+ EXT(statp).nsmap[ns] = n; -+ DIAG_POP_NEEDS_COMMENT; -+ 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] = - malloc(sizeof (struct sockaddr_in6)); -- if (EXT(statp).nsaddrs[ns] != NULL) -- memset (mempcpy(EXT(statp).nsaddrs[ns], -+ if (EXT(statp).nsaddrs[n] != NULL) { -+ memset (mempcpy(EXT(statp).nsaddrs[n], - &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).nscount = statp->nscount; -+ EXT(statp).nsinit = 1; - } - - /* -@@ -428,37 +458,44 @@ __libc_res_nsend(res_state statp, const - */ - if (__builtin_expect ((statp->options & RES_ROTATE) != 0, 0) && - (statp->options & RES_BLAST) == 0) { -- 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; -+ 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; -+ } - } - - /* - * Send request, RETRY times, or until successful. - */ - for (try = 0; try < statp->retry; try++) { -- for (ns = 0; ns < statp->nscount; ns++) -+ for (ns = 0; ns < MAXNS; ns++) - { - #ifdef DEBUG - char tmpbuf[40]; - #endif --#if defined USE_HOOKS || defined DEBUG -- struct sockaddr *nsap = get_nsaddr (statp, ns); --#endif -+ struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns]; - -+ if (nsap == NULL) -+ goto next_ns; - same_ns: - #ifdef USE_HOOKS - if (__glibc_unlikely (statp->qhook != NULL)) { -@@ -615,21 +652,6 @@ libresolv_hidden_def (res_nsend) - - /* 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]; --} -- - static int - send_vc(res_state statp, - const u_char *buf, int buflen, const u_char *buf2, int buflen2, -@@ -644,7 +666,7 @@ send_vc(res_state statp, - // XXX REMOVE - // int anssiz = *anssizp; - HEADER *anhp = (HEADER *) ans; -- struct sockaddr *nsap = get_nsaddr (statp, ns); -+ struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns]; - int truncating, connreset, n; - /* On some architectures compiler might emit a warning indicating - 'resplen' may be used uninitialized. However if buf2 == NULL -@@ -677,8 +699,8 @@ send_vc(res_state statp, - - if (getpeername(statp->_vcsock, - (struct sockaddr *)&peer, &size) < 0 || -- !sock_eq(&peer, (struct sockaddr_in6 *) nsap)) { -- __res_iclose(statp, false); -+ !sock_eq(&peer, nsap)) { -+ __res_iclose(statp, false); - statp->_flags &= ~RES_F_VC; - } - } -@@ -687,19 +709,20 @@ send_vc(res_state statp, - if (statp->_vcsock >= 0) - __res_iclose(statp, false); - -- statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM, 0); -+ statp->_vcsock = socket(nsap->sin6_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, nsap, -- nsap->sa_family == AF_INET -+ if (connect(statp->_vcsock, (struct sockaddr *)nsap, -+ nsap->sin6_family == AF_INET - ? sizeof (struct sockaddr_in) - : sizeof (struct sockaddr_in6)) < 0) { - *terrno = errno; -- Aerror(statp, stderr, "connect/vc", errno, nsap); -+ Aerror(statp, stderr, "connect/vc", errno, -+ (struct sockaddr *) nsap); - __res_iclose(statp, false); - return (0); - } -@@ -906,7 +929,8 @@ static int - reopen (res_state statp, int *terrno, int ns) - { - if (EXT(statp).nssocks[ns] == -1) { -- struct sockaddr *nsap = get_nsaddr (statp, ns); -+ struct sockaddr *nsap -+ = (struct sockaddr *) EXT(statp).nsaddrs[ns]; - socklen_t slen; - - /* only try IPv6 if IPv6 NS and if not failed before */ |