SHA256
3
0
forked from pool/glibc
glibc/0018-resolv-Always-set-resplen2-out-parameter-in-send_dg-.patch

188 lines
5.7 KiB
Diff

2016-03-25 Florian Weimer <fweimer@redhat.com>
[BZ #19791]
* resolv/res_send.c (close_and_return_error): New function.
(send_dg): Initialize *resplen2 after reopen failure. Call
close_and_return_error for error returns. On error paths without
__res_iclose, initialze *resplen2 explicitly. Update comment for
successful return.
Index: glibc-2.23/NEWS
===================================================================
--- glibc-2.23.orig/NEWS
+++ glibc-2.23/NEWS
@@ -17,6 +17,7 @@ The following bugs are resolved with thi
[19758] Or bit_Prefer_MAP_32BIT_EXEC in EXTRA_LD_ENVVARS
[19759] Don't inline mempcpy for x86
[19762] Use HAS_ARCH_FEATURE with Fast_Rep_String
+ [19791] Assertion failure in res_query.c with un-connectable name server addresses
[19792] MIPS: backtrace yields infinite backtrace with makecontext
[19822] libm.so install clobbers old version
Index: glibc-2.23/resolv/res_send.c
===================================================================
--- glibc-2.23.orig/resolv/res_send.c
+++ glibc-2.23/resolv/res_send.c
@@ -649,6 +649,18 @@ get_nsaddr (res_state statp, int n)
return (struct sockaddr *) (void *) &statp->nsaddr_list[n];
}
+/* Close the resolver structure, assign zero to *RESPLEN2 if RESPLEN2
+ is not NULL, and return zero. */
+static int
+__attribute__ ((warn_unused_result))
+close_and_return_error (res_state statp, int *resplen2)
+{
+ __res_iclose(statp, false);
+ if (resplen2 != NULL)
+ *resplen2 = 0;
+ return 0;
+}
+
/* The send_vc function is responsible for sending a DNS query over TCP
to the nameserver numbered NS from the res_state STATP i.e.
EXT(statp).nssocks[ns]. The function supports sending both IPv4 and
@@ -1114,7 +1126,11 @@ send_dg(res_state statp,
retry_reopen:
retval = reopen (statp, terrno, ns);
if (retval <= 0)
- return retval;
+ {
+ if (resplen2 != NULL)
+ *resplen2 = 0;
+ return retval;
+ }
retry:
evNowTime(&now);
evConsTime(&timeout, seconds, 0);
@@ -1127,8 +1143,6 @@ send_dg(res_state statp,
int recvresp2 = buf2 == NULL;
pfd[0].fd = EXT(statp).nssocks[ns];
pfd[0].events = POLLOUT;
- if (resplen2 != NULL)
- *resplen2 = 0;
wait:
if (need_recompute) {
recompute_resend:
@@ -1136,9 +1150,7 @@ send_dg(res_state statp,
if (evCmpTime(finish, now) <= 0) {
poll_err_out:
Perror(statp, stderr, "poll", errno);
- err_out:
- __res_iclose(statp, false);
- return (0);
+ return close_and_return_error (statp, resplen2);
}
evSubTime(&timeout, &finish, &now);
need_recompute = 0;
@@ -1185,7 +1197,9 @@ send_dg(res_state statp,
}
*gotsomewhere = 1;
- return (0);
+ if (resplen2 != NULL)
+ *resplen2 = 0;
+ return 0;
}
if (n < 0) {
if (errno == EINTR)
@@ -1253,7 +1267,7 @@ send_dg(res_state statp,
fail_sendmmsg:
Perror(statp, stderr, "sendmmsg", errno);
- goto err_out;
+ return close_and_return_error (statp, resplen2);
}
}
else
@@ -1271,7 +1285,7 @@ send_dg(res_state statp,
if (errno == EINTR || errno == EAGAIN)
goto recompute_resend;
Perror(statp, stderr, "send", errno);
- goto err_out;
+ return close_and_return_error (statp, resplen2);
}
just_one:
if (nwritten != 0 || buf2 == NULL || single_request)
@@ -1349,7 +1363,7 @@ send_dg(res_state statp,
goto wait;
}
Perror(statp, stderr, "recvfrom", errno);
- goto err_out;
+ return close_and_return_error (statp, resplen2);
}
*gotsomewhere = 1;
if (__glibc_unlikely (*thisresplenp < HFIXEDSZ)) {
@@ -1360,7 +1374,7 @@ send_dg(res_state statp,
(stdout, ";; undersized: %d\n",
*thisresplenp));
*terrno = EMSGSIZE;
- goto err_out;
+ return close_and_return_error (statp, resplen2);
}
if ((recvresp1 || hp->id != anhp->id)
&& (recvresp2 || hp2->id != anhp->id)) {
@@ -1409,7 +1423,7 @@ send_dg(res_state statp,
? *thisanssizp : *thisresplenp);
/* record the error */
statp->_flags |= RES_F_EDNS0ERR;
- goto err_out;
+ return close_and_return_error (statp, resplen2);
}
#endif
if (!(statp->options & RES_INSECURE2)
@@ -1461,10 +1475,10 @@ send_dg(res_state statp,
goto wait;
}
- __res_iclose(statp, false);
/* don't retry if called from dig */
if (!statp->pfcode)
- return (0);
+ return close_and_return_error (statp, resplen2);
+ __res_iclose(statp, false);
}
if (anhp->rcode == NOERROR && anhp->ancount == 0
&& anhp->aa == 0 && anhp->ra == 0 && anhp->arcount == 0) {
@@ -1486,6 +1500,8 @@ send_dg(res_state statp,
__res_iclose(statp, false);
// XXX if we have received one reply we could
// XXX use it and not repeat it over TCP...
+ if (resplen2 != NULL)
+ *resplen2 = 0;
return (1);
}
/* Mark which reply we received. */
@@ -1501,21 +1517,22 @@ send_dg(res_state statp,
__res_iclose (statp, false);
retval = reopen (statp, terrno, ns);
if (retval <= 0)
- return retval;
+ {
+ if (resplen2 != NULL)
+ *resplen2 = 0;
+ return retval;
+ }
pfd[0].fd = EXT(statp).nssocks[ns];
}
}
goto wait;
}
- /*
- * All is well, or the error is fatal. Signal that the
- * next nameserver ought not be tried.
- */
+ /* All is well. We have received both responses (if
+ two responses were requested). */
return (resplen);
- } else if (pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL)) {
- /* Something went wrong. We can stop trying. */
- goto err_out;
- }
+ } else if (pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL))
+ /* Something went wrong. We can stop trying. */
+ return close_and_return_error (statp, resplen2);
else {
/* poll should not have returned > 0 in this case. */
abort ();