summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Klug <john.klug@multitech.com>2017-07-24 17:43:40 -0500
committerJohn Klug <john.klug@multitech.com>2017-07-24 17:43:40 -0500
commit7312dd24edebda4a9a54debe7c8ac9064e4bd136 (patch)
tree16af0aeab5ffbe06247255f6d4bb19e1eb5f4d0b
parentf34571efbffb4b69ad74d0d72e7f3bf885b3a523 (diff)
downloadmeta-mlinux-7312dd24edebda4a9a54debe7c8ac9064e4bd136.tar.gz
meta-mlinux-7312dd24edebda4a9a54debe7c8ac9064e4bd136.tar.bz2
meta-mlinux-7312dd24edebda4a9a54debe7c8ac9064e4bd136.zip
Fix the gethostbyname memory leak
-rw-r--r--recipes-core/eglibc/eglibc_%.bbappend4
-rw-r--r--recipes-core/eglibc/files/cvs-gethostbyname4-memory-leak.patch648
2 files changed, 652 insertions, 0 deletions
diff --git a/recipes-core/eglibc/eglibc_%.bbappend b/recipes-core/eglibc/eglibc_%.bbappend
new file mode 100644
index 0000000..ece3df9
--- /dev/null
+++ b/recipes-core/eglibc/eglibc_%.bbappend
@@ -0,0 +1,4 @@
+SRC_URI += " file://cvs-gethostbyname4-memory-leak.patch \
+ "
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/files"
diff --git a/recipes-core/eglibc/files/cvs-gethostbyname4-memory-leak.patch b/recipes-core/eglibc/files/cvs-gethostbyname4-memory-leak.patch
new file mode 100644
index 0000000..3b66a60
--- /dev/null
+++ b/recipes-core/eglibc/files/cvs-gethostbyname4-memory-leak.patch
@@ -0,0 +1,648 @@
+diff -Naur '--exclude=.git' '--exclude=*.pyc' '--exclude=*.py' '--exclude=*.*~' libc.orig/include/arpa/nameser_compat.h libc/include/arpa/nameser_compat.h
+--- libc.orig/include/arpa/nameser_compat.h 2008-05-12 11:38:35.000000000 -0400
++++ libc/include/arpa/nameser_compat.h 2017-04-06 16:34:20.413823000 -0400
+@@ -1,8 +1,8 @@
+ #ifndef _ARPA_NAMESER_COMPAT_
+ #include <resolv/arpa/nameser_compat.h>
+
+-/* Picksome unused number to represent lookups of IPv4 and IPv6 (i.e.,
+- T_A and T_AAAA). */
+-#define T_UNSPEC 62321
++/* The number is outside the 16-bit RR type range and is used
++ internally by the implementation. */
++#define T_QUERY_A_AND_AAAA 439963904
+
+ #endif
+diff -Naur '--exclude=.git' '--exclude=*.pyc' '--exclude=*.py' '--exclude=*.*~' libc.orig/include/resolv.h libc/include/resolv.h
+--- libc.orig/include/resolv.h 2013-09-05 18:41:05.000000000 -0400
++++ libc/include/resolv.h 2017-04-06 16:33:09.853700600 -0400
+@@ -48,11 +48,11 @@
+ libc_hidden_proto (__res_state)
+
+ int __libc_res_nquery (res_state, const char *, int, int, u_char *, int,
+- u_char **, u_char **, int *, int *);
++ u_char **, u_char **, int *, int *, int *);
+ int __libc_res_nsearch (res_state, const char *, int, int, u_char *, int,
+- u_char **, u_char **, int *, int *);
++ u_char **, u_char **, int *, int *, int *);
+ int __libc_res_nsend (res_state, const u_char *, int, const u_char *, int,
+- u_char *, int, u_char **, u_char **, int *, int *)
++ u_char *, int, u_char **, u_char **, int *, int *, int *)
+ attribute_hidden;
+
+ libresolv_hidden_proto (_sethtent)
+diff -Naur '--exclude=.git' '--exclude=*.pyc' '--exclude=*.py' '--exclude=*.*~' libc.orig/resolv/gethnamaddr.c libc/resolv/gethnamaddr.c
+--- libc.orig/resolv/gethnamaddr.c 2013-06-15 13:37:04.000000000 -0400
++++ libc/resolv/gethnamaddr.c 2017-04-06 16:13:44.727609300 -0400
+@@ -621,7 +621,7 @@
+ buf.buf = origbuf = (querybuf *) alloca (1024);
+
+ if ((n = __libc_res_nsearch(&_res, name, C_IN, type, buf.buf->buf, 1024,
+- &buf.ptr, NULL, NULL, NULL)) < 0) {
++ &buf.ptr, NULL, NULL, NULL, NULL)) < 0) {
+ if (buf.buf != origbuf)
+ free (buf.buf);
+ Dprintf("res_nsearch failed (%d)\n", n);
+@@ -716,12 +716,12 @@
+ buf.buf = orig_buf = (querybuf *) alloca (1024);
+
+ n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, 1024,
+- &buf.ptr, NULL, NULL, NULL);
++ &buf.ptr, NULL, NULL, NULL, NULL);
+ if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) {
+ strcpy(qp, "ip6.int");
+ n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf,
+ buf.buf != orig_buf ? MAXPACKET : 1024,
+- &buf.ptr, NULL, NULL, NULL);
++ &buf.ptr, NULL, NULL, NULL, NULL);
+ }
+ if (n < 0) {
+ if (buf.buf != orig_buf)
+diff -Naur '--exclude=.git' '--exclude=*.pyc' '--exclude=*.py' '--exclude=*.*~' libc.orig/resolv/nss_dns/dns-canon.c libc/resolv/nss_dns/dns-canon.c
+--- libc.orig/resolv/nss_dns/dns-canon.c 2014-01-03 12:51:28.000000000 -0500
++++ libc/resolv/nss_dns/dns-canon.c 2017-04-06 16:11:49.654787500 -0400
+@@ -62,7 +62,7 @@
+ {
+ int r = __libc_res_nquery (&_res, name, ns_c_in, qtypes[i],
+ buf, sizeof (buf), &ansp.ptr, NULL, NULL,
+- NULL);
++ NULL, NULL);
+ if (r > 0)
+ {
+ /* We need to decode the response. Just one question record.
+diff -Naur '--exclude=.git' '--exclude=*.pyc' '--exclude=*.py' '--exclude=*.*~' libc.orig/resolv/nss_dns/dns-host.c libc/resolv/nss_dns/dns-host.c
+--- libc.orig/resolv/nss_dns/dns-host.c 2017-04-06 14:03:55.000000000 -0400
++++ libc/resolv/nss_dns/dns-host.c 2017-04-06 16:12:50.319551700 -0400
+@@ -190,7 +190,7 @@
+ host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
+
+ n = __libc_res_nsearch (&_res, name, C_IN, type, host_buffer.buf->buf,
+- 1024, &host_buffer.ptr, NULL, NULL, NULL);
++ 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
+ if (n < 0)
+ {
+ switch (errno)
+@@ -225,7 +225,7 @@
+ n = __libc_res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf->buf,
+ host_buffer.buf != orig_host_buffer
+ ? MAXPACKET : 1024, &host_buffer.ptr,
+- NULL, NULL, NULL);
++ NULL, NULL, NULL, NULL);
+
+ if (n < 0)
+ {
+@@ -308,12 +308,13 @@
+ u_char *ans2p = NULL;
+ int nans2p = 0;
+ int resplen2 = 0;
++ int ans2p_malloced = 0;
+
+ int olderr = errno;
+ enum nss_status status;
+- int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
++ int n = __libc_res_nsearch (&_res, name, C_IN, T_QUERY_A_AND_AAAA,
+ host_buffer.buf->buf, 2048, &host_buffer.ptr,
+- &ans2p, &nans2p, &resplen2);
++ &ans2p, &nans2p, &resplen2, &ans2p_malloced);
+ if (n < 0)
+ {
+ switch (errno)
+@@ -352,6 +353,10 @@
+ resplen2, name, pat, buffer, buflen,
+ errnop, herrnop, ttlp);
+
++ /* Check whether ans2p was separately allocated. */
++ if (ans2p_malloced)
++ free (ans2p);
++
+ if (host_buffer.buf != orig_host_buffer)
+ free (host_buffer.buf);
+
+@@ -460,7 +465,7 @@
+ strcpy (qp, "].ip6.arpa");
+ n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR,
+ host_buffer.buf->buf, 1024, &host_buffer.ptr,
+- NULL, NULL, NULL);
++ NULL, NULL, NULL, NULL);
+ if (n >= 0)
+ goto got_it_already;
+ }
+@@ -481,14 +486,14 @@
+ }
+
+ n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
+- 1024, &host_buffer.ptr, NULL, NULL, NULL);
++ 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
+ if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0)
+ {
+ strcpy (qp, "ip6.int");
+ n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
+ host_buffer.buf != orig_host_buffer
+ ? MAXPACKET : 1024, &host_buffer.ptr,
+- NULL, NULL, NULL);
++ NULL, NULL, NULL, NULL);
+ }
+ if (n < 0)
+ {
+@@ -613,7 +618,8 @@
+ int have_to_map = 0;
+ uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
+ buffer += pad;
+- if (__builtin_expect (buflen < sizeof (struct host_data) + pad, 0))
++ buflen = buflen > pad ? buflen - pad : 0;
++ if (__glibc_unlikely (buflen < sizeof (struct host_data)))
+ {
+ /* The buffer is too small. */
+ too_small:
+@@ -1267,8 +1273,8 @@
+ expected application behaviour. Some of the synthesized responses
+ aren't very well thought out and sometimes appear to imply that
+ IPv4 responses are always answer 1, and IPv6 responses are always
+- answer 2, but that's not true (see the implementation of send_dg
+- and send_vc to see response can arrive in any order, particularly
++ answer 2, but that's not true (see the implemetnation of send_dg
++ and send_vc to see response can arrive in any order, particlarly
+ for UDP). However, we expect it holds roughly enough of the time
+ that this code works, but certainly needs to be fixed to make this
+ a more robust implementation.
+@@ -1305,12 +1311,12 @@
+ ----------------------------------------------
+
+ [1] If the first response is a success we return success.
+- This ignores the state of the second answer and in fact
+- incorrectly sets errno and h_errno to that of the second
++ This ignores the state of the second answer and in fact
++ incorrectly sets errno and h_errno to that of the second
+ answer. However because the response is a success we ignore
+ *errnop and *h_errnop (though that means you touched errno on
+- success). We are being conservative here and returning the
+- likely IPv4 response in the first answer as a success.
++ success). We are being conservative here and returning the
++ likely IPv4 response in the first answer as a success.
+
+ [2] If the first response is a recoverable TRYAGAIN we return
+ that instead of looking at the second response. The
+@@ -1364,7 +1370,7 @@
+ if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND)
+ status = status2;
+ /* Do not return a truncated second response (unless it was
+- unavoidable e.g. unrecoverable TRYAGAIN). */
++ unavoidable e.g. unrecoverable TRYAGAIN). */
+ if (status == NSS_STATUS_SUCCESS
+ && (status2 == NSS_STATUS_TRYAGAIN
+ && *errnop == ERANGE && *h_errnop != NO_RECOVERY))
+diff -Naur '--exclude=.git' '--exclude=*.pyc' '--exclude=*.py' '--exclude=*.*~' libc.orig/resolv/nss_dns/dns-network.c libc/resolv/nss_dns/dns-network.c
+--- libc.orig/resolv/nss_dns/dns-network.c 2014-01-03 12:51:28.000000000 -0500
++++ libc/resolv/nss_dns/dns-network.c 2017-04-06 16:13:18.561373600 -0400
+@@ -118,18 +118,15 @@
+ } net_buffer;
+ querybuf *orig_net_buffer;
+ int anslen;
+- char *qbuf;
+ enum nss_status status;
+
+ if (__res_maybe_init (&_res, 0) == -1)
+ return NSS_STATUS_UNAVAIL;
+
+- qbuf = strdupa (name);
+-
+ net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
+
+- anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
+- 1024, &net_buffer.ptr, NULL, NULL, NULL);
++ anslen = __libc_res_nsearch (&_res, name, C_IN, T_PTR, net_buffer.buf->buf,
++ 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
+ if (anslen < 0)
+ {
+ /* Nothing found. */
+@@ -205,7 +202,7 @@
+ net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
+
+ anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
+- 1024, &net_buffer.ptr, NULL, NULL, NULL);
++ 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
+ if (anslen < 0)
+ {
+ /* Nothing found. */
+@@ -398,8 +395,8 @@
+
+ case BYNAME:
+ {
+- char **ap = result->n_aliases++;
+- while (*ap != NULL)
++ char **ap;
++ for (ap = result->n_aliases; *ap != NULL; ++ap)
+ {
+ /* Check each alias name for being of the forms:
+ 4.3.2.1.in-addr.arpa = net 1.2.3.4
+diff -Naur '--exclude=.git' '--exclude=*.pyc' '--exclude=*.py' '--exclude=*.*~' libc.orig/resolv/res_mkquery.c libc/resolv/res_mkquery.c
+--- libc.orig/resolv/res_mkquery.c 2013-09-05 18:41:05.000000000 -0400
++++ libc/resolv/res_mkquery.c 2017-04-06 16:13:56.412597600 -0400
+@@ -110,6 +110,10 @@
+ int n;
+ u_char *dnptrs[20], **dpp, **lastdnptr;
+
++ if (class < 0 || class > 65535
++ || type < 0 || type > 65535)
++ return -1;
++
+ #ifdef DEBUG
+ if (statp->options & RES_DEBUG)
+ printf(";; res_nmkquery(%s, %s, %s, %s)\n",
+diff -Naur '--exclude=.git' '--exclude=*.pyc' '--exclude=*.py' '--exclude=*.*~' libc.orig/resolv/res_query.c libc/resolv/res_query.c
+--- libc.orig/resolv/res_query.c 2017-04-06 14:03:55.000000000 -0400
++++ libc/resolv/res_query.c 2017-04-06 16:15:04.137842200 -0400
+@@ -98,7 +98,7 @@
+ __libc_res_nquerydomain(res_state statp, const char *name, const char *domain,
+ int class, int type, u_char *answer, int anslen,
+ u_char **answerp, u_char **answerp2, int *nanswerp2,
+- int *resplen2);
++ int *resplen2, int *answerp2_malloced);
+
+ /*
+ * Formulate a normal query, send, and await answer.
+@@ -119,14 +119,15 @@
+ u_char **answerp, /* if buffer needs to be enlarged */
+ u_char **answerp2,
+ int *nanswerp2,
+- int *resplen2)
++ int *resplen2,
++ int *answerp2_malloced)
+ {
+ HEADER *hp = (HEADER *) answer;
+ HEADER *hp2;
+ int n, use_malloc = 0;
+ u_int oflags = statp->_flags;
+
+- size_t bufsize = (type == T_UNSPEC ? 2 : 1) * QUERYSIZE;
++ size_t bufsize = (type == T_QUERY_A_AND_AAAA ? 2 : 1) * QUERYSIZE;
+ u_char *buf = alloca (bufsize);
+ u_char *query1 = buf;
+ int nquery1 = -1;
+@@ -141,7 +142,7 @@
+ printf(";; res_query(%s, %d, %d)\n", name, class, type);
+ #endif
+
+- if (type == T_UNSPEC)
++ if (type == T_QUERY_A_AND_AAAA)
+ {
+ n = res_nmkquery(statp, QUERY, name, class, T_A, NULL, 0, NULL,
+ query1, bufsize);
+@@ -194,7 +195,7 @@
+ if (__builtin_expect (n <= 0, 0) && !use_malloc) {
+ /* Retry just in case res_nmkquery failed because of too
+ short buffer. Shouldn't happen. */
+- bufsize = (type == T_UNSPEC ? 2 : 1) * MAXPACKET;
++ bufsize = (type == T_QUERY_A_AND_AAAA ? 2 : 1) * MAXPACKET;
+ buf = malloc (bufsize);
+ if (buf != NULL) {
+ query1 = buf;
+@@ -224,7 +225,8 @@
+ }
+ assert (answerp == NULL || (void *) *answerp == (void *) answer);
+ n = __libc_res_nsend(statp, query1, nquery1, query2, nquery2, answer,
+- anslen, answerp, answerp2, nanswerp2, resplen2);
++ anslen, answerp, answerp2, nanswerp2, resplen2,
++ answerp2_malloced);
+ if (use_malloc)
+ free (buf);
+ if (n < 0) {
+@@ -316,7 +318,7 @@
+ int anslen) /* size of answer buffer */
+ {
+ return __libc_res_nquery(statp, name, class, type, answer, anslen,
+- NULL, NULL, NULL, NULL);
++ NULL, NULL, NULL, NULL, NULL);
+ }
+ libresolv_hidden_def (res_nquery)
+
+@@ -335,7 +337,8 @@
+ u_char **answerp,
+ u_char **answerp2,
+ int *nanswerp2,
+- int *resplen2)
++ int *resplen2,
++ int *answerp2_malloced)
+ {
+ const char *cp, * const *domain;
+ HEADER *hp = (HEADER *) answer;
+@@ -360,7 +363,7 @@
+ if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL)
+ return (__libc_res_nquery(statp, cp, class, type, answer,
+ anslen, answerp, answerp2,
+- nanswerp2, resplen2));
++ nanswerp2, resplen2, answerp2_malloced));
+
+ #ifdef DEBUG
+ if (statp->options & RES_DEBUG)
+@@ -377,8 +380,9 @@
+ if (dots >= statp->ndots || trailing_dot) {
+ ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
+ answer, anslen, answerp,
+- answerp2, nanswerp2, resplen2);
+- if (ret > 0 || trailing_dot)
++ answerp2, nanswerp2, resplen2,
++ answerp2_malloced);
++ if (ret > 0 || (ret == 0 && *resplen2 > 0) || trailing_dot)
+ return (ret);
+ saved_herrno = h_errno;
+ tried_as_is++;
+@@ -386,12 +390,12 @@
+ answer = *answerp;
+ anslen = MAXPACKET;
+ }
+- if (answerp2
+- && (*answerp2 < answer || *answerp2 >= answer + anslen))
++ if (answerp2 && *answerp2_malloced)
+ {
+ free (*answerp2);
+ *answerp2 = NULL;
+ *nanswerp2 = 0;
++ *answerp2_malloced = 0;
+ }
+ }
+
+@@ -418,21 +422,20 @@
+ class, type,
+ answer, anslen, answerp,
+ answerp2, nanswerp2,
+- resplen2);
+- if (ret > 0)
++ resplen2, answerp2_malloced);
++ if ((ret > 0) || (ret == 0 && *resplen2 > 0))
+ return (ret);
+
+ if (answerp && *answerp != answer) {
+ answer = *answerp;
+ anslen = MAXPACKET;
+ }
+- if (answerp2
+- && (*answerp2 < answer
+- || *answerp2 >= answer + anslen))
++ if (answerp2 && *answerp2_malloced)
+ {
+ free (*answerp2);
+ *answerp2 = NULL;
+ *nanswerp2 = 0;
++ *answerp2_malloced = 0;
+ }
+
+ /*
+@@ -488,8 +491,9 @@
+ && !(tried_as_is || root_on_list)) {
+ ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
+ answer, anslen, answerp,
+- answerp2, nanswerp2, resplen2);
+- if (ret > 0)
++ answerp2, nanswerp2, resplen2,
++ answerp2_malloced);
++ if ((ret > 0) || (ret == 0 && *resplen2 > 0))
+ return (ret);
+ }
+
+@@ -500,11 +504,12 @@
+ * else send back meaningless H_ERRNO, that being the one from
+ * the last DNSRCH we did.
+ */
+- if (answerp2 && (*answerp2 < answer || *answerp2 >= answer + anslen))
++ if (answerp2 && *answerp2_malloced)
+ {
+ free (*answerp2);
+ *answerp2 = NULL;
+ *nanswerp2 = 0;
++ *answerp2_malloced = 0;
+ }
+ if (saved_herrno != -1)
+ RES_SET_H_ERRNO(statp, saved_herrno);
+@@ -524,7 +529,7 @@
+ int anslen) /* size of answer */
+ {
+ return __libc_res_nsearch(statp, name, class, type, answer,
+- anslen, NULL, NULL, NULL, NULL);
++ anslen, NULL, NULL, NULL, NULL, NULL);
+ }
+ libresolv_hidden_def (res_nsearch)
+
+@@ -542,7 +547,8 @@
+ u_char **answerp,
+ u_char **answerp2,
+ int *nanswerp2,
+- int *resplen2)
++ int *resplen2,
++ int *answerp2_malloced)
+ {
+ char nbuf[MAXDNAME];
+ const char *longname = nbuf;
+@@ -584,7 +590,7 @@
+ }
+ return (__libc_res_nquery(statp, longname, class, type, answer,
+ anslen, answerp, answerp2, nanswerp2,
+- resplen2));
++ resplen2, answerp2_malloced));
+ }
+
+ int
+@@ -596,7 +602,8 @@
+ int anslen) /* size of answer */
+ {
+ return __libc_res_nquerydomain(statp, name, domain, class, type,
+- answer, anslen, NULL, NULL, NULL, NULL);
++ answer, anslen, NULL, NULL, NULL, NULL,
++ NULL);
+ }
+ libresolv_hidden_def (res_nquerydomain)
+
+diff -Naur '--exclude=.git' '--exclude=*.pyc' '--exclude=*.py' '--exclude=*.*~' libc.orig/resolv/res_send.c libc/resolv/res_send.c
+--- libc.orig/resolv/res_send.c 2017-04-06 14:03:55.000000000 -0400
++++ libc/resolv/res_send.c 2017-04-06 16:16:12.448561400 -0400
+@@ -120,13 +120,13 @@
+ #define MAXPACKET 65536
+ #endif
+
+-
++#ifdef SOCK_NONBLOCK
+ #ifndef __ASSUME_SOCK_CLOEXEC
+ static int __have_o_nonblock;
+ #else
+ # define __have_o_nonblock 0
+ #endif
+-
++#endif
+
+ /* From ev_streams.c. */
+
+@@ -203,12 +203,12 @@
+ static int send_vc(res_state, const u_char *, int,
+ const u_char *, int,
+ u_char **, int *, int *, int, u_char **,
+- u_char **, int *, int *);
++ u_char **, int *, int *, int *);
+ static int send_dg(res_state, const u_char *, int,
+ const u_char *, int,
+ u_char **, int *, int *, int,
+ int *, int *, u_char **,
+- u_char **, int *, int *);
++ u_char **, int *, int *, int *);
+ #ifdef DEBUG
+ static void Aerror(const res_state, FILE *, const char *, int,
+ const struct sockaddr *);
+@@ -360,7 +360,7 @@
+ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
+ const u_char *buf2, int buflen2,
+ u_char *ans, int anssiz, u_char **ansp, u_char **ansp2,
+- int *nansp2, int *resplen2)
++ int *nansp2, int *resplen2, int *ansp2_malloced)
+ {
+ int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
+
+@@ -565,7 +565,8 @@
+ try = statp->retry;
+ n = send_vc(statp, buf, buflen, buf2, buflen2,
+ &ans, &anssiz, &terrno,
+- ns, ansp, ansp2, nansp2, resplen2);
++ ns, ansp, ansp2, nansp2, resplen2,
++ ansp2_malloced);
+ if (n < 0)
+ return (-1);
+ if (n == 0 && (buf2 == NULL || *resplen2 == 0))
+@@ -575,7 +576,7 @@
+ n = send_dg(statp, buf, buflen, buf2, buflen2,
+ &ans, &anssiz, &terrno,
+ ns, &v_circuit, &gotsomewhere, ansp,
+- ansp2, nansp2, resplen2);
++ ansp2, nansp2, resplen2, ansp2_malloced);
+ if (n < 0)
+ return (-1);
+ if (n == 0 && (buf2 == NULL || *resplen2 == 0))
+@@ -665,7 +666,7 @@
+ const u_char *buf, int buflen, u_char *ans, int anssiz)
+ {
+ return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz,
+- NULL, NULL, NULL, NULL);
++ NULL, NULL, NULL, NULL, NULL);
+ }
+ libresolv_hidden_def (res_nsend)
+
+@@ -709,7 +710,7 @@
+ are needed but ANSCP is NULL, then as much of the response as
+ possible is read into the buffer, but the results will be truncated.
+ When truncation happens because of a small answer buffer the DNS
+- packets header field TC will bet set to 1, indicating a truncated
++ packets header feild TC will bet set to 1, indicating a truncated
+ message and the rest of the socket data will be read and discarded.
+
+ Answers to the query are stored secondly in *ANSP2 up to a max of
+@@ -747,7 +748,7 @@
+ const u_char *buf, int buflen, const u_char *buf2, int buflen2,
+ u_char **ansp, int *anssizp,
+ int *terrno, int ns, u_char **anscp, u_char **ansp2, int *anssizp2,
+- int *resplen2)
++ int *resplen2, int *ansp2_malloced)
+ {
+ const HEADER *hp = (HEADER *) buf;
+ const HEADER *hp2 = (HEADER *) buf2;
+@@ -828,7 +829,7 @@
+ */
+ int recvresp1 = 0;
+ /* Skip the second response if there is no second query.
+- To do that we mark the second response as received. */
++ To do that we mark the second response as received. */
+ int recvresp2 = buf2 == NULL;
+ uint16_t rlen16;
+ read_len:
+@@ -896,6 +897,8 @@
+ }
+ *thisanssizp = MAXPACKET;
+ *thisansp = newp;
++ if (thisansp == ansp2)
++ *ansp2_malloced = 1;
+ anhp = (HEADER *) newp;
+ /* A uint16_t can't be larger than MAXPACKET
+ thus it's safe to allocate MAXPACKET but
+@@ -993,6 +996,7 @@
+
+ /* only try IPv6 if IPv6 NS and if not failed before */
+ if (nsap->sa_family == AF_INET6 && !statp->ipv6_unavail) {
++#ifdef SOCK_NONBLOCK
+ if (__builtin_expect (__have_o_nonblock >= 0, 1)) {
+ EXT(statp).nssocks[ns] =
+ socket(PF_INET6, SOCK_DGRAM|SOCK_NONBLOCK,
+@@ -1005,12 +1009,14 @@
+ #endif
+ }
+ if (__builtin_expect (__have_o_nonblock < 0, 0))
++#endif
+ EXT(statp).nssocks[ns] =
+ socket(PF_INET6, SOCK_DGRAM, 0);
+ if (EXT(statp).nssocks[ns] < 0)
+ statp->ipv6_unavail = errno == EAFNOSUPPORT;
+ slen = sizeof (struct sockaddr_in6);
+ } else if (nsap->sa_family == AF_INET) {
++#ifdef SOCK_NONBLOCK
+ if (__builtin_expect (__have_o_nonblock >= 0, 1)) {
+ EXT(statp).nssocks[ns]
+ = socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK,
+@@ -1023,6 +1029,7 @@
+ #endif
+ }
+ if (__builtin_expect (__have_o_nonblock < 0, 0))
++#endif
+ EXT(statp).nssocks[ns]
+ = socket(PF_INET, SOCK_DGRAM, 0);
+ slen = sizeof (struct sockaddr_in);
+@@ -1049,7 +1056,11 @@
+ __res_iclose(statp, false);
+ return (0);
+ }
++#ifdef SOCK_NONBLOCK
+ if (__builtin_expect (__have_o_nonblock < 0, 0)) {
++#else
++ {
++#endif
+ /* Make socket non-blocking. */
+ int fl = __fcntl (EXT(statp).nssocks[ns], F_GETFL);
+ if (fl != -1)
+@@ -1083,7 +1094,7 @@
+ are needed but ANSCP is NULL, then as much of the response as
+ possible is read into the buffer, but the results will be truncated.
+ When truncation happens because of a small answer buffer the DNS
+- packets header field TC will bet set to 1, indicating a truncated
++ packets header feild TC will bet set to 1, indicating a truncated
+ message, while the rest of the UDP packet is discarded.
+
+ Answers to the query are stored secondly in *ANSP2 up to a max of
+@@ -1128,7 +1139,7 @@
+ const u_char *buf, int buflen, const u_char *buf2, int buflen2,
+ u_char **ansp, int *anssizp,
+ int *terrno, int ns, int *v_circuit, int *gotsomewhere, u_char **anscp,
+- u_char **ansp2, int *anssizp2, int *resplen2)
++ u_char **ansp2, int *anssizp2, int *resplen2, int *ansp2_malloced)
+ {
+ const HEADER *hp = (HEADER *) buf;
+ const HEADER *hp2 = (HEADER *) buf2;
+@@ -1165,7 +1176,7 @@
+ int nwritten = 0;
+ int recvresp1 = 0;
+ /* Skip the second response if there is no second query.
+- To do that we mark the second response as received. */
++ To do that we mark the second response as received. */
+ int recvresp2 = buf2 == NULL;
+ pfd[0].fd = EXT(statp).nssocks[ns];
+ pfd[0].events = POLLOUT;
+@@ -1359,6 +1370,8 @@
+ if (newp != NULL) {
+ *thisanssizp = MAXPACKET;
+ *thisansp = newp;
++ if (thisansp == ansp2)
++ *ansp2_malloced = 1;
+ }
+ }
+ /* We could end up with truncation if anscp was NULL
+@@ -1542,6 +1555,7 @@
+ retval = reopen (statp, terrno, ns);
+ if (retval <= 0)
+ return retval;
++ pfd[0].fd = EXT(statp).nssocks[ns];
+ }
+ }
+ goto wait;