CRUX-ARM : Home

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