f57669
Sourceware bug 16574
f57669
f57669
commit d668061994a7486a3ba9c7d5e7882d85a2883707
f57669
Author: Andreas Schwab <schwab@suse.de>
f57669
Date:   Thu Feb 13 11:01:57 2014 +0100
f57669
f57669
    Fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer
f57669
f57669
commit ab7ac0f2cf8731fe4c3f3aea6088a7c0127b5725
f57669
Author: Ondřej Bílka <neleai@seznam.cz>
f57669
Date:   Sun Feb 16 12:59:23 2014 +0100
f57669
f57669
    Deduplicate resolv/nss_dns/dns-host.c
f57669
    
f57669
    In resolv/nss_dns/dns-host.c one of code path duplicated code after
f57669
    that. We merge these paths.
f57669
f57669
commit ab09bf616ad527b249aca5f2a4956fd526f0712f
f57669
Author: Andreas Schwab <schwab@suse.de>
f57669
Date:   Tue Feb 18 10:57:25 2014 +0100
f57669
f57669
    Properly fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer
f57669
    
f57669
    Instead of trying to guess whether the second buffer needs to be freed
f57669
    set a flag at the place it is allocated
f57669
f57669
Index: glibc-2.17-c758a686/include/resolv.h
f57669
===================================================================
f57669
--- glibc-2.17-c758a686.orig/include/resolv.h
f57669
+++ glibc-2.17-c758a686/include/resolv.h
f57669
@@ -56,11 +56,11 @@ libc_hidden_proto (__res_randomid)
f57669
 libc_hidden_proto (__res_state)
f57669
 
f57669
 int __libc_res_nquery (res_state, const char *, int, int, u_char *, int,
f57669
-		       u_char **, u_char **, int *, int *);
f57669
+		       u_char **, u_char **, int *, int *, int *);
f57669
 int __libc_res_nsearch (res_state, const char *, int, int, u_char *, int,
f57669
-			u_char **, u_char **, int *, int *);
f57669
+			u_char **, u_char **, int *, int *, int *);
f57669
 int __libc_res_nsend (res_state, const u_char *, int, const u_char *, int,
f57669
-		      u_char *, int, u_char **, u_char **, int *, int *)
f57669
+		      u_char *, int, u_char **, u_char **, int *, int *, int *)
f57669
   attribute_hidden;
f57669
 
f57669
 libresolv_hidden_proto (_sethtent)
f57669
Index: glibc-2.17-c758a686/resolv/gethnamaddr.c
f57669
===================================================================
f57669
--- glibc-2.17-c758a686.orig/resolv/gethnamaddr.c
f57669
+++ glibc-2.17-c758a686/resolv/gethnamaddr.c
f57669
@@ -616,7 +616,7 @@ gethostbyname2(name, af)
f57669
 	buf.buf = origbuf = (querybuf *) alloca (1024);
f57669
 
f57669
 	if ((n = __libc_res_nsearch(&_res, name, C_IN, type, buf.buf->buf, 1024,
f57669
-				    &buf.ptr, NULL, NULL, NULL)) < 0) {
f57669
+				    &buf.ptr, NULL, NULL, NULL, NULL)) < 0) {
f57669
 		if (buf.buf != origbuf)
f57669
 			free (buf.buf);
f57669
 		Dprintf("res_nsearch failed (%d)\n", n);
f57669
@@ -711,12 +711,12 @@ gethostbyaddr(addr, len, af)
f57669
 	buf.buf = orig_buf = (querybuf *) alloca (1024);
f57669
 
f57669
 	n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, 1024,
f57669
-			      &buf.ptr, NULL, NULL, NULL);
f57669
+			      &buf.ptr, NULL, NULL, NULL, NULL);
f57669
 	if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) {
f57669
 		strcpy(qp, "ip6.int");
f57669
 		n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf,
f57669
 				      buf.buf != orig_buf ? MAXPACKET : 1024,
f57669
-				      &buf.ptr, NULL, NULL, NULL);
f57669
+				      &buf.ptr, NULL, NULL, NULL, NULL);
f57669
 	}
