]> git.ipfire.org Git - people/mlorenz/ipfire-2.x.git/blob - src/patches/glibc/glibc-rh1296031.patch
c430abba1f2aa275d00e8fac2acfb2c818622d18
[people/mlorenz/ipfire-2.x.git] / src / patches / glibc / glibc-rh1296031.patch
1 Index: glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-host.c
2 ===================================================================
3 --- glibc-2.12-2-gc4ccff1.orig/resolv/nss_dns/dns-host.c
4 +++ glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-host.c
5 @@ -1043,7 +1043,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 @@ -1217,7 +1220,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 @@ -1231,11 +1241,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 && (*errnop != ERANGE || *h_errnop == NO_RECOVERY)))
135 @@ -1245,8 +1345,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: glibc-2.12-2-gc4ccff1/resolv/res_send.c
152 ===================================================================
153 --- glibc-2.12-2-gc4ccff1.orig/resolv/res_send.c
154 +++ glibc-2.12-2-gc4ccff1/resolv/res_send.c
155 @@ -1,3 +1,20 @@
156 +/* Copyright (C) 2016 Free Software Foundation, Inc.
157 + This file is part of the GNU C Library.
158 +
159 + The GNU C Library is free software; you can redistribute it and/or
160 + modify it under the terms of the GNU Lesser General Public
161 + License as published by the Free Software Foundation; either
162 + version 2.1 of the License, or (at your option) any later version.
163 +
164 + The GNU C Library is distributed in the hope that it will be useful,
165 + but WITHOUT ANY WARRANTY; without even the implied warranty of
166 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
167 + Lesser General Public License for more details.
168 +
169 + You should have received a copy of the GNU Lesser General Public
170 + License along with the GNU C Library; if not, see
171 + <http://www.gnu.org/licenses/>. */
172 +
173 /*
174 * Copyright (c) 1985, 1989, 1993
175 * The Regents of the University of California. All rights reserved.
176 @@ -360,6 +377,8 @@ __libc_res_nsend(res_state statp, const
177 #ifdef USE_HOOKS
178 if (__builtin_expect (statp->qhook || statp->rhook, 0)) {
179 if (anssiz < MAXPACKET && ansp) {
180 + /* Always allocate MAXPACKET, callers expect
181 + this specific size. */
182 u_char *buf = malloc (MAXPACKET);
183 if (buf == NULL)
184 return (-1);
185 @@ -652,6 +671,77 @@ libresolv_hidden_def (res_nsend)
186
187 /* Private */
188
189 +/* The send_vc function is responsible for sending a DNS query over TCP
190 + to the nameserver numbered NS from the res_state STATP i.e.
191 + EXT(statp).nssocks[ns]. The function supports sending both IPv4 and
192 + IPv6 queries at the same serially on the same socket.
193 +
194 + Please note that for TCP there is no way to disable sending both
195 + queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP
196 + and sends the queries serially and waits for the result after each
197 + sent query. This implemetnation should be corrected to honour these
198 + options.
199 +
200 + Please also note that for TCP we send both queries over the same
201 + socket one after another. This technically violates best practice
202 + since the server is allowed to read the first query, respond, and
203 + then close the socket (to service another client). If the server
204 + does this, then the remaining second query in the socket data buffer
205 + will cause the server to send the client an RST which will arrive
206 + asynchronously and the client's OS will likely tear down the socket
207 + receive buffer resulting in a potentially short read and lost
208 + response data. This will force the client to retry the query again,
209 + and this process may repeat until all servers and connection resets
210 + are exhausted and then the query will fail. It's not known if this
211 + happens with any frequency in real DNS server implementations. This
212 + implementation should be corrected to use two sockets by default for
213 + parallel queries.
214 +
215 + The query stored in BUF of BUFLEN length is sent first followed by
216 + the query stored in BUF2 of BUFLEN2 length. Queries are sent
217 + serially on the same socket.
218 +
219 + Answers to the query are stored firstly in *ANSP up to a max of
220 + *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
221 + is non-NULL (to indicate that modifying the answer buffer is allowed)
222 + then malloc is used to allocate a new response buffer and ANSCP and
223 + ANSP will both point to the new buffer. If more than *ANSSIZP bytes
224 + are needed but ANSCP is NULL, then as much of the response as
225 + possible is read into the buffer, but the results will be truncated.
226 + When truncation happens because of a small answer buffer the DNS
227 + packets header feild TC will bet set to 1, indicating a truncated
228 + message and the rest of the socket data will be read and discarded.
229 +
230 + Answers to the query are stored secondly in *ANSP2 up to a max of
231 + *ANSSIZP2 bytes, with the actual response length stored in
232 + *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
233 + is non-NULL (required for a second query) then malloc is used to
234 + allocate a new response buffer, *ANSSIZP2 is set to the new buffer
235 + size and *ANSP2_MALLOCED is set to 1.
236 +
237 + The ANSP2_MALLOCED argument will eventually be removed as the
238 + change in buffer pointer can be used to detect the buffer has
239 + changed and that the caller should use free on the new buffer.
240 +
241 + Note that the answers may arrive in any order from the server and
242 + therefore the first and second answer buffers may not correspond to
243 + the first and second queries.
244 +
245 + It is not supported to call this function with a non-NULL ANSP2
246 + but a NULL ANSCP. Put another way, you can call send_vc with a
247 + single unmodifiable buffer or two modifiable buffers, but no other
248 + combination is supported.
249 +
250 + It is the caller's responsibility to free the malloc allocated
251 + buffers by detecting that the pointers have changed from their
252 + original values i.e. *ANSCP or *ANSP2 has changed.
253 +
254 + If errors are encountered then *TERRNO is set to an appropriate
255 + errno value and a zero result is returned for a recoverable error,
256 + and a less-than zero result is returned for a non-recoverable error.
257 +
258 + If no errors are encountered then *TERRNO is left unmodified and
259 + a the length of the first response in bytes is returned. */
260 static int
261 send_vc(res_state statp,
262 const u_char *buf, int buflen, const u_char *buf2, int buflen2,
263 @@ -661,11 +751,7 @@ send_vc(res_state statp,
264 {
265 const HEADER *hp = (HEADER *) buf;
266 const HEADER *hp2 = (HEADER *) buf2;
267 - u_char *ans = *ansp;
268 - int orig_anssizp = *anssizp;
269 - // XXX REMOVE
270 - // int anssiz = *anssizp;
271 - HEADER *anhp = (HEADER *) ans;
272 + HEADER *anhp = (HEADER *) *ansp;
273 struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns];
274 int truncating, connreset, resplen, n;
275 struct iovec iov[4];
276 @@ -741,6 +827,8 @@ send_vc(res_state statp,
277 * Receive length & response
278 */
279 int recvresp1 = 0;
280 + /* Skip the second response if there is no second query.
281 + To do that we mark the second response as received. */
282 int recvresp2 = buf2 == NULL;
283 uint16_t rlen16;
284 read_len:
285 @@ -777,33 +865,14 @@ send_vc(res_state statp,
286 u_char **thisansp;
287 int *thisresplenp;
288 if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
289 + /* We have not received any responses
290 + yet or we only have one response to
291 + receive. */
292 thisanssizp = anssizp;
293 thisansp = anscp ?: ansp;
294 assert (anscp != NULL || ansp2 == NULL);
295 thisresplenp = &resplen;
296 } else {
297 - if (*anssizp != MAXPACKET) {
298 - /* No buffer allocated for the first
299 - reply. We can try to use the rest
300 - of the user-provided buffer. */
301 -#ifdef _STRING_ARCH_unaligned
302 - *anssizp2 = orig_anssizp - resplen;
303 - *ansp2 = *ansp + resplen;
304 -#else
305 - int aligned_resplen
306 - = ((resplen + __alignof__ (HEADER) - 1)
307 - & ~(__alignof__ (HEADER) - 1));
308 - *anssizp2 = orig_anssizp - aligned_resplen;
309 - *ansp2 = *ansp + aligned_resplen;
310 -#endif
311 - } else {
312 - /* The first reply did not fit into the
313 - user-provided buffer. Maybe the second
314 - answer will. */
315 - *anssizp2 = orig_anssizp;
316 - *ansp2 = *ansp;
317 - }
318 -
319 thisanssizp = anssizp2;
320 thisansp = ansp2;
321 thisresplenp = resplen2;
322 @@ -811,10 +880,14 @@ send_vc(res_state statp,
323 anhp = (HEADER *) *thisansp;
324
325 *thisresplenp = rlen;
326 - if (rlen > *thisanssizp) {
327 - /* Yes, we test ANSCP here. If we have two buffers
328 - both will be allocatable. */
329 - if (__builtin_expect (anscp != NULL, 1)) {
330 + /* Is the answer buffer too small? */
331 + if (*thisanssizp < rlen) {
332 + /* If the current buffer is non-NULL and it's not
333 + pointing at the static user-supplied buffer then
334 + we can reallocate it. */
335 + if (thisansp != NULL && thisansp != ansp) {
336 + /* Always allocate MAXPACKET, callers expect
337 + this specific size. */
338 u_char *newp = malloc (MAXPACKET);
339 if (newp == NULL) {
340 *terrno = ENOMEM;
341 @@ -824,6 +897,9 @@ send_vc(res_state statp,
342 *thisanssizp = MAXPACKET;
343 *thisansp = newp;
344 anhp = (HEADER *) newp;
345 + /* A uint16_t can't be larger than MAXPACKET
346 + thus it's safe to allocate MAXPACKET but
347 + read RLEN bytes instead. */
348 len = rlen;
349 } else {
350 Dprint(statp->options & RES_DEBUG,
351 @@ -987,6 +1063,66 @@ reopen (res_state statp, int *terrno, in
352 return 1;
353 }
354
355 +/* The send_dg function is responsible for sending a DNS query over UDP
356 + to the nameserver numbered NS from the res_state STATP i.e.
357 + EXT(statp).nssocks[ns]. The function supports IPv4 and IPv6 queries
358 + along with the ability to send the query in parallel for both stacks
359 + (default) or serially (RES_SINGLKUP). It also supports serial lookup
360 + with a close and reopen of the socket used to talk to the server
361 + (RES_SNGLKUPREOP) to work around broken name servers.
362 +
363 + The query stored in BUF of BUFLEN length is sent first followed by
364 + the query stored in BUF2 of BUFLEN2 length. Queries are sent
365 + in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP).
366 +
367 + Answers to the query are stored firstly in *ANSP up to a max of
368 + *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
369 + is non-NULL (to indicate that modifying the answer buffer is allowed)
370 + then malloc is used to allocate a new response buffer and ANSCP and
371 + ANSP will both point to the new buffer. If more than *ANSSIZP bytes
372 + are needed but ANSCP is NULL, then as much of the response as
373 + possible is read into the buffer, but the results will be truncated.
374 + When truncation happens because of a small answer buffer the DNS
375 + packets header feild TC will bet set to 1, indicating a truncated
376 + message, while the rest of the UDP packet is discarded.
377 +
378 + Answers to the query are stored secondly in *ANSP2 up to a max of
379 + *ANSSIZP2 bytes, with the actual response length stored in
380 + *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
381 + is non-NULL (required for a second query) then malloc is used to
382 + allocate a new response buffer, *ANSSIZP2 is set to the new buffer
383 + size and *ANSP2_MALLOCED is set to 1.
384 +
385 + The ANSP2_MALLOCED argument will eventually be removed as the
386 + change in buffer pointer can be used to detect the buffer has
387 + changed and that the caller should use free on the new buffer.
388 +
389 + Note that the answers may arrive in any order from the server and
390 + therefore the first and second answer buffers may not correspond to
391 + the first and second queries.
392 +
393 + It is not supported to call this function with a non-NULL ANSP2
394 + but a NULL ANSCP. Put another way, you can call send_vc with a
395 + single unmodifiable buffer or two modifiable buffers, but no other
396 + combination is supported.
397 +
398 + It is the caller's responsibility to free the malloc allocated
399 + buffers by detecting that the pointers have changed from their
400 + original values i.e. *ANSCP or *ANSP2 has changed.
401 +
402 + If an answer is truncated because of UDP datagram DNS limits then
403 + *V_CIRCUIT is set to 1 and the return value non-zero to indicate to
404 + the caller to retry with TCP. The value *GOTSOMEWHERE is set to 1
405 + if any progress was made reading a response from the nameserver and
406 + is used by the caller to distinguish between ECONNREFUSED and
407 + ETIMEDOUT (the latter if *GOTSOMEWHERE is 1).
408 +
409 + If errors are encountered then *TERRNO is set to an appropriate
410 + errno value and a zero result is returned for a recoverable error,
411 + and a less-than zero result is returned for a non-recoverable error.
412 +
413 + If no errors are encountered then *TERRNO is left unmodified and
414 + a the length of the first response in bytes is returned. */
415 static int
416 send_dg(res_state statp,
417 const u_char *buf, int buflen, const u_char *buf2, int buflen2,
418 @@ -996,8 +1132,6 @@ send_dg(res_state statp,
419 {
420 const HEADER *hp = (HEADER *) buf;
421 const HEADER *hp2 = (HEADER *) buf2;
422 - u_char *ans = *ansp;
423 - int orig_anssizp = *anssizp;
424 struct timespec now, timeout, finish;
425 struct pollfd pfd[1];
426 int ptimeout;
427 @@ -1029,6 +1163,8 @@ send_dg(res_state statp,
428 int need_recompute = 0;
429 int nwritten = 0;
430 int recvresp1 = 0;
431 + /* Skip the second response if there is no second query.
432 + To do that we mark the second response as received. */
433 int recvresp2 = buf2 == NULL;
434 pfd[0].fd = EXT(statp).nssocks[ns];
435 pfd[0].events = POLLOUT;
436 @@ -1125,50 +1261,52 @@ send_dg(res_state statp,
437 int *thisresplenp;
438
439 if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
440 + /* We have not received any responses
441 + yet or we only have one response to
442 + receive. */
443 thisanssizp = anssizp;
444 thisansp = anscp ?: ansp;
445 assert (anscp != NULL || ansp2 == NULL);
446 thisresplenp = &resplen;
447 } else {
448 - if (*anssizp != MAXPACKET) {
449 - /* No buffer allocated for the first
450 - reply. We can try to use the rest
451 - of the user-provided buffer. */
452 -#ifdef _STRING_ARCH_unaligned
453 - *anssizp2 = orig_anssizp - resplen;
454 - *ansp2 = *ansp + resplen;
455 -#else
456 - int aligned_resplen
457 - = ((resplen + __alignof__ (HEADER) - 1)
458 - & ~(__alignof__ (HEADER) - 1));
459 - *anssizp2 = orig_anssizp - aligned_resplen;
460 - *ansp2 = *ansp + aligned_resplen;
461 -#endif
462 - } else {
463 - /* The first reply did not fit into the
464 - user-provided buffer. Maybe the second
465 - answer will. */
466 - *anssizp2 = orig_anssizp;
467 - *ansp2 = *ansp;
468 - }
469 -
470 thisanssizp = anssizp2;
471 thisansp = ansp2;
472 thisresplenp = resplen2;
473 }
474
475 if (*thisanssizp < MAXPACKET
476 - /* Yes, we test ANSCP here. If we have two buffers
477 - both will be allocatable. */
478 - && anscp
479 + /* If the current buffer is non-NULL and it's not
480 + pointing at the static user-supplied buffer then
481 + we can reallocate it. */
482 + && (thisansp != NULL && thisansp != ansp)
483 + /* Is the size too small? */
484 && (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0
485 - || *thisanssizp < *thisresplenp)) {
486 + || *thisanssizp < *thisresplenp)
487 + ) {
488 + /* Always allocate MAXPACKET, callers expect
489 + this specific size. */
490 u_char *newp = malloc (MAXPACKET);
491 if (newp != NULL) {
492 - *anssizp = MAXPACKET;
493 - *thisansp = ans = newp;
494 + *thisanssizp = MAXPACKET;
495 + *thisansp = newp;
496 }
497 }
498 + /* We could end up with truncation if anscp was NULL
499 + (not allowed to change caller's buffer) and the
500 + response buffer size is too small. This isn't a
501 + reliable way to detect truncation because the ioctl
502 + may be an inaccurate report of the UDP message size.
503 + Therefore we use this only to issue debug output.
504 + To do truncation accurately with UDP we need
505 + MSG_TRUNC which is only available on Linux. We
506 + can abstract out the Linux-specific feature in the
507 + future to detect truncation. */
508 + if (__glibc_unlikely (*thisanssizp < *thisresplenp)) {
509 + Dprint(statp->options & RES_DEBUG,
510 + (stdout, ";; response may be truncated (UDP)\n")
511 + );
512 + }
513 +
514 HEADER *anhp = (HEADER *) *thisansp;
515 socklen_t fromlen = sizeof(struct sockaddr_in6);
516 assert (sizeof(from) <= fromlen);
517 Index: glibc-2.12-2-gc4ccff1/resolv/res_query.c
518 ===================================================================
519 --- glibc-2.12-2-gc4ccff1.orig/resolv/res_query.c
520 +++ glibc-2.12-2-gc4ccff1/resolv/res_query.c
521 @@ -391,6 +391,7 @@ __libc_res_nsearch(res_state statp,
522 && (*answerp2 < answer || *answerp2 >= answer + anslen))
523 {
524 free (*answerp2);
525 + *nanswerp2 = 0;
526 *answerp2 = NULL;
527 }
528 }
529 @@ -431,6 +432,7 @@ __libc_res_nsearch(res_state statp,
530 || *answerp2 >= answer + anslen))
531 {
532 free (*answerp2);
533 + *nanswerp2 = 0;
534 *answerp2 = NULL;
535 }
536
537 @@ -503,6 +505,7 @@ __libc_res_nsearch(res_state statp,
538 if (answerp2 && (*answerp2 < answer || *answerp2 >= answer + anslen))
539 {
540 free (*answerp2);
541 + *nanswerp2 = NULL;
542 *answerp2 = NULL;
543 }
544 if (saved_herrno != -1)