]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
dns_nsec3_addnsec3() can fail when iterating back
authorEvan Hunt <each@isc.org>
Sat, 21 Dec 2024 02:31:30 +0000 (18:31 -0800)
committerEvan Hunt <each@isc.org>
Fri, 10 Jan 2025 01:04:08 +0000 (17:04 -0800)
when adding a new NSEC3 record, dns_nsec3_addnsec3() uses a
dbiterator to seek to the newly created node and then find its
predecessor.  dbiterators in the qpzone use snapshots, so changes
to the database are not reflected in an already-existing iterator.
consequently, when we add a new node, we have to create a new iterator
before we can seek to it.

lib/dns/nsec3.c

index a4942b3a5b84512bd307645ebf7339317a65d233..e825ffea85e670f81fb0a645f9a14d99e5680293 100644 (file)
@@ -776,7 +776,7 @@ addnsec3:
                /*
                 * Create the node if it doesn't exist and hold
                 * a reference to it until we have added the NSEC3
-                * or we discover we don't need to add make a change.
+                * or we discover we don't need to make a change.
                 */
                CHECK(dns_db_findnsec3node(db, hashname, true, &newnode));
                result = dns_db_findrdataset(db, newnode, version,
@@ -792,6 +792,17 @@ addnsec3:
                        if (result != ISC_R_NOMORE) {
                                goto failure;
                        }
+               } else if (result == ISC_R_NOTFOUND) {
+                       /*
+                        * If we didn't find an NSEC3 in the node,
+                        * then the node must have been newly created
+                        * by dns_db_findnsec3node(). The iterator
+                        * needs to be updated so we can seek for
+                        * the node's predecessor.
+                        */
+                       dns_dbiterator_destroy(&dbit);
+                       CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY,
+                                                   &dbit));
                }
 
                /*