f57669
 	if (n < 0) {
f57669
 		if (buf.buf != orig_buf)
f57669
Index: glibc-2.17-c758a686/resolv/nss_dns/dns-canon.c
f57669
===================================================================
f57669
--- glibc-2.17-c758a686.orig/resolv/nss_dns/dns-canon.c
f57669
+++ glibc-2.17-c758a686/resolv/nss_dns/dns-canon.c
f57669
@@ -61,7 +61,7 @@ _nss_dns_getcanonname_r (const char *nam
f57669
     {
f57669
       int r = __libc_res_nquery (&_res, name, ns_c_in, qtypes[i],
f57669
 				 buf, sizeof (buf), &ansp.ptr, NULL, NULL,
f57669
-				 NULL);
f57669
+				 NULL, NULL);
f57669
       if (r > 0)
f57669
 	{
f57669
 	  /* We need to decode the response.  Just one question record.
f57669
Index: glibc-2.17-c758a686/resolv/nss_dns/dns-host.c
f57669
===================================================================
f57669
--- glibc-2.17-c758a686.orig/resolv/nss_dns/dns-host.c
f57669
+++ glibc-2.17-c758a686/resolv/nss_dns/dns-host.c
f57669
@@ -190,7 +190,7 @@ _nss_dns_gethostbyname3_r (const char *n
f57669
   host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
f57669
 
f57669
   n = __libc_res_nsearch (&_res, name, C_IN, type, host_buffer.buf->buf,
f57669
-			  1024, &host_buffer.ptr, NULL, NULL, NULL);
f57669
+			  1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
f57669
   if (n < 0)
f57669
     {
f57669
       switch (errno)
f57669
@@ -225,7 +225,7 @@ _nss_dns_gethostbyname3_r (const char *n
f57669
 	n = __libc_res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf->buf,
f57669
 				host_buffer.buf != orig_host_buffer
f57669
 				? MAXPACKET : 1024, &host_buffer.ptr,
f57669
-				NULL, NULL, NULL);
f57669
+				NULL, NULL, NULL, NULL);
f57669
 
f57669
       if (n < 0)
f57669
 	{
f57669
@@ -308,13 +308,20 @@ _nss_dns_gethostbyname4_r (const char *n
f57669
   u_char *ans2p = NULL;
f57669
   int nans2p = 0;
f57669
   int resplen2 = 0;
f57669
+  int ans2p_malloced = 0;
f57669
 
f57669
   int olderr = errno;
f57669
   enum nss_status status;
f57669
   int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
f57669
 			      host_buffer.buf->buf, 2048, &host_buffer.ptr,
f57669
-			      &ans2p, &nans2p, &resplen2);
f57669
-  if (n < 0)
f57669
+			      &ans2p, &nans2p, &resplen2, &ans2p_malloced);
f57669
+  if (n >= 0)
f57669
+    {
f57669
+      status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p,
f57669
+			       resplen2, name, pat, buffer, buflen,
f57669
+			       errnop, herrnop, ttlp);
f57669
+    }
f57669
+  else
f57669
     {
f57669
       switch (errno)
f57669
 	{
f57669
@@ -341,16 +348,11 @@ _nss_dns_gethostbyname4_r (const char *n
f57669
 	*errnop = EAGAIN;
f57669
       else
f57669
 	__set_errno (olderr);
f57669
-
f57669
-      if (host_buffer.buf != orig_host_buffer)
f57669
-	free (host_buffer.buf);
f57669
-
f57669
-      return status;
f57669
     }
f57669
 
f57669
-  status = gaih_getanswer(host_buffer.buf, n, (const querybuf *) ans2p,
f57669
-			  resplen2, name, pat, buffer, buflen,
f57669
-			  errnop, herrnop, ttlp);
f57669
+  /* Check whether ans2p was separately allocated.  */
f57669
+  if (ans2p_malloced)
f57669
+    free (ans2p);
f57669
 
f57669
   if (host_buffer.buf != orig_host_buffer)
f57669
     free (host_buffer.buf);
f57669
@@ -460,7 +462,7 @@ _nss_dns_gethostbyaddr2_r (const void *a
f57669
 	  strcpy (qp, "].ip6.arpa");
f57669
 	  n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR,
f57669
 				 host_buffer.buf->buf, 1024, &host_buffer.ptr,
f57669
-				 NULL, NULL, NULL);
f57669
+				 NULL, NULL, NULL, NULL);
f57669
 	  if (n >= 0)
f57669
 	    goto got_it_already;
f57669
 	}
f57669
@@ -481,14 +483,14 @@ _nss_dns_gethostbyaddr2_r (const void *a
f57669
     }
f57669
 
f57669
   n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
f57669
-			 1024, &host_buffer.ptr, NULL, NULL, NULL);
f57669
+			 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
f57669
   if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0)
