forked from pool/glibc
Andreas Schwab
44414488d6
- Import patches from 2.23 branch OBS-URL: https://build.opensuse.org/request/show/394998 OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=436
188 lines
5.7 KiB
Diff
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 ();
|