summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/recipes-core/glibc/glibc/CVE-2015-7547.patch583
-rw-r--r--meta/recipes-core/glibc/glibc_2.20.bb1
2 files changed, 584 insertions, 0 deletions
diff --git a/meta/recipes-core/glibc/glibc/CVE-2015-7547.patch b/meta/recipes-core/glibc/glibc/CVE-2015-7547.patch
new file mode 100644
index 0000000000..d877408dad
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/CVE-2015-7547.patch
@@ -0,0 +1,583 @@
1From e9db92d3acfe1822d56d11abcea5bfc4c41cf6ca Mon Sep 17 00:00:00 2001
2From: Carlos O'Donell <carlos@systemhalted.org>
3Date: Tue, 16 Feb 2016 21:26:37 -0500
4Subject: [PATCH] CVE-2015-7547: getaddrinfo() stack-based buffer overflow (Bug
5 18665).
6
7* A stack-based buffer overflow was found in libresolv when invoked from
8 libnss_dns, allowing specially crafted DNS responses to seize control
9 of execution flow in the DNS client. The buffer overflow occurs in
10 the functions send_dg (send datagram) and send_vc (send TCP) for the
11 NSS module libnss_dns.so.2 when calling getaddrinfo with AF_UNSPEC
12 family. The use of AF_UNSPEC triggers the low-level resolver code to
13 send out two parallel queries for A and AAAA. A mismanagement of the
14 buffers used for those queries could result in the response of a query
15 writing beyond the alloca allocated buffer created by
16 _nss_dns_gethostbyname4_r. Buffer management is simplified to remove
17 the overflow. Thanks to the Google Security Team and Red Hat for
18 reporting the security impact of this issue, and Robert Holiday of
19 Ciena for reporting the related bug 18665. (CVE-2015-7547)
20
21See also:
22https://sourceware.org/ml/libc-alpha/2016-02/msg00416.html
23https://sourceware.org/ml/libc-alpha/2016-02/msg00418.html
24
25Upstream-Status: Backport
26CVE: CVE-2015-7547
27
28https://sourceware.org/git/?p=glibc.git;a=commit;h=e9db92d3acfe1822d56d11abcea5bfc4c41cf6ca
29minor tweaking to remove Changelog and NEWS
30
31---
32 resolv/nss_dns/dns-host.c | 111 +++++++++++++++++++-
33 resolv/res_query.c | 3 +
34 resolv/res_send.c | 260 +++++++++++++++++++++++++++++++++++-----------
35 3 files changed, 339 insertions(+), 66 deletions(-)
36
37diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
38index 3258e70..755832e 100644
39--- a/resolv/nss_dns/dns-host.c
40+++ b/resolv/nss_dns/dns-host.c
41@@ -1031,7 +1031,10 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
42 int h_namelen = 0;
43
44 if (ancount == 0)
45- return NSS_STATUS_NOTFOUND;
46+ {
47+ *h_errnop = HOST_NOT_FOUND;
48+ return NSS_STATUS_NOTFOUND;
49+ }
50
51 while (ancount-- > 0 && cp < end_of_message && had_error == 0)
52 {
53@@ -1208,7 +1211,14 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
54 /* Special case here: if the resolver sent a result but it only
55 contains a CNAME while we are looking for a T_A or T_AAAA record,
56 we fail with NOTFOUND instead of TRYAGAIN. */
57- return canon == NULL ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
58+ if (canon != NULL)
59+ {
60+ *h_errnop = HOST_NOT_FOUND;
61+ return NSS_STATUS_NOTFOUND;
62+ }
63+
64+ *h_errnop = NETDB_INTERNAL;
65+ return NSS_STATUS_TRYAGAIN;
66 }
67
68
69@@ -1222,11 +1232,101 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
70
71 enum nss_status status = NSS_STATUS_NOTFOUND;
72
73+ /* Combining the NSS status of two distinct queries requires some
74+ compromise and attention to symmetry (A or AAAA queries can be
75+ returned in any order). What follows is a breakdown of how this
76+ code is expected to work and why. We discuss only SUCCESS,
77+ TRYAGAIN, NOTFOUND and UNAVAIL, since they are the only returns
78+ that apply (though RETURN and MERGE exist). We make a distinction
79+ between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable).
80+ A recoverable TRYAGAIN is almost always due to buffer size issues
81+ and returns ERANGE in errno and the caller is expected to retry
82+ with a larger buffer.
83+
84+ Lastly, you may be tempted to make significant changes to the
85+ conditions in this code to bring about symmetry between responses.
86+ Please don't change anything without due consideration for
87+ expected application behaviour. Some of the synthesized responses
88+ aren't very well thought out and sometimes appear to imply that
89+ IPv4 responses are always answer 1, and IPv6 responses are always
90+ answer 2, but that's not true (see the implementation of send_dg
91+ and send_vc to see response can arrive in any order, particularly
92+ for UDP). However, we expect it holds roughly enough of the time
93+ that this code works, but certainly needs to be fixed to make this
94+ a more robust implementation.
95+
96+ ----------------------------------------------
97+ | Answer 1 Status / | Synthesized | Reason |
98+ | Answer 2 Status | Status | |
99+ |--------------------------------------------|
100+ | SUCCESS/SUCCESS | SUCCESS | [1] |
101+ | SUCCESS/TRYAGAIN | TRYAGAIN | [5] |
102+ | SUCCESS/TRYAGAIN' | SUCCESS | [1] |
103+ | SUCCESS/NOTFOUND | SUCCESS | [1] |
104+ | SUCCESS/UNAVAIL | SUCCESS | [1] |
105+ | TRYAGAIN/SUCCESS | TRYAGAIN | [2] |
106+ | TRYAGAIN/TRYAGAIN | TRYAGAIN | [2] |
107+ | TRYAGAIN/TRYAGAIN' | TRYAGAIN | [2] |
108+ | TRYAGAIN/NOTFOUND | TRYAGAIN | [2] |
109+ | TRYAGAIN/UNAVAIL | TRYAGAIN | [2] |
110+ | TRYAGAIN'/SUCCESS | SUCCESS | [3] |
111+ | TRYAGAIN'/TRYAGAIN | TRYAGAIN | [3] |
112+ | TRYAGAIN'/TRYAGAIN' | TRYAGAIN' | [3] |
113+ | TRYAGAIN'/NOTFOUND | TRYAGAIN' | [3] |
114+ | TRYAGAIN'/UNAVAIL | UNAVAIL | [3] |
115+ | NOTFOUND/SUCCESS | SUCCESS | [3] |
116+ | NOTFOUND/TRYAGAIN | TRYAGAIN | [3] |
117+ | NOTFOUND/TRYAGAIN' | TRYAGAIN' | [3] |
118+ | NOTFOUND/NOTFOUND | NOTFOUND | [3] |
119+ | NOTFOUND/UNAVAIL | UNAVAIL | [3] |
120+ | UNAVAIL/SUCCESS | UNAVAIL | [4] |
121+ | UNAVAIL/TRYAGAIN | UNAVAIL | [4] |
122+ | UNAVAIL/TRYAGAIN' | UNAVAIL | [4] |
123+ | UNAVAIL/NOTFOUND | UNAVAIL | [4] |
124+ | UNAVAIL/UNAVAIL | UNAVAIL | [4] |
125+ ----------------------------------------------
126+
127+ [1] If the first response is a success we return success.
128+ This ignores the state of the second answer and in fact
129+ incorrectly sets errno and h_errno to that of the second
130+ answer. However because the response is a success we ignore
131+ *errnop and *h_errnop (though that means you touched errno on
132+ success). We are being conservative here and returning the
133+ likely IPv4 response in the first answer as a success.
134+
135+ [2] If the first response is a recoverable TRYAGAIN we return
136+ that instead of looking at the second response. The
137+ expectation here is that we have failed to get an IPv4 response
138+ and should retry both queries.
139+
140+ [3] If the first response was not a SUCCESS and the second
141+ response is not NOTFOUND (had a SUCCESS, need to TRYAGAIN,
142+ or failed entirely e.g. TRYAGAIN' and UNAVAIL) then use the
143+ result from the second response, otherwise the first responses
144+ status is used. Again we have some odd side-effects when the
145+ second response is NOTFOUND because we overwrite *errnop and
146+ *h_errnop that means that a first answer of NOTFOUND might see
147+ its *errnop and *h_errnop values altered. Whether it matters
148+ in practice that a first response NOTFOUND has the wrong
149+ *errnop and *h_errnop is undecided.
150+
151+ [4] If the first response is UNAVAIL we return that instead of
152+ looking at the second response. The expectation here is that
153+ it will have failed similarly e.g. configuration failure.
154+
155+ [5] Testing this code is complicated by the fact that truncated
156+ second response buffers might be returned as SUCCESS if the
157+ first answer is a SUCCESS. To fix this we add symmetry to
158+ TRYAGAIN with the second response. If the second response
159+ is a recoverable error we now return TRYAGIN even if the first
160+ response was SUCCESS. */
161+
162 if (anslen1 > 0)
163 status = gaih_getanswer_slice(answer1, anslen1, qname,
164 &pat, &buffer, &buflen,
165 errnop, h_errnop, ttlp,
166 &first);
167+
168 if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
169 || (status == NSS_STATUS_TRYAGAIN
170 /* We want to look at the second answer in case of an
171@@ -1242,8 +1342,15 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
172 &pat, &buffer, &buflen,
173 errnop, h_errnop, ttlp,
174 &first);
175+ /* Use the second response status in some cases. */
176 if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND)
177 status = status2;
178+ /* Do not return a truncated second response (unless it was
179+ unavoidable e.g. unrecoverable TRYAGAIN). */
180+ if (status == NSS_STATUS_SUCCESS
181+ && (status2 == NSS_STATUS_TRYAGAIN
182+ && *errnop == ERANGE && *h_errnop != NO_RECOVERY))
183+ status = NSS_STATUS_TRYAGAIN;
184 }
185
186 return status;
187diff --git a/resolv/res_query.c b/resolv/res_query.c
188index e4ee2a6..616fd57 100644
189--- a/resolv/res_query.c
190+++ b/resolv/res_query.c
191@@ -396,6 +396,7 @@ __libc_res_nsearch(res_state statp,
192 {
193 free (*answerp2);
194 *answerp2 = NULL;
195+ *nanswerp2 = 0;
196 *answerp2_malloced = 0;
197 }
198 }
199@@ -436,6 +437,7 @@ __libc_res_nsearch(res_state statp,
200 {
201 free (*answerp2);
202 *answerp2 = NULL;
203+ *nanswerp2 = 0;
204 *answerp2_malloced = 0;
205 }
206
207@@ -510,6 +512,7 @@ __libc_res_nsearch(res_state statp,
208 {
209 free (*answerp2);
210 *answerp2 = NULL;
211+ *nanswerp2 = 0;
212 *answerp2_malloced = 0;
213 }
214 if (saved_herrno != -1)
215diff --git a/resolv/res_send.c b/resolv/res_send.c
216index af42b8a..5f9f0e7 100644
217--- a/resolv/res_send.c
218+++ b/resolv/res_send.c
219@@ -1,3 +1,20 @@
220+/* Copyright (C) 2016 Free Software Foundation, Inc.
221+ This file is part of the GNU C Library.
222+
223+ The GNU C Library is free software; you can redistribute it and/or
224+ modify it under the terms of the GNU Lesser General Public
225+ License as published by the Free Software Foundation; either
226+ version 2.1 of the License, or (at your option) any later version.
227+
228+ The GNU C Library is distributed in the hope that it will be useful,
229+ but WITHOUT ANY WARRANTY; without even the implied warranty of
230+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
231+ Lesser General Public License for more details.
232+
233+ You should have received a copy of the GNU Lesser General Public
234+ License along with the GNU C Library; if not, see
235+ <http://www.gnu.org/licenses/>. */
236+
237 /*
238 * Copyright (c) 1985, 1989, 1993
239 * The Regents of the University of California. All rights reserved.
240@@ -360,6 +377,8 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
241 #ifdef USE_HOOKS
242 if (__glibc_unlikely (statp->qhook || statp->rhook)) {
243 if (anssiz < MAXPACKET && ansp) {
244+ /* Always allocate MAXPACKET, callers expect
245+ this specific size. */
246 u_char *buf = malloc (MAXPACKET);
247 if (buf == NULL)
248 return (-1);
249@@ -653,6 +672,77 @@ libresolv_hidden_def (res_nsend)
250
251 /* Private */
252
253+/* The send_vc function is responsible for sending a DNS query over TCP
254+ to the nameserver numbered NS from the res_state STATP i.e.
255+ EXT(statp).nssocks[ns]. The function supports sending both IPv4 and
256+ IPv6 queries at the same serially on the same socket.
257+
258+ Please note that for TCP there is no way to disable sending both
259+ queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP
260+ and sends the queries serially and waits for the result after each
261+ sent query. This implemetnation should be corrected to honour these
262+ options.
263+
264+ Please also note that for TCP we send both queries over the same
265+ socket one after another. This technically violates best practice
266+ since the server is allowed to read the first query, respond, and
267+ then close the socket (to service another client). If the server
268+ does this, then the remaining second query in the socket data buffer
269+ will cause the server to send the client an RST which will arrive
270+ asynchronously and the client's OS will likely tear down the socket
271+ receive buffer resulting in a potentially short read and lost
272+ response data. This will force the client to retry the query again,
273+ and this process may repeat until all servers and connection resets
274+ are exhausted and then the query will fail. It's not known if this
275+ happens with any frequency in real DNS server implementations. This
276+ implementation should be corrected to use two sockets by default for
277+ parallel queries.
278+
279+ The query stored in BUF of BUFLEN length is sent first followed by
280+ the query stored in BUF2 of BUFLEN2 length. Queries are sent
281+ serially on the same socket.
282+
283+ Answers to the query are stored firstly in *ANSP up to a max of
284+ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
285+ is non-NULL (to indicate that modifying the answer buffer is allowed)
286+ then malloc is used to allocate a new response buffer and ANSCP and
287+ ANSP will both point to the new buffer. If more than *ANSSIZP bytes
288+ are needed but ANSCP is NULL, then as much of the response as
289+ possible is read into the buffer, but the results will be truncated.
290+ When truncation happens because of a small answer buffer the DNS
291+ packets header field TC will bet set to 1, indicating a truncated
292+ message and the rest of the socket data will be read and discarded.
293+
294+ Answers to the query are stored secondly in *ANSP2 up to a max of
295+ *ANSSIZP2 bytes, with the actual response length stored in
296+ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
297+ is non-NULL (required for a second query) then malloc is used to
298+ allocate a new response buffer, *ANSSIZP2 is set to the new buffer
299+ size and *ANSP2_MALLOCED is set to 1.
300+
301+ The ANSP2_MALLOCED argument will eventually be removed as the
302+ change in buffer pointer can be used to detect the buffer has
303+ changed and that the caller should use free on the new buffer.
304+
305+ Note that the answers may arrive in any order from the server and
306+ therefore the first and second answer buffers may not correspond to
307+ the first and second queries.
308+
309+ It is not supported to call this function with a non-NULL ANSP2
310+ but a NULL ANSCP. Put another way, you can call send_vc with a
311+ single unmodifiable buffer or two modifiable buffers, but no other
312+ combination is supported.
313+
314+ It is the caller's responsibility to free the malloc allocated
315+ buffers by detecting that the pointers have changed from their
316+ original values i.e. *ANSCP or *ANSP2 has changed.
317+
318+ If errors are encountered then *TERRNO is set to an appropriate
319+ errno value and a zero result is returned for a recoverable error,
320+ and a less-than zero result is returned for a non-recoverable error.
321+
322+ If no errors are encountered then *TERRNO is left unmodified and
323+ a the length of the first response in bytes is returned. */
324 static int
325 send_vc(res_state statp,
326 const u_char *buf, int buflen, const u_char *buf2, int buflen2,
327@@ -662,11 +752,7 @@ send_vc(res_state statp,
328 {
329 const HEADER *hp = (HEADER *) buf;
330 const HEADER *hp2 = (HEADER *) buf2;
331- u_char *ans = *ansp;
332- int orig_anssizp = *anssizp;
333- // XXX REMOVE
334- // int anssiz = *anssizp;
335- HEADER *anhp = (HEADER *) ans;
336+ HEADER *anhp = (HEADER *) *ansp;
337 struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns];
338 int truncating, connreset, resplen, n;
339 struct iovec iov[4];
340@@ -742,6 +828,8 @@ send_vc(res_state statp,
341 * Receive length & response
342 */
343 int recvresp1 = 0;
344+ /* Skip the second response if there is no second query.
345+ To do that we mark the second response as received. */
346 int recvresp2 = buf2 == NULL;
347 uint16_t rlen16;
348 read_len:
349@@ -778,33 +866,14 @@ send_vc(res_state statp,
350 u_char **thisansp;
351 int *thisresplenp;
352 if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
353+ /* We have not received any responses
354+ yet or we only have one response to
355+ receive. */
356 thisanssizp = anssizp;
357 thisansp = anscp ?: ansp;
358 assert (anscp != NULL || ansp2 == NULL);
359 thisresplenp = &resplen;
360 } else {
361- if (*anssizp != MAXPACKET) {
362- /* No buffer allocated for the first
363- reply. We can try to use the rest
364- of the user-provided buffer. */
365-#if _STRING_ARCH_unaligned
366- *anssizp2 = orig_anssizp - resplen;
367- *ansp2 = *ansp + resplen;
368-#else
369- int aligned_resplen
370- = ((resplen + __alignof__ (HEADER) - 1)
371- & ~(__alignof__ (HEADER) - 1));
372- *anssizp2 = orig_anssizp - aligned_resplen;
373- *ansp2 = *ansp + aligned_resplen;
374-#endif
375- } else {
376- /* The first reply did not fit into the
377- user-provided buffer. Maybe the second
378- answer will. */
379- *anssizp2 = orig_anssizp;
380- *ansp2 = *ansp;
381- }
382-
383 thisanssizp = anssizp2;
384 thisansp = ansp2;
385 thisresplenp = resplen2;
386@@ -812,10 +881,14 @@ send_vc(res_state statp,
387 anhp = (HEADER *) *thisansp;
388
389 *thisresplenp = rlen;
390- if (rlen > *thisanssizp) {
391- /* Yes, we test ANSCP here. If we have two buffers
392- both will be allocatable. */
393- if (__glibc_likely (anscp != NULL)) {
394+ /* Is the answer buffer too small? */
395+ if (*thisanssizp < rlen) {
396+ /* If the current buffer is not the the static
397+ user-supplied buffer then we can reallocate
398+ it. */
399+ if (thisansp != NULL && thisansp != ansp) {
400+ /* Always allocate MAXPACKET, callers expect
401+ this specific size. */
402 u_char *newp = malloc (MAXPACKET);
403 if (newp == NULL) {
404 *terrno = ENOMEM;
405@@ -827,6 +900,9 @@ send_vc(res_state statp,
406 if (thisansp == ansp2)
407 *ansp2_malloced = 1;
408 anhp = (HEADER *) newp;
409+ /* A uint16_t can't be larger than MAXPACKET
410+ thus it's safe to allocate MAXPACKET but
411+ read RLEN bytes instead. */
412 len = rlen;
413 } else {
414 Dprint(statp->options & RES_DEBUG,
415@@ -990,6 +1066,66 @@ reopen (res_state statp, int *terrno, int ns)
416 return 1;
417 }
418
419+/* The send_dg function is responsible for sending a DNS query over UDP
420+ to the nameserver numbered NS from the res_state STATP i.e.
421+ EXT(statp).nssocks[ns]. The function supports IPv4 and IPv6 queries
422+ along with the ability to send the query in parallel for both stacks
423+ (default) or serially (RES_SINGLKUP). It also supports serial lookup
424+ with a close and reopen of the socket used to talk to the server
425+ (RES_SNGLKUPREOP) to work around broken name servers.
426+
427+ The query stored in BUF of BUFLEN length is sent first followed by
428+ the query stored in BUF2 of BUFLEN2 length. Queries are sent
429+ in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP).
430+
431+ Answers to the query are stored firstly in *ANSP up to a max of
432+ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
433+ is non-NULL (to indicate that modifying the answer buffer is allowed)
434+ then malloc is used to allocate a new response buffer and ANSCP and
435+ ANSP will both point to the new buffer. If more than *ANSSIZP bytes
436+ are needed but ANSCP is NULL, then as much of the response as
437+ possible is read into the buffer, but the results will be truncated.
438+ When truncation happens because of a small answer buffer the DNS
439+ packets header field TC will bet set to 1, indicating a truncated
440+ message, while the rest of the UDP packet is discarded.
441+
442+ Answers to the query are stored secondly in *ANSP2 up to a max of
443+ *ANSSIZP2 bytes, with the actual response length stored in
444+ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
445+ is non-NULL (required for a second query) then malloc is used to
446+ allocate a new response buffer, *ANSSIZP2 is set to the new buffer
447+ size and *ANSP2_MALLOCED is set to 1.
448+
449+ The ANSP2_MALLOCED argument will eventually be removed as the
450+ change in buffer pointer can be used to detect the buffer has
451+ changed and that the caller should use free on the new buffer.
452+
453+ Note that the answers may arrive in any order from the server and
454+ therefore the first and second answer buffers may not correspond to
455+ the first and second queries.
456+
457+ It is not supported to call this function with a non-NULL ANSP2
458+ but a NULL ANSCP. Put another way, you can call send_vc with a
459+ single unmodifiable buffer or two modifiable buffers, but no other
460+ combination is supported.
461+
462+ It is the caller's responsibility to free the malloc allocated
463+ buffers by detecting that the pointers have changed from their
464+ original values i.e. *ANSCP or *ANSP2 has changed.
465+
466+ If an answer is truncated because of UDP datagram DNS limits then
467+ *V_CIRCUIT is set to 1 and the return value non-zero to indicate to
468+ the caller to retry with TCP. The value *GOTSOMEWHERE is set to 1
469+ if any progress was made reading a response from the nameserver and
470+ is used by the caller to distinguish between ECONNREFUSED and
471+ ETIMEDOUT (the latter if *GOTSOMEWHERE is 1).
472+
473+ If errors are encountered then *TERRNO is set to an appropriate
474+ errno value and a zero result is returned for a recoverable error,
475+ and a less-than zero result is returned for a non-recoverable error.
476+
477+ If no errors are encountered then *TERRNO is left unmodified and
478+ a the length of the first response in bytes is returned. */
479 static int
480 send_dg(res_state statp,
481 const u_char *buf, int buflen, const u_char *buf2, int buflen2,
482@@ -999,8 +1135,6 @@ send_dg(res_state statp,
483 {
484 const HEADER *hp = (HEADER *) buf;
485 const HEADER *hp2 = (HEADER *) buf2;
486- u_char *ans = *ansp;
487- int orig_anssizp = *anssizp;
488 struct timespec now, timeout, finish;
489 struct pollfd pfd[1];
490 int ptimeout;
491@@ -1033,6 +1167,8 @@ send_dg(res_state statp,
492 int need_recompute = 0;
493 int nwritten = 0;
494 int recvresp1 = 0;
495+ /* Skip the second response if there is no second query.
496+ To do that we mark the second response as received. */
497 int recvresp2 = buf2 == NULL;
498 pfd[0].fd = EXT(statp).nssocks[ns];
499 pfd[0].events = POLLOUT;
500@@ -1196,55 +1332,56 @@ send_dg(res_state statp,
501 int *thisresplenp;
502
503 if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
504+ /* We have not received any responses
505+ yet or we only have one response to
506+ receive. */
507 thisanssizp = anssizp;
508 thisansp = anscp ?: ansp;
509 assert (anscp != NULL || ansp2 == NULL);
510 thisresplenp = &resplen;
511 } else {
512- if (*anssizp != MAXPACKET) {
513- /* No buffer allocated for the first
514- reply. We can try to use the rest
515- of the user-provided buffer. */
516-#if _STRING_ARCH_unaligned
517- *anssizp2 = orig_anssizp - resplen;
518- *ansp2 = *ansp + resplen;
519-#else
520- int aligned_resplen
521- = ((resplen + __alignof__ (HEADER) - 1)
522- & ~(__alignof__ (HEADER) - 1));
523- *anssizp2 = orig_anssizp - aligned_resplen;
524- *ansp2 = *ansp + aligned_resplen;
525-#endif
526- } else {
527- /* The first reply did not fit into the
528- user-provided buffer. Maybe the second
529- answer will. */
530- *anssizp2 = orig_anssizp;
531- *ansp2 = *ansp;
532- }
533-
534 thisanssizp = anssizp2;
535 thisansp = ansp2;
536 thisresplenp = resplen2;
537 }
538
539 if (*thisanssizp < MAXPACKET
540- /* Yes, we test ANSCP here. If we have two buffers
541- both will be allocatable. */
542- && anscp
543+ /* If the current buffer is not the the static
544+ user-supplied buffer then we can reallocate
545+ it. */
546+ && (thisansp != NULL && thisansp != ansp)
547 #ifdef FIONREAD
548+ /* Is the size too small? */
549 && (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0
550 || *thisanssizp < *thisresplenp)
551 #endif
552 ) {
553+ /* Always allocate MAXPACKET, callers expect
554+ this specific size. */
555 u_char *newp = malloc (MAXPACKET);
556 if (newp != NULL) {
557- *anssizp = MAXPACKET;
558- *thisansp = ans = newp;
559+ *thisanssizp = MAXPACKET;
560+ *thisansp = newp;
561 if (thisansp == ansp2)
562 *ansp2_malloced = 1;
563 }
564 }
565+ /* We could end up with truncation if anscp was NULL
566+ (not allowed to change caller's buffer) and the
567+ response buffer size is too small. This isn't a
568+ reliable way to detect truncation because the ioctl
569+ may be an inaccurate report of the UDP message size.
570+ Therefore we use this only to issue debug output.
571+ To do truncation accurately with UDP we need
572+ MSG_TRUNC which is only available on Linux. We
573+ can abstract out the Linux-specific feature in the
574+ future to detect truncation. */
575+ if (__glibc_unlikely (*thisanssizp < *thisresplenp)) {
576+ Dprint(statp->options & RES_DEBUG,
577+ (stdout, ";; response may be truncated (UDP)\n")
578+ );
579+ }
580+
581 HEADER *anhp = (HEADER *) *thisansp;
582 socklen_t fromlen = sizeof(struct sockaddr_in6);
583 assert (sizeof(from) <= fromlen);
diff --git a/meta/recipes-core/glibc/glibc_2.20.bb b/meta/recipes-core/glibc/glibc_2.20.bb
index bfd8c6489f..a928293ed4 100644
--- a/meta/recipes-core/glibc/glibc_2.20.bb
+++ b/meta/recipes-core/glibc/glibc_2.20.bb
@@ -47,6 +47,7 @@ CVEPATCHES = "\
47 file://CVE-2014-9402_endless-loop-in-getaddr_r.patch \ 47 file://CVE-2014-9402_endless-loop-in-getaddr_r.patch \
48 file://CVE-2015-1781-resolv-nss_dns-dns-host.c-buffer-overf.patch \ 48 file://CVE-2015-1781-resolv-nss_dns-dns-host.c-buffer-overf.patch \
49 file://CVE-2015-1472-wscanf-allocates-too-little-memory.patch \ 49 file://CVE-2015-1472-wscanf-allocates-too-little-memory.patch \
50 file://CVE-2015-7547.patch \
50 " 51 "
51LIC_FILES_CHKSUM = "file://LICENSES;md5=e9a558e243b36d3209f380deb394b213 \ 52LIC_FILES_CHKSUM = "file://LICENSES;md5=e9a558e243b36d3209f380deb394b213 \
52 file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \ 53 file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \