diff options
author | Florian Weimer <fweimer@redhat.com> | 2020-10-14 10:54:39 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2020-10-14 10:54:39 +0200 |
commit | f1f00c072138af90ae6da180f260111f09afe7a3 (patch) | |
tree | a9d805ee0cf1038733cc0529c8c02cc522083c92 /resolv/res_send.c | |
parent | 08443b19965f48862b02c2fd7b33a39d66daf2ff (diff) | |
download | glibc-f1f00c072138af90ae6da180f260111f09afe7a3.zip glibc-f1f00c072138af90ae6da180f260111f09afe7a3.tar.gz glibc-f1f00c072138af90ae6da180f260111f09afe7a3.tar.bz2 |
resolv: Handle transaction ID collisions in parallel queries (bug 26600)
If the transaction IDs are equal, the old check attributed both
responses to the first query, not recognizing the second response.
This fixes bug 26600.
Diffstat (limited to 'resolv/res_send.c')
-rw-r--r-- | resolv/res_send.c | 40 |
1 files changed, 20 insertions, 20 deletions
diff --git a/resolv/res_send.c b/resolv/res_send.c index 7e5fec6..70e5066 100644 --- a/resolv/res_send.c +++ b/resolv/res_send.c @@ -1342,15 +1342,6 @@ send_dg(res_state statp, *terrno = EMSGSIZE; return close_and_return_error (statp, resplen2); } - if ((recvresp1 || hp->id != anhp->id) - && (recvresp2 || hp2->id != anhp->id)) { - /* - * response from old query, ignore it. - * XXX - potential security hazard could - * be detected here. - */ - goto wait; - } /* Paranoia check. Due to the connected UDP socket, the kernel has already filtered invalid addresses @@ -1360,15 +1351,24 @@ send_dg(res_state statp, /* Check for the correct header layout and a matching question. */ - if ((recvresp1 || !res_queriesmatch(buf, buf + buflen, - *thisansp, - *thisansp - + *thisanssizp)) - && (recvresp2 || !res_queriesmatch(buf2, buf2 + buflen2, - *thisansp, - *thisansp - + *thisanssizp))) - goto wait; + int matching_query = 0; /* Default to no matching query. */ + if (!recvresp1 + && anhp->id == hp->id + && res_queriesmatch (buf, buf + buflen, + *thisansp, *thisansp + *thisanssizp)) + matching_query = 1; + if (!recvresp2 + && anhp->id == hp2->id + && res_queriesmatch (buf2, buf2 + buflen2, + *thisansp, *thisansp + *thisanssizp)) + matching_query = 2; + if (matching_query == 0) + /* Spurious UDP packet. Drop it and continue + waiting. */ + { + need_recompute = 1; + goto wait; + } if (anhp->rcode == SERVFAIL || anhp->rcode == NOTIMP || @@ -1383,7 +1383,7 @@ send_dg(res_state statp, /* No data from the first reply. */ resplen = 0; /* We are waiting for a possible second reply. */ - if (hp->id == anhp->id) + if (matching_query == 1) recvresp1 = 1; else recvresp2 = 1; @@ -1414,7 +1414,7 @@ send_dg(res_state statp, return (1); } /* Mark which reply we received. */ - if (recvresp1 == 0 && hp->id == anhp->id) + if (matching_query == 1) recvresp1 = 1; else recvresp2 = 1; |