f57669
     {
f57669
       strcpy (qp, "ip6.int");
f57669
       n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
f57669
 			     host_buffer.buf != orig_host_buffer
f57669
 			     ? MAXPACKET : 1024, &host_buffer.ptr,
f57669
-			     NULL, NULL, NULL);
f57669
+			     NULL, NULL, NULL, NULL);
f57669
     }
f57669
   if (n < 0)
f57669
     {
f57669
Index: glibc-2.17-c758a686/resolv/nss_dns/dns-network.c
f57669
===================================================================
f57669
--- glibc-2.17-c758a686.orig/resolv/nss_dns/dns-network.c
f57669
+++ glibc-2.17-c758a686/resolv/nss_dns/dns-network.c
f57669
@@ -129,7 +129,7 @@ _nss_dns_getnetbyname_r (const char *nam
f57669
   net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
f57669
 
f57669
   anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
f57669
-			       1024, &net_buffer.ptr, NULL, NULL, NULL);
f57669
+			       1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
f57669
   if (anslen < 0)
f57669
     {
f57669
       /* Nothing found.  */
f57669
@@ -205,7 +205,7 @@ _nss_dns_getnetbyaddr_r (uint32_t net, i
f57669
   net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
f57669
 
f57669
   anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
f57669
-			      1024, &net_buffer.ptr, NULL, NULL, NULL);
f57669
+			      1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
f57669
   if (anslen < 0)
f57669
     {
f57669
       /* Nothing found.  */
f57669
Index: glibc-2.17-c758a686/resolv/res_query.c
f57669
===================================================================
f57669
--- glibc-2.17-c758a686.orig/resolv/res_query.c
f57669
+++ glibc-2.17-c758a686/resolv/res_query.c
f57669
@@ -98,7 +98,7 @@ static int
f57669
 __libc_res_nquerydomain(res_state statp, const char *name, const char *domain,
f57669
 			int class, int type, u_char *answer, int anslen,
f57669
 			u_char **answerp, u_char **answerp2, int *nanswerp2,
f57669
-			int *resplen2);
f57669
+			int *resplen2, int *answerp2_malloced);
f57669
 
f57669
 /*
f57669
  * Formulate a normal query, send, and await answer.
f57669
@@ -119,7 +119,8 @@ __libc_res_nquery(res_state statp,
f57669
 		  u_char **answerp,	/* if buffer needs to be enlarged */
f57669
 		  u_char **answerp2,
f57669
 		  int *nanswerp2,
f57669
-		  int *resplen2)
f57669
+		  int *resplen2,
f57669
+		  int *answerp2_malloced)
f57669
 {
f57669
 	HEADER *hp = (HEADER *) answer;
f57669
 	HEADER *hp2;
f57669
@@ -224,7 +225,8 @@ __libc_res_nquery(res_state statp,
f57669
 	}
f57669
 	assert (answerp == NULL || (void *) *answerp == (void *) answer);
f57669
 	n = __libc_res_nsend(statp, query1, nquery1, query2, nquery2, answer,
f57669
-			     anslen, answerp, answerp2, nanswerp2, resplen2);
f57669
+			     anslen, answerp, answerp2, nanswerp2, resplen2,
f57669
+			     answerp2_malloced);
f57669
 	if (use_malloc)
f57669
 		free (buf);
