]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix fix_iterator hang
authorMatthijs Mekking <matthijs@isc.org>
Tue, 19 Mar 2024 07:48:56 +0000 (08:48 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Mon, 25 Mar 2024 09:40:23 +0000 (10:40 +0100)
If there are no more previous leaves, it means the queried name
precedes the entire range of names in the database, so we should just
move the iterator one step back and return, instead of continuing our
search for the predecessor.

This is similar to an earlier bug fixed in an earlier commit:

    ea9a8cb392ff59438a911485742b220d40f24d6f

lib/dns/qp.c

index 4e70fa0dac485a483700209357186430945c58e3..dff011ba6684b9ebd5f21baf77a06a7f2922fea4 100644 (file)
@@ -2126,6 +2126,7 @@ fix_iterator(dns_qpreader_t *qp, dns_qpiter_t *iter, dns_qpnode_t *start,
                dns_qpiter_init(qp, iter);
                return (prevleaf(iter));
        }
+
        /*
         * As long as the branch offset point is after the point where the
         * search key differs, we need to branch up and find a better leaf
@@ -2139,7 +2140,17 @@ fix_iterator(dns_qpreader_t *qp, dns_qpiter_t *iter, dns_qpnode_t *start,
                         * go to the parent branch and iterate back to the
                         * predecessor from that point.
                         */
-                       n = prevleaf(iter);
+                       isc_result_t result = dns_qpiter_prev(iter, NULL, NULL,
+                                                             NULL);
+                       if (result == ISC_R_NOMORE) {
+                               /*
+                                * This was the first domain; move the iterator
+                                * one step back from the origin and return.
+                                */
+                               return (prevleaf(iter));
+                       }
+                       RUNTIME_CHECK(result == ISC_R_SUCCESS);
+                       n = iter->stack[iter->sp];
                        leaf = n;
                } else {
                        if (is_branch(n)) {