]>
Commit | Line | Data |
---|---|---|
bb330e25 AF |
1 | Sourceware bug 16574 |
2 | ||
3 | commit d668061994a7486a3ba9c7d5e7882d85a2883707 | |
4 | Author: Andreas Schwab <schwab@suse.de> | |
5 | Date: Thu Feb 13 11:01:57 2014 +0100 | |
6 | ||
7 | Fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer | |
8 | ||
9 | commit ab7ac0f2cf8731fe4c3f3aea6088a7c0127b5725 | |
10 | Author: Ondřej Bílka <neleai@seznam.cz> | |
11 | Date: Sun Feb 16 12:59:23 2014 +0100 | |
12 | ||
13 | Deduplicate resolv/nss_dns/dns-host.c | |
14 | ||
15 | In resolv/nss_dns/dns-host.c one of code path duplicated code after | |
16 | that. We merge these paths. | |
17 | ||
18 | commit ab09bf616ad527b249aca5f2a4956fd526f0712f | |
19 | Author: Andreas Schwab <schwab@suse.de> | |
20 | Date: Tue Feb 18 10:57:25 2014 +0100 | |
21 | ||
22 | Properly fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer | |
23 | ||
24 | Instead of trying to guess whether the second buffer needs to be freed | |
25 | set a flag at the place it is allocated | |
26 | ||
27 | Index: glibc-2.12-2-gc4ccff1/include/resolv.h | |
28 | =================================================================== | |
29 | --- glibc-2.12-2-gc4ccff1.orig/include/resolv.h | |
30 | +++ glibc-2.12-2-gc4ccff1/include/resolv.h | |
31 | @@ -58,11 +58,11 @@ libc_hidden_proto (__res_randomid) | |
32 | libc_hidden_proto (__res_state) | |
33 | ||
34 | int __libc_res_nquery (res_state, const char *, int, int, u_char *, int, | |
35 | - u_char **, u_char **, int *, int *); | |
36 | + u_char **, u_char **, int *, int *, int *); | |
37 | int __libc_res_nsearch (res_state, const char *, int, int, u_char *, int, | |
38 | - u_char **, u_char **, int *, int *); | |
39 | + u_char **, u_char **, int *, int *, int *); | |
40 | int __libc_res_nsend (res_state, const u_char *, int, const u_char *, int, | |
41 | - u_char *, int, u_char **, u_char **, int *, int *) | |
42 | + u_char *, int, u_char **, u_char **, int *, int *, int *) | |
43 | attribute_hidden; | |
44 | ||
45 | libresolv_hidden_proto (_sethtent) | |
46 | Index: glibc-2.12-2-gc4ccff1/resolv/gethnamaddr.c | |
47 | =================================================================== | |
48 | --- glibc-2.12-2-gc4ccff1.orig/resolv/gethnamaddr.c | |
49 | +++ glibc-2.12-2-gc4ccff1/resolv/gethnamaddr.c | |
50 | @@ -634,7 +634,7 @@ gethostbyname2(name, af) | |
51 | buf.buf = origbuf = (querybuf *) alloca (1024); | |
52 | ||
53 | if ((n = __libc_res_nsearch(&_res, name, C_IN, type, buf.buf->buf, 1024, | |
54 | - &buf.ptr, NULL, NULL, NULL)) < 0) { | |
55 | + &buf.ptr, NULL, NULL, NULL, NULL)) < 0) { | |
56 | if (buf.buf != origbuf) | |
57 | free (buf.buf); | |
58 | Dprintf("res_nsearch failed (%d)\n", n); | |
59 | @@ -729,12 +729,12 @@ gethostbyaddr(addr, len, af) | |
60 | buf.buf = orig_buf = (querybuf *) alloca (1024); | |
61 | ||
62 | n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, 1024, | |
63 | - &buf.ptr, NULL, NULL, NULL); | |
64 | + &buf.ptr, NULL, NULL, NULL, NULL); | |
65 | if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) { | |
66 | strcpy(qp, "ip6.int"); | |
67 | n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, | |
68 | buf.buf != orig_buf ? MAXPACKET : 1024, | |
69 | - &buf.ptr, NULL, NULL, NULL); | |
70 | + &buf.ptr, NULL, NULL, NULL, NULL); | |
71 | } | |
72 | if (n < 0) { | |
73 | if (buf.buf != orig_buf) | |
74 | Index: glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-canon.c | |
75 | =================================================================== | |
76 | --- glibc-2.12-2-gc4ccff1.orig/resolv/nss_dns/dns-canon.c | |
77 | +++ glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-canon.c | |
78 | @@ -62,7 +62,7 @@ _nss_dns_getcanonname_r (const char *nam | |
79 | { | |
80 | int r = __libc_res_nquery (&_res, name, ns_c_in, qtypes[i], | |
81 | buf, sizeof (buf), &ansp.ptr, NULL, NULL, | |
82 | - NULL); | |
83 | + NULL, NULL); | |
84 | if (r > 0) | |
85 | { | |
86 | /* We need to decode the response. Just one question record. | |
87 | Index: glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-host.c | |
88 | =================================================================== | |
89 | --- glibc-2.12-2-gc4ccff1.orig/resolv/nss_dns/dns-host.c | |
90 | +++ glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-host.c | |
91 | @@ -191,7 +191,7 @@ _nss_dns_gethostbyname3_r (const char *n | |
92 | host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024); | |
93 | ||
94 | n = __libc_res_nsearch (&_res, name, C_IN, type, host_buffer.buf->buf, | |
95 | - 1024, &host_buffer.ptr, NULL, NULL, NULL); | |
96 | + 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL); | |
97 | if (n < 0) | |
98 | { | |
99 | switch (errno) | |
100 | @@ -221,7 +221,7 @@ _nss_dns_gethostbyname3_r (const char *n | |
101 | n = __libc_res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf->buf, | |
102 | host_buffer.buf != orig_host_buffer | |
103 | ? MAXPACKET : 1024, &host_buffer.ptr, | |
104 | - NULL, NULL, NULL); | |
105 | + NULL, NULL, NULL, NULL); | |
106 | ||
107 | if (n < 0) | |
108 | { | |
109 | @@ -304,13 +304,20 @@ _nss_dns_gethostbyname4_r (const char *n | |
110 | u_char *ans2p = NULL; | |
111 | int nans2p = 0; | |
112 | int resplen2 = 0; | |
113 | + int ans2p_malloced = 0; | |
114 | ||
115 | int olderr = errno; | |
116 | enum nss_status status; | |
117 | int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC, | |
118 | host_buffer.buf->buf, 2048, &host_buffer.ptr, | |
119 | - &ans2p, &nans2p, &resplen2); | |
120 | - if (n < 0) | |
121 | + &ans2p, &nans2p, &resplen2, &ans2p_malloced); | |
122 | + if (n >= 0) | |
123 | + { | |
124 | + status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p, | |
125 | + resplen2, name, pat, buffer, buflen, | |
126 | + errnop, herrnop, ttlp); | |
127 | + } | |
128 | + else | |
129 | { | |
130 | if (errno == ESRCH) | |
131 | { | |
132 | @@ -325,16 +332,11 @@ _nss_dns_gethostbyname4_r (const char *n | |
133 | *errnop = EAGAIN; | |
134 | else | |
135 | __set_errno (olderr); | |
136 | - | |
137 | - if (host_buffer.buf != orig_host_buffer) | |
138 | - free (host_buffer.buf); | |
139 | - | |
140 | - return status; | |
141 | } | |
142 | ||
143 | - status = gaih_getanswer(host_buffer.buf, n, (const querybuf *) ans2p, | |
144 | - resplen2, name, pat, buffer, buflen, | |
145 | - errnop, herrnop, ttlp); | |
146 | + /* Check whether ans2p was separately allocated. */ | |
147 | + if (ans2p_malloced) | |
148 | + free (ans2p); | |
149 | ||
150 | if (host_buffer.buf != orig_host_buffer) | |
151 | free (host_buffer.buf); | |
152 | @@ -444,7 +446,7 @@ _nss_dns_gethostbyaddr2_r (const void *a | |
153 | strcpy (qp, "].ip6.arpa"); | |
154 | n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, | |
155 | host_buffer.buf->buf, 1024, &host_buffer.ptr, | |
156 | - NULL, NULL, NULL); | |
157 | + NULL, NULL, NULL, NULL); | |
158 | if (n >= 0) | |
159 | goto got_it_already; | |
160 | } | |
161 | @@ -465,14 +467,14 @@ _nss_dns_gethostbyaddr2_r (const void *a | |
162 | } | |
163 | ||
164 | n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf, | |
165 | - 1024, &host_buffer.ptr, NULL, NULL, NULL); | |
166 | + 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL); | |
167 | if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) | |
168 | { | |
169 | strcpy (qp, "ip6.int"); | |
170 | n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf, | |
171 | host_buffer.buf != orig_host_buffer | |
172 | ? MAXPACKET : 1024, &host_buffer.ptr, | |
173 | - NULL, NULL, NULL); | |
174 | + NULL, NULL, NULL, NULL); | |
175 | } | |
176 | if (n < 0) | |
177 | { | |
178 | Index: glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-network.c | |
179 | =================================================================== | |
180 | --- glibc-2.12-2-gc4ccff1.orig/resolv/nss_dns/dns-network.c | |
181 | +++ glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-network.c | |
182 | @@ -130,7 +130,7 @@ _nss_dns_getnetbyname_r (const char *nam | |
183 | net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024); | |
184 | ||
185 | anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf, | |
186 | - 1024, &net_buffer.ptr, NULL, NULL, NULL); | |
187 | + 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL); | |
188 | if (anslen < 0) | |
189 | { | |
190 | /* Nothing found. */ | |
191 | @@ -206,7 +206,7 @@ _nss_dns_getnetbyaddr_r (uint32_t net, i | |
192 | net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024); | |
193 | ||
194 | anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf, | |
195 | - 1024, &net_buffer.ptr, NULL, NULL, NULL); | |
196 | + 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL); | |
197 | if (anslen < 0) | |
198 | { | |
199 | /* Nothing found. */ | |
200 | Index: glibc-2.12-2-gc4ccff1/resolv/res_query.c | |
201 | =================================================================== | |
202 | --- glibc-2.12-2-gc4ccff1.orig/resolv/res_query.c | |
203 | +++ glibc-2.12-2-gc4ccff1/resolv/res_query.c | |
204 | @@ -98,7 +98,7 @@ static int | |
205 | __libc_res_nquerydomain(res_state statp, const char *name, const char *domain, | |
206 | int class, int type, u_char *answer, int anslen, | |
207 | u_char **answerp, u_char **answerp2, int *nanswerp2, | |
208 | - int *resplen2); | |
209 | + int *resplen2, int *answerp2_malloced); | |
210 | ||
211 | /* | |
212 | * Formulate a normal query, send, and await answer. | |
213 | @@ -119,7 +119,8 @@ __libc_res_nquery(res_state statp, | |
214 | u_char **answerp, /* if buffer needs to be enlarged */ | |
215 | u_char **answerp2, | |
216 | int *nanswerp2, | |
217 | - int *resplen2) | |
218 | + int *resplen2, | |
219 | + int *answerp2_malloced) | |
220 | { | |
221 | HEADER *hp = (HEADER *) answer; | |
222 | HEADER *hp2; | |
223 | @@ -224,7 +225,8 @@ __libc_res_nquery(res_state statp, | |
224 | } | |
225 | assert (answerp == NULL || (void *) *answerp == (void *) answer); | |
226 | n = __libc_res_nsend(statp, query1, nquery1, query2, nquery2, answer, | |
227 | - anslen, answerp, answerp2, nanswerp2, resplen2); | |
228 | + anslen, answerp, answerp2, nanswerp2, resplen2, | |
229 | + answerp2_malloced); | |
230 | if (use_malloc) | |
231 | free (buf); | |
232 | if (n < 0) { | |
233 | @@ -316,7 +318,7 @@ res_nquery(res_state statp, | |
234 | int anslen) /* size of answer buffer */ | |
235 | { | |
236 | return __libc_res_nquery(statp, name, class, type, answer, anslen, | |
237 | - NULL, NULL, NULL, NULL); | |
238 | + NULL, NULL, NULL, NULL, NULL); | |
239 | } | |
240 | libresolv_hidden_def (res_nquery) | |
241 | ||
242 | @@ -335,7 +337,8 @@ __libc_res_nsearch(res_state statp, | |
243 | u_char **answerp, | |
244 | u_char **answerp2, | |
245 | int *nanswerp2, | |
246 | - int *resplen2) | |
247 | + int *resplen2, | |
248 | + int *answerp2_malloced) | |
249 | { | |
250 | const char *cp, * const *domain; | |
251 | HEADER *hp = (HEADER *) answer; | |
252 | @@ -359,7 +362,7 @@ __libc_res_nsearch(res_state statp, | |
253 | if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL) | |
254 | return (__libc_res_nquery(statp, cp, class, type, answer, | |
255 | anslen, answerp, answerp2, | |
256 | - nanswerp2, resplen2)); | |
257 | + nanswerp2, resplen2, answerp2_malloced)); | |
258 | ||
259 | #ifdef DEBUG | |
260 | if (statp->options & RES_DEBUG) | |
261 | @@ -376,7 +379,8 @@ __libc_res_nsearch(res_state statp, | |
262 | if (dots >= statp->ndots || trailing_dot) { | |
263 | ret = __libc_res_nquerydomain(statp, name, NULL, class, type, | |
264 | answer, anslen, answerp, | |
265 | - answerp2, nanswerp2, resplen2); | |
266 | + answerp2, nanswerp2, resplen2, | |
267 | + answerp2_malloced); | |
268 | if (ret > 0 || trailing_dot | |
269 | /* If the second response is valid then we use that. */ | |
270 | || (ret == 0 && resplen2 != NULL && *resplen2 > 0)) | |
271 | @@ -387,12 +391,12 @@ __libc_res_nsearch(res_state statp, | |
272 | answer = *answerp; | |
273 | anslen = MAXPACKET; | |
274 | } | |
275 | - if (answerp2 | |
276 | - && (*answerp2 < answer || *answerp2 >= answer + anslen)) | |
277 | + if (answerp2 && *answerp2_malloced) | |
278 | { | |
279 | free (*answerp2); | |
280 | *nanswerp2 = 0; | |
281 | *answerp2 = NULL; | |
282 | + *answerp2_malloced = 0; | |
283 | } | |
284 | } | |
285 | ||
286 | @@ -418,7 +422,7 @@ __libc_res_nsearch(res_state statp, | |
287 | class, type, | |
288 | answer, anslen, answerp, | |
289 | answerp2, nanswerp2, | |
290 | - resplen2); | |
291 | + resplen2, answerp2_malloced); | |
292 | if (ret > 0 || (ret == 0 && resplen2 != NULL | |
293 | && *resplen2 > 0)) | |
294 | return (ret); | |
295 | @@ -427,13 +431,12 @@ __libc_res_nsearch(res_state statp, | |
296 | answer = *answerp; | |
297 | anslen = MAXPACKET; | |
298 | } | |
299 | - if (answerp2 | |
300 | - && (*answerp2 < answer | |
301 | - || *answerp2 >= answer + anslen)) | |
302 | + if (answerp2 && *answerp2_malloced) | |
303 | { | |
304 | free (*answerp2); | |
305 | *nanswerp2 = 0; | |
306 | *answerp2 = NULL; | |
307 | + *answerp2_malloced = 0; | |
308 | } | |
309 | ||
310 | /* | |
311 | @@ -489,7 +492,8 @@ __libc_res_nsearch(res_state statp, | |
312 | if (dots && !(tried_as_is || root_on_list)) { | |
313 | ret = __libc_res_nquerydomain(statp, name, NULL, class, type, | |
314 | answer, anslen, answerp, | |
315 | - answerp2, nanswerp2, resplen2); | |
316 | + answerp2, nanswerp2, resplen2, | |
317 | + answerp2_malloced); | |
318 | if (ret > 0 || (ret == 0 && resplen2 != NULL | |
319 | && *resplen2 > 0)) | |
320 | return (ret); | |
321 | @@ -502,11 +506,12 @@ __libc_res_nsearch(res_state statp, | |
322 | * else send back meaningless H_ERRNO, that being the one from | |
323 | * the last DNSRCH we did. | |
324 | */ | |
325 | - if (answerp2 && (*answerp2 < answer || *answerp2 >= answer + anslen)) | |
326 | + if (answerp2 && *answerp2_malloced) | |
327 | { | |
328 | free (*answerp2); | |
329 | - *nanswerp2 = NULL; | |
330 | + *nanswerp2 = 0; | |
331 | *answerp2 = NULL; | |
332 | + *answerp2_malloced = 0; | |
333 | } | |
334 | if (saved_herrno != -1) | |
335 | RES_SET_H_ERRNO(statp, saved_herrno); | |
336 | @@ -526,7 +531,7 @@ res_nsearch(res_state statp, | |
337 | int anslen) /* size of answer */ | |
338 | { | |
339 | return __libc_res_nsearch(statp, name, class, type, answer, | |
340 | - anslen, NULL, NULL, NULL, NULL); | |
341 | + anslen, NULL, NULL, NULL, NULL, NULL); | |
342 | } | |
343 | libresolv_hidden_def (res_nsearch) | |
344 | ||
345 | @@ -544,7 +549,8 @@ __libc_res_nquerydomain(res_state statp, | |
346 | u_char **answerp, | |
347 | u_char **answerp2, | |
348 | int *nanswerp2, | |
349 | - int *resplen2) | |
350 | + int *resplen2, | |
351 | + int *answerp2_malloced) | |
352 | { | |
353 | char nbuf[MAXDNAME]; | |
354 | const char *longname = nbuf; | |
355 | @@ -582,7 +588,7 @@ __libc_res_nquerydomain(res_state statp, | |
356 | } | |
357 | return (__libc_res_nquery(statp, longname, class, type, answer, | |
358 | anslen, answerp, answerp2, nanswerp2, | |
359 | - resplen2)); | |
360 | + resplen2, answerp2_malloced)); | |
361 | } | |
362 | ||
363 | int | |
364 | @@ -594,7 +600,8 @@ res_nquerydomain(res_state statp, | |
365 | int anslen) /* size of answer */ | |
366 | { | |
367 | return __libc_res_nquerydomain(statp, name, domain, class, type, | |
368 | - answer, anslen, NULL, NULL, NULL, NULL); | |
369 | + answer, anslen, NULL, NULL, NULL, NULL, | |
370 | + NULL); | |
371 | } | |
372 | libresolv_hidden_def (res_nquerydomain) | |
373 | ||
374 | Index: glibc-2.12-2-gc4ccff1/resolv/res_send.c | |
375 | =================================================================== | |
376 | --- glibc-2.12-2-gc4ccff1.orig/resolv/res_send.c | |
377 | +++ glibc-2.12-2-gc4ccff1/resolv/res_send.c | |
378 | @@ -203,12 +203,12 @@ evNowTime(struct timespec *res) { | |
379 | static int send_vc(res_state, const u_char *, int, | |
380 | const u_char *, int, | |
381 | u_char **, int *, int *, int, u_char **, | |
382 | - u_char **, int *, int *); | |
383 | + u_char **, int *, int *, int *); | |
384 | static int send_dg(res_state, const u_char *, int, | |
385 | const u_char *, int, | |
386 | u_char **, int *, int *, int, | |
387 | int *, int *, u_char **, | |
388 | - u_char **, int *, int *); | |
389 | + u_char **, int *, int *, int *); | |
390 | #ifdef DEBUG | |
391 | static void Aerror(const res_state, FILE *, const char *, int, | |
392 | const struct sockaddr *); | |
393 | @@ -360,7 +360,7 @@ int | |
394 | __libc_res_nsend(res_state statp, const u_char *buf, int buflen, | |
395 | const u_char *buf2, int buflen2, | |
396 | u_char *ans, int anssiz, u_char **ansp, u_char **ansp2, | |
397 | - int *nansp2, int *resplen2) | |
398 | + int *nansp2, int *resplen2, int *ansp2_malloced) | |
399 | { | |
400 | int gotsomewhere, terrno, try, v_circuit, resplen, ns, n; | |
401 | ||
402 | @@ -565,7 +565,8 @@ __libc_res_nsend(res_state statp, const | |
403 | try = statp->retry; | |
404 | n = send_vc(statp, buf, buflen, buf2, buflen2, | |
405 | &ans, &anssiz, &terrno, | |
406 | - ns, ansp, ansp2, nansp2, resplen2); | |
407 | + ns, ansp, ansp2, nansp2, resplen2, | |
408 | + ansp2_malloced); | |
409 | if (n < 0) | |
410 | return (-1); | |
411 | if (n == 0 && (buf2 == NULL || *resplen2 == 0)) | |
412 | @@ -575,7 +576,7 @@ __libc_res_nsend(res_state statp, const | |
413 | n = send_dg(statp, buf, buflen, buf2, buflen2, | |
414 | &ans, &anssiz, &terrno, | |
415 | ns, &v_circuit, &gotsomewhere, ansp, | |
416 | - ansp2, nansp2, resplen2); | |
417 | + ansp2, nansp2, resplen2, ansp2_malloced); | |
418 | if (n < 0) | |
419 | return (-1); | |
420 | if (n == 0 && (buf2 == NULL || *resplen2 == 0)) | |
421 | @@ -665,7 +666,7 @@ res_nsend(res_state statp, | |
422 | const u_char *buf, int buflen, u_char *ans, int anssiz) | |
423 | { | |
424 | return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz, | |
425 | - NULL, NULL, NULL, NULL); | |
426 | + NULL, NULL, NULL, NULL, NULL); | |
427 | } | |
428 | libresolv_hidden_def (res_nsend) | |
429 | ||
430 | @@ -747,7 +748,7 @@ send_vc(res_state statp, | |
431 | const u_char *buf, int buflen, const u_char *buf2, int buflen2, | |
432 | u_char **ansp, int *anssizp, | |
433 | int *terrno, int ns, u_char **anscp, u_char **ansp2, int *anssizp2, | |
434 | - int *resplen2) | |
435 | + int *resplen2, int *ansp2_malloced) | |
436 | { | |
437 | const HEADER *hp = (HEADER *) buf; | |
438 | const HEADER *hp2 = (HEADER *) buf2; | |
439 | @@ -896,6 +897,8 @@ send_vc(res_state statp, | |
440 | } | |
441 | *thisanssizp = MAXPACKET; | |
442 | *thisansp = newp; | |
443 | + if (thisansp == ansp2) | |
444 | + *ansp2_malloced = 1; | |
445 | anhp = (HEADER *) newp; | |
446 | /* A uint16_t can't be larger than MAXPACKET | |
447 | thus it's safe to allocate MAXPACKET but | |
448 | @@ -1128,7 +1131,7 @@ send_dg(res_state statp, | |
449 | const u_char *buf, int buflen, const u_char *buf2, int buflen2, | |
450 | u_char **ansp, int *anssizp, | |
451 | int *terrno, int ns, int *v_circuit, int *gotsomewhere, u_char **anscp, | |
452 | - u_char **ansp2, int *anssizp2, int *resplen2) | |
453 | + u_char **ansp2, int *anssizp2, int *resplen2, int *ansp2_malloced) | |
454 | { | |
455 | const HEADER *hp = (HEADER *) buf; | |
456 | const HEADER *hp2 = (HEADER *) buf2; | |
457 | @@ -1289,6 +1292,8 @@ send_dg(res_state statp, | |
458 | if (newp != NULL) { | |
459 | *thisanssizp = MAXPACKET; | |
460 | *thisansp = newp; | |
461 | + if (thisansp == ansp2) | |
462 | + *ansp2_malloced = 1; | |
463 | } | |
464 | } | |
465 | /* We could end up with truncation if anscp was NULL |