f57669
 	if (n < 0) {
f57669
@@ -316,7 +318,7 @@ res_nquery(res_state statp,
f57669
 	   int anslen)		/* size of answer buffer */
f57669
 {
f57669
 	return __libc_res_nquery(statp, name, class, type, answer, anslen,
f57669
-				 NULL, NULL, NULL, NULL);
f57669
+				 NULL, NULL, NULL, NULL, NULL);
f57669
 }
f57669
 libresolv_hidden_def (res_nquery)
f57669
 
f57669
@@ -335,7 +337,8 @@ __libc_res_nsearch(res_state statp,
f57669
 		   u_char **answerp,
f57669
 		   u_char **answerp2,
f57669
 		   int *nanswerp2,
f57669
-		   int *resplen2)
f57669
+		   int *resplen2,
f57669
+		   int *answerp2_malloced)
f57669
 {
f57669
 	const char *cp, * const *domain;
f57669
 	HEADER *hp = (HEADER *) answer;
f57669
@@ -360,7 +363,7 @@ __libc_res_nsearch(res_state statp,
f57669
 	if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL)
f57669
 		return (__libc_res_nquery(statp, cp, class, type, answer,
f57669
 					  anslen, answerp, answerp2,
f57669
-					  nanswerp2, resplen2));
f57669
+					  nanswerp2, resplen2, answerp2_malloced));
f57669
 
f57669
 #ifdef DEBUG
f57669
 	if (statp->options & RES_DEBUG)
f57669
@@ -377,7 +380,8 @@ __libc_res_nsearch(res_state statp,
f57669
 	if (dots >= statp->ndots || trailing_dot) {
f57669
 		ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
f57669
 					      answer, anslen, answerp,
f57669
-					      answerp2, nanswerp2, resplen2);
f57669
+					      answerp2, nanswerp2, resplen2,
f57669
+					      answerp2_malloced);
f57669
 		if (ret > 0 || trailing_dot
f57669
 		    /* If the second response is valid then we use that.  */
f57669
 		    || (ret == 0 && resplen2 != NULL && *resplen2 > 0))
f57669
@@ -388,11 +392,11 @@ __libc_res_nsearch(res_state statp,
f57669
 			answer = *answerp;
f57669
 			anslen = MAXPACKET;
f57669
 		}
f57669
-		if (answerp2
f57669
-		    && (*answerp2 < answer || *answerp2 >= answer + anslen))
f57669
+		if (answerp2 && *answerp2_malloced)
f57669
 		  {
f57669
 		    free (*answerp2);
f57669
 		    *answerp2 = NULL;
f57669
+		    *answerp2_malloced = 0;
f57669
 		  }
f57669
 	}
f57669
 
f57669
@@ -419,7 +423,7 @@ __libc_res_nsearch(res_state statp,
f57669
 						      class, type,
f57669
 						      answer, anslen, answerp,
f57669
 						      answerp2, nanswerp2,
f57669
-						      resplen2);
f57669
+						      resplen2, answerp2_malloced);
f57669
 			if (ret > 0 || (ret == 0 && resplen2 != NULL
f57669
 					&& *resplen2 > 0))
f57669
 				return (ret);
f57669
@@ -428,12 +432,11 @@ __libc_res_nsearch(res_state statp,
f57669
 				answer = *answerp;
f57669
 				anslen = MAXPACKET;
f57669
 			}
f57669
-			if (answerp2
f57669
-			    && (*answerp2 < answer
f57669
-				|| *answerp2 >= answer + anslen))
f57669
+			if (answerp2 && *answerp2_malloced)
f57669
 			  {
f57669
 			    free (*answerp2);
f57669
 			    *answerp2 = NULL;
f57669
+			    *answerp2_malloced = 0;
f57669
 			  }
f57669
 
