mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 15:05:23 +00:00
qpzone find() function could set foundname incorrectly
when a requested name is found in the QP trie during a lookup, but its records have been marked as nonexistent by a previous deletion, then it's treated as a partial match, but the foundname could be left pointing to the original qname rather than the parent. this could lead to an assertion failure in query_findclosestnsec3().
This commit is contained in:
@@ -3407,10 +3407,8 @@ find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||||||
if (tresult != DNS_R_CONTINUE) {
|
if (tresult != DNS_R_CONTINUE) {
|
||||||
result = tresult;
|
result = tresult;
|
||||||
search.chain.len = i - 1;
|
search.chain.len = i - 1;
|
||||||
|
dns_name_copy(&n->name, foundname);
|
||||||
node = n;
|
node = n;
|
||||||
if (foundname != NULL) {
|
|
||||||
dns_name_copy(&node->name, foundname);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3678,12 +3676,20 @@ found:
|
|||||||
/*
|
/*
|
||||||
* We have an exact match for the name, but there are no
|
* We have an exact match for the name, but there are no
|
||||||
* active rdatasets in the desired version. That means that
|
* active rdatasets in the desired version. That means that
|
||||||
* this node doesn't exist in the desired version, and that
|
* this node doesn't exist in the desired version.
|
||||||
* we really have a partial match.
|
* If there's a node above this one, reassign the
|
||||||
|
* foundname to the parent and treat this as a partial
|
||||||
|
* match.
|
||||||
*/
|
*/
|
||||||
if (!wild) {
|
if (!wild) {
|
||||||
NODE_UNLOCK(lock, &nlocktype);
|
unsigned int len = search.chain.len - 1;
|
||||||
goto partial_match;
|
if (len > 0) {
|
||||||
|
NODE_UNLOCK(lock, &nlocktype);
|
||||||
|
dns_qpchain_node(&search.chain, len - 1, NULL,
|
||||||
|
(void **)&node, NULL);
|
||||||
|
dns_name_copy(&node->name, foundname);
|
||||||
|
goto partial_match;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -170,7 +170,14 @@ ISC_RUN_TEST_IMPL(find) {
|
|||||||
dns_rdataset_init(&rdataset);
|
dns_rdataset_init(&rdataset);
|
||||||
res = dns_db_find(db1, dns_rootname, v1, dns_rdatatype_soa, 0, 0, NULL,
|
res = dns_db_find(db1, dns_rootname, v1, dns_rdatatype_soa, 0, 0, NULL,
|
||||||
name, &rdataset, NULL);
|
name, &rdataset, NULL);
|
||||||
assert_int_equal(res, DNS_R_NXDOMAIN);
|
/*
|
||||||
|
* Note: in the QPzone database, the root node always exists,
|
||||||
|
* even if it's empty, so we would get DNS_R_NXRRSET from this
|
||||||
|
* query. In other databases (including the old RBTDB) the root
|
||||||
|
* node can be nonexistent, and the query would then return
|
||||||
|
* DNS_R_NXDOMAIN. Allow for both possibilities.
|
||||||
|
*/
|
||||||
|
assert_true(res == DNS_R_NXRRSET || res == DNS_R_NXDOMAIN);
|
||||||
|
|
||||||
if (dns_rdataset_isassociated(&rdataset)) {
|
if (dns_rdataset_isassociated(&rdataset)) {
|
||||||
dns_rdataset_disassociate(&rdataset);
|
dns_rdataset_disassociate(&rdataset);
|
||||||
|
Reference in New Issue
Block a user