]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
fix a QP chain bug
authorEvan Hunt <each@isc.org>
Sat, 30 Sep 2023 05:31:17 +0000 (22:31 -0700)
committerEvan Hunt <each@isc.org>
Mon, 9 Oct 2023 20:29:02 +0000 (13:29 -0700)
depending on how the QP trie is traversed during a lookup, it is
possible for a search to terminate on a leaf which is a partial
match, without that leaf being added to the chain. to ensure the
chain is correct in this case, when a partial match condition is
detected via qpkey_compare(), we will call add_link() again, just
in case.  (add_link() will check for a duplicated node, so it will
be harmless if it was already done.)

lib/dns/qp.c
tests/dns/qp_test.c

index 4bc75414c9d4ce86b4892d06a04bd2d172fdedc1..873183a8e5db976dae087aa8c19a323fae5919f0 100644 (file)
@@ -1996,6 +1996,10 @@ dns_qp_getname(dns_qpreadable_t qpr, const dns_name_t *name, void **pval_r,
 
 static inline void
 add_link(dns_qpchain_t *chain, dns_qpnode_t *node, size_t offset) {
+       /* prevent duplication */
+       if (chain->chain[chain->len - 1].node == node) {
+               return;
+       }
        chain->chain[chain->len].node = node;
        chain->chain[chain->len].offset = offset;
        chain->len++;
@@ -2161,9 +2165,8 @@ dns_qp_lookup(dns_qpreadable_t qpr, const dns_name_t *name,
                SET_IF_NOT_NULL(pval_r, leaf_pval(n));
                SET_IF_NOT_NULL(ival_r, leaf_ival(n));
                maybe_set_name(qp, n, foundname);
+               add_link(chain, n, offset);
                if (offset == QPKEY_EQUAL) {
-                       /* add the exact match to the chain */
-                       add_link(chain, n, offset);
                        return (ISC_R_SUCCESS);
                } else {
                        return (DNS_R_PARTIALMATCH);
index c0c399085f3c62c25e0a7fe2cfb9da17117ada11..f15022618f9f14c8c20081dd957f3038ccf67d9c 100644 (file)
@@ -550,6 +550,10 @@ ISC_RUN_TEST_IMPL(qpchain) {
                  { ".", "a.", "b.a.", "c.b.a.", "e.d.c.b.a." } },
                { "a.b.c.d.", ISC_R_SUCCESS, 3, { ".", "c.d.", "a.b.c.d." } },
                { "b.c.d.", DNS_R_PARTIALMATCH, 2, { ".", "c.d." } },
+               { "z.x.k.c.d.",
+                 DNS_R_PARTIALMATCH,
+                 3,
+                 { ".", "c.d.", "x.k.c.d." } },
                { NULL, 0, 0, { NULL } },
        };