f57669
 			/*
f57669
@@ -489,7 +492,8 @@ __libc_res_nsearch(res_state statp,
f57669
 	    && !(tried_as_is || root_on_list)) {
f57669
 		ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
f57669
 					      answer, anslen, answerp,
f57669
-					      answerp2, nanswerp2, resplen2);
f57669
+					      answerp2, nanswerp2, resplen2,
f57669
+					      answerp2_malloced);
f57669
 		if (ret > 0 || (ret == 0 && resplen2 != NULL
f57669
 				&& *resplen2 > 0))
f57669
 			return (ret);
f57669
@@ -502,10 +506,11 @@ __libc_res_nsearch(res_state statp,
f57669
 	 * else send back meaningless H_ERRNO, that being the one from
f57669
 	 * the last DNSRCH we did.
f57669
 	 */
f57669
-	if (answerp2 && (*answerp2 < answer || *answerp2 >= answer + anslen))
f57669
+	if (answerp2 && *answerp2_malloced)
f57669
 	  {
f57669
 	    free (*answerp2);
f57669
 	    *answerp2 = NULL;
f57669
+	    *answerp2_malloced = 0;
f57669
 	  }
f57669
 	if (saved_herrno != -1)
f57669
 		RES_SET_H_ERRNO(statp, saved_herrno);
f57669
@@ -525,7 +530,7 @@ res_nsearch(res_state statp,
f57669
 	    int anslen)		/* size of answer */
f57669
 {
f57669
 	return __libc_res_nsearch(statp, name, class, type, answer,
f57669
-				  anslen, NULL, NULL, NULL, NULL);
f57669
+				  anslen, NULL, NULL, NULL, NULL, NULL);
f57669
 }
f57669
 libresolv_hidden_def (res_nsearch)
f57669
 
f57669
@@ -543,7 +548,8 @@ __libc_res_nquerydomain(res_state statp,
f57669
 			u_char **answerp,
f57669
 			u_char **answerp2,
f57669
 			int *nanswerp2,
f57669
-			int *resplen2)
f57669
+			int *resplen2,
f57669
+			int *answerp2_malloced)
f57669
 {
f57669
 	char nbuf[MAXDNAME];
f57669
 	const char *longname = nbuf;
f57669
@@ -585,7 +591,7 @@ __libc_res_nquerydomain(res_state statp,
f57669
 	}
f57669
 	return (__libc_res_nquery(statp, longname, class, type, answer,
f57669
 				  anslen, answerp, answerp2, nanswerp2,
f57669
-				  resplen2));
f57669
+				  resplen2, answerp2_malloced));
f57669
 }
f57669
 
f57669
 int
f57669
@@ -597,7 +603,8 @@ res_nquerydomain(res_state statp,
f57669
 	    int anslen)		/* size of answer */
f57669
 {
f57669
 	return __libc_res_nquerydomain(statp, name, domain, class, type,
f57669
-				       answer, anslen, NULL, NULL, NULL, NULL);
f57669
+				       answer, anslen, NULL, NULL, NULL, NULL,
f57669
+				       NULL);
f57669
 }
f57669
 libresolv_hidden_def (res_nquerydomain)
f57669
 
f57669
Index: glibc-2.17-c758a686/resolv/res_send.c
f57669
===================================================================
f57669
--- glibc-2.17-c758a686.orig/resolv/res_send.c
f57669
+++ glibc-2.17-c758a686/resolv/res_send.c
f57669
@@ -186,12 +186,12 @@ evNowTime(struct timespec *res) {
f57669
 static int		send_vc(res_state, const u_char *, int,
f57669
 				const u_char *, int,
f57669
 				u_char **, int *, int *, int, u_char **,
f57669
-				u_char **, int *, int *);
f57669
+				u_char **, int *, int *, int *);
f57669
 static int		send_dg(res_state, const u_char *, int,
f57669
 				const u_char *, int,
f57669
 				u_char **, int *, int *, int,
f57669
 				int *, int *, u_char **,
f57669
-				u_char **, int *, int *);
f57669
+				u_char **, int *, int *, int *);
f57669
 #ifdef DEBUG
f57669
 static void		Aerror(const res_state, FILE *, const char *, int,
f57669
 			       const struct sockaddr *);
f57669
@@ -343,7 +343,7 @@ int
f57669
 __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
f57669
 		 const u_char *buf2, int buflen2,
