fix: dev: Fix a stack use-after-free in qpzone

In previous_closest_nsec(), a new qpreader was opened to search the NSEC
tree. It was possible for that to be used to update a QP iterator object
owned by the caller, and then be destroyed when the function returned.

This qpreader object isn't necessary anymore; since namespaces were
added to the QP trie in commit 15653c54a0, we can now just reuse the
existing reader for the main tree.

Closes #5942

Merge branch '5942-qpiter-fix' into 'main'

See merge request isc-projects/bind9!11955
This commit is contained in:
Evan Hunt 2026-05-05 23:19:59 +00:00
commit 82f67fc633

View file

@ -3061,7 +3061,6 @@ previous_closest_nsec(dns_rdatatype_t type, qpz_search_t *search,
dns_name_t *name, qpznode_t **nodep, dns_qpiter_t *nit,
bool *firstp) {
isc_result_t result;
dns_qpread_t qpr;
REQUIRE(nodep != NULL && *nodep == NULL);
REQUIRE(type == dns_rdatatype_nsec3 || firstp != NULL);
@ -3074,8 +3073,6 @@ previous_closest_nsec(dns_rdatatype_t type, qpz_search_t *search,
return result;
}
dns_qpmulti_query(search->qpdb->tree, &qpr);
for (;;) {
qpznode_t *nsec_node = NULL;
@ -3085,8 +3082,9 @@ previous_closest_nsec(dns_rdatatype_t type, qpz_search_t *search,
* NSEC namespace.
*/
*firstp = false;
result = dns_qp_lookup(&qpr, name, DNS_DBNAMESPACE_NSEC,
nit, NULL, NULL, NULL);
result = dns_qp_lookup(&search->qpr, name,
DNS_DBNAMESPACE_NSEC, nit, NULL,
NULL, NULL);
INSIST(result != ISC_R_NOTFOUND);
if (result == ISC_R_SUCCESS) {
@ -3153,7 +3151,6 @@ previous_closest_nsec(dns_rdatatype_t type, qpz_search_t *search,
}
}
dns_qpread_destroy(search->qpdb->tree, &qpr);
return result;
}