]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/glibc/glibc-rh1296031.patch
dhcpcd: fix delay after dhcp down.
[ipfire-2.x.git] / src / patches / glibc / glibc-rh1296031.patch
CommitLineData
bb330e25
AF
1Index: 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;
151Index: 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);
517Index: 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)