From: Matthijs Mekking Date: Wed, 11 Aug 2021 08:31:56 +0000 (+0200) Subject: Don't use stale nodes when looking up a zonecut X-Git-Tag: v9.17.18~37^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bc448fb3b1483141c0bb3c5f344244612433560d;p=thirdparty%2Fbind9.git Don't use stale nodes when looking up a zonecut When looking up a zonecut in cache, we use 'dns_rbt_findnode' to find the closest matching node. This function however does not take into account stale nodes. When we do find a stale node and use it, this has implications for subsequent lookups. For example, this may break QNAME minimization because we are using a deeper zonecut than we should have. Check the header for staleness and if so, and stale entries are not accepted, look for the deepest zonecut from this node up. --- diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index bfca24a5b9e..32355c1398f 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -5363,6 +5363,7 @@ cache_findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options, } else if (!dcnull) { dns_name_copy(dcname, foundname); } + /* * We now go looking for an NS rdataset at the node. */ @@ -5378,7 +5379,22 @@ cache_findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options, header_next = header->next; if (check_stale_header(node, header, &locktype, lock, &search, &header_prev)) { - /* Do nothing. */ + /* + * The function dns_rbt_findnode found us the a matching + * node for 'name' and stored the result in 'dcname'. + * This is the deepest known zonecut in our database. + * However, this node may be stale and if serve-stale + * is not enabled (in other words 'stale-answer-enable' + * is set to no), this node may not be used as a + * zonecut we know about. If so, find the deepest + * zonecut from this node up and return that instead. + */ + NODE_UNLOCK(lock, locktype); + result = find_deepest_zonecut(&search, node, nodep, + foundname, rdataset, + sigrdataset); + dns_name_copy(foundname, dcname); + goto tree_exit; } else if (EXISTS(header) && !ANCIENT(header)) { /* * If we found a type we were looking for, remember