|
|
9b4944 |
commit f1f00c072138af90ae6da180f260111f09afe7a3
|
|
|
9b4944 |
Author: Florian Weimer <fweimer@redhat.com>
|
|
|
9b4944 |
Date: Wed Oct 14 10:54:39 2020 +0200
|
|
|
9b4944 |
|
|
|
9b4944 |
resolv: Handle transaction ID collisions in parallel queries (bug 26600)
|
|
|
9b4944 |
|
|
|
9b4944 |
If the transaction IDs are equal, the old check attributed both
|
|
|
9b4944 |
responses to the first query, not recognizing the second response.
|
|
|
9b4944 |
This fixes bug 26600.
|
|
|
9b4944 |
|
|
|
9b4944 |
[dj: stripped out testsuite parts]
|
|
|
9b4944 |
|
|
|
9b4944 |
diff --git a/resolv/res_send.c b/resolv/res_send.c
|
|
|
9b4944 |
index c9b02cca130bc20d..ac19627634281c2f 100644
|
|
|
9b4944 |
--- a/resolv/res_send.c
|
|
|
9b4944 |
+++ b/resolv/res_send.c
|
|
|
9b4944 |
@@ -1315,15 +1315,6 @@ send_dg(res_state statp,
|
|
|
9b4944 |
*terrno = EMSGSIZE;
|
|
|
9b4944 |
return close_and_return_error (statp, resplen2);
|
|
|
9b4944 |
}
|
|
|
9b4944 |
- if ((recvresp1 || hp->id != anhp->id)
|
|
|
9b4944 |
- && (recvresp2 || hp2->id != anhp->id)) {
|
|
|
9b4944 |
- /*
|
|
|
9b4944 |
- * response from old query, ignore it.
|
|
|
9b4944 |
- * XXX - potential security hazard could
|
|
|
9b4944 |
- * be detected here.
|
|
|
9b4944 |
- */
|
|
|
9b4944 |
- goto wait;
|
|
|
9b4944 |
- }
|
|
|
9b4944 |
|
|
|
9b4944 |
/* Paranoia check. Due to the connected UDP socket,
|
|
|
9b4944 |
the kernel has already filtered invalid addresses
|
|
|
9b4944 |
@@ -1333,15 +1324,24 @@ send_dg(res_state statp,
|
|
|
9b4944 |
|
|
|
9b4944 |
/* Check for the correct header layout and a matching
|
|
|
9b4944 |
question. */
|
|
|
9b4944 |
- if ((recvresp1 || !res_queriesmatch(buf, buf + buflen,
|
|
|
9b4944 |
- *thisansp,
|
|
|
9b4944 |
- *thisansp
|
|
|
9b4944 |
- + *thisanssizp))
|
|
|
9b4944 |
- && (recvresp2 || !res_queriesmatch(buf2, buf2 + buflen2,
|
|
|
9b4944 |
- *thisansp,
|
|
|
9b4944 |
- *thisansp
|
|
|
9b4944 |
- + *thisanssizp)))
|
|
|
9b4944 |
- goto wait;
|
|
|
9b4944 |
+ int matching_query = 0; /* Default to no matching query. */
|
|
|
9b4944 |
+ if (!recvresp1
|
|
|
9b4944 |
+ && anhp->id == hp->id
|
|
|
9b4944 |
+ && res_queriesmatch (buf, buf + buflen,
|
|
|
9b4944 |
+ *thisansp, *thisansp + *thisanssizp))
|
|
|
9b4944 |
+ matching_query = 1;
|
|
|
9b4944 |
+ if (!recvresp2
|
|
|
9b4944 |
+ && anhp->id == hp2->id
|
|
|
9b4944 |
+ && res_queriesmatch (buf2, buf2 + buflen2,
|
|
|
9b4944 |
+ *thisansp, *thisansp + *thisanssizp))
|
|
|
9b4944 |
+ matching_query = 2;
|
|
|
9b4944 |
+ if (matching_query == 0)
|
|
|
9b4944 |
+ /* Spurious UDP packet. Drop it and continue
|
|
|
9b4944 |
+ waiting. */
|
|
|
9b4944 |
+ {
|
|
|
9b4944 |
+ need_recompute = 1;
|
|
|
9b4944 |
+ goto wait;
|
|
|
9b4944 |
+ }
|
|
|
9b4944 |
|
|
|
9b4944 |
if (anhp->rcode == SERVFAIL ||
|
|
|
9b4944 |
anhp->rcode == NOTIMP ||
|
|
|
9b4944 |
@@ -1356,7 +1356,7 @@ send_dg(res_state statp,
|
|
|
9b4944 |
/* No data from the first reply. */
|
|
|
9b4944 |
resplen = 0;
|
|
|
9b4944 |
/* We are waiting for a possible second reply. */
|
|
|
9b4944 |
- if (hp->id == anhp->id)
|
|
|
9b4944 |
+ if (matching_query == 1)
|
|
|
9b4944 |
recvresp1 = 1;
|
|
|
9b4944 |
else
|
|
|
9b4944 |
recvresp2 = 1;
|
|
|
9b4944 |
@@ -1387,7 +1387,7 @@ send_dg(res_state statp,
|
|
|
9b4944 |
return (1);
|
|
|
9b4944 |
}
|
|
|
9b4944 |
/* Mark which reply we received. */
|
|
|
9b4944 |
- if (recvresp1 == 0 && hp->id == anhp->id)
|
|
|
9b4944 |
+ if (matching_query == 1)
|
|
|
9b4944 |
recvresp1 = 1;
|
|
|
9b4944 |
else
|
|
|
9b4944 |
recvresp2 = 1;
|