f57669
 		 u_char *ans, int anssiz, u_char **ansp, u_char **ansp2,
f57669
-		 int *nansp2, int *resplen2)
f57669
+		 int *nansp2, int *resplen2, int *ansp2_malloced)
f57669
 {
f57669
   int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
f57669
 
f57669
@@ -546,7 +546,8 @@ __libc_res_nsend(res_state statp, const
f57669
 			try = statp->retry;
f57669
 			n = send_vc(statp, buf, buflen, buf2, buflen2,
f57669
 				    &ans, &anssiz, &terrno,
f57669
-				    ns, ansp, ansp2, nansp2, resplen2);
f57669
+				    ns, ansp, ansp2, nansp2, resplen2,
f57669
+				    ansp2_malloced);
f57669
 			if (n < 0)
f57669
 				return (-1);
f57669
 			if (n == 0 && (buf2 == NULL || *resplen2 == 0))
f57669
@@ -556,7 +557,7 @@ __libc_res_nsend(res_state statp, const
f57669
 			n = send_dg(statp, buf, buflen, buf2, buflen2,
f57669
 				    &ans, &anssiz, &terrno,
f57669
 				    ns, &v_circuit, &gotsomewhere, ansp,
f57669
-				    ansp2, nansp2, resplen2);
f57669
+				    ansp2, nansp2, resplen2, ansp2_malloced);
f57669
 			if (n < 0)
f57669
 				return (-1);
f57669
 			if (n == 0 && (buf2 == NULL || *resplen2 == 0))
f57669
@@ -646,7 +647,7 @@ res_nsend(res_state statp,
f57669
 	  const u_char *buf, int buflen, u_char *ans, int anssiz)
f57669
 {
f57669
   return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz,
f57669
-			  NULL, NULL, NULL, NULL);
f57669
+			  NULL, NULL, NULL, NULL, NULL);
f57669
 }
f57669
 libresolv_hidden_def (res_nsend)
f57669
 
f57669
@@ -657,7 +658,7 @@ send_vc(res_state statp,
f57669
 	const u_char *buf, int buflen, const u_char *buf2, int buflen2,
f57669
 	u_char **ansp, int *anssizp,
f57669
 	int *terrno, int ns, u_char **anscp, u_char **ansp2, int *anssizp2,
f57669
-	int *resplen2)
f57669
+	int *resplen2, int *ansp2_malloced)
f57669
 {
f57669
 	const HEADER *hp = (HEADER *) buf;
f57669
 	const HEADER *hp2 = (HEADER *) buf2;
f57669
@@ -823,6 +824,8 @@ send_vc(res_state statp,
f57669
 			}
f57669
 			*thisanssizp = MAXPACKET;
f57669
 			*thisansp = newp;
f57669
+			if (thisansp == ansp2)
f57669
+			  *ansp2_malloced = 1;
f57669
 			anhp = (HEADER *) newp;
f57669
 			len = rlen;
f57669
 		} else {
f57669
@@ -992,7 +995,7 @@ send_dg(res_state statp,
f57669
 	const u_char *buf, int buflen, const u_char *buf2, int buflen2,
f57669
 	u_char **ansp, int *anssizp,
f57669
 	int *terrno, int ns, int *v_circuit, int *gotsomewhere, u_char **anscp,
f57669
-	u_char **ansp2, int *anssizp2, int *resplen2)
f57669
+	u_char **ansp2, int *anssizp2, int *resplen2, int *ansp2_malloced)
f57669
 {
f57669
 	const HEADER *hp = (HEADER *) buf;
f57669
 	const HEADER *hp2 = (HEADER *) buf2;
f57669
@@ -1235,6 +1238,8 @@ send_dg(res_state statp,
f57669
 			if (newp != NULL) {
f57669
 				*anssizp = MAXPACKET;
f57669
 				*thisansp = ans = newp;
f57669
+				if (thisansp == ansp2)
f57669
+				  *ansp2_malloced = 1;
f57669
 			}
f57669
 		}
f57669
 		HEADER *anhp = (HEADER *) *thisansp;