From: Ondřej Surý Date: Sat, 13 Sep 2025 04:19:43 +0000 (+0200) Subject: Fix detection whether node is active in find_wildcard() X-Git-Tag: v9.21.14~45^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1e9430ffadfee279e2fad3d4b1d3658620e7149b;p=thirdparty%2Fbind9.git Fix detection whether node is active in find_wildcard() The current code would fail during the write transaction. The first header would not match the search->serial and the node might be incorrectly detected as inactive. --- diff --git a/lib/dns/qpzone.c b/lib/dns/qpzone.c index bbaa16b6875..5f5de351b2e 100644 --- a/lib/dns/qpzone.c +++ b/lib/dns/qpzone.c @@ -2769,10 +2769,19 @@ wildcard_blocked(qpz_search_t *search, const dns_name_t *qname, return false; } +static bool +node_active(qpz_search_t *search, qpznode_t *node) { + DNS_SLABTOP_FOREACH(top, node->data) { + if (first_existing_header(top, search->serial) != NULL) { + return true; + } + } + return false; +} + static isc_result_t find_wildcard(qpz_search_t *search, qpznode_t **nodep, const dns_name_t *qname, dns_namespace_t nspace) { - dns_slabheader_t *found = NULL; isc_result_t result = ISC_R_NOTFOUND; /* @@ -2800,17 +2809,7 @@ find_wildcard(qpz_search_t *search, qpznode_t **nodep, const dns_name_t *qname, * may not need the information, because it simplifies the * locking and code flow. */ - DNS_SLABTOP_FOREACH(top, node->data) { - dns_slabheader_t *header = top->header; - if (header->serial <= search->serial && - !IGNORE(header) && EXISTS(header)) - { - found = header; - break; - } - } - - active = (found != NULL); + active = node_active(search, node); wild = node->wild; NODE_UNLOCK(nlock, &nlocktype); @@ -2819,6 +2818,7 @@ find_wildcard(qpz_search_t *search, qpznode_t **nodep, const dns_name_t *qname, dns_fixedname_t fwname; dns_name_t *wname = dns_fixedname_initname(&fwname); dns_qpiter_t wit; + bool wactive; /* * Construct the wildcard name for this level. @@ -2840,18 +2840,9 @@ find_wildcard(qpz_search_t *search, qpznode_t **nodep, const dns_name_t *qname, */ nlock = qpzone_get_lock(wnode); NODE_RDLOCK(nlock, &nlocktype); - DNS_SLABTOP_FOREACH(top, wnode->data) { - dns_slabheader_t *header = top->header; - if (header->serial <= search->serial && - !IGNORE(header) && EXISTS(header)) - { - found = header; - break; - } - } + wactive = node_active(search, wnode); NODE_UNLOCK(nlock, &nlocktype); - if (found != NULL || - activeempty(search, &wit, wname)) + if (wactive || activeempty(search, &wit, wname)) { if (wildcard_blocked(search, qname, wname))