]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Restrict the alias-chain deadlock check to chaining CNAMEs
authorOndřej Surý <ondrej@isc.org>
Thu, 2 Jul 2026 13:35:56 +0000 (15:35 +0200)
committerOndřej Surý <ondrej@isc.org>
Thu, 2 Jul 2026 14:47:14 +0000 (16:47 +0200)
check_deadlock() aborted any fetch whose name equals the owner of a
chaining rdataset, assuming nothing the validator needs can live at an
alias.  That is true for a CNAME, but a DNAME aliases only the names
below its owner: with a DNAME at a zone apex, the DNSKEY signing the
DNAME lives at the owner name itself, so every answer synthesized from
a signed apex DNAME failed validation whenever that key was not
already validated in the cache.

Chaining CNAMEs, including those synthesized from a DNAME, still cover
the self-join case the check was added for.

lib/dns/validator.c

index 54e410c834c02ae51fabb721dc5ca9f7d0a0ad37..4d819a6ef7b9d9ac2c6086b1b3f8f92ca0cab507 100644 (file)
@@ -981,12 +981,18 @@ check_deadlock(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
                }
 
                /*
-                * Validating a CNAME/DNAME ("chaining" rdataset): a fetch at
-                * the alias's own name cannot advance the chain (the type we
-                * need, e.g. DS/DNSKEY for an insecurity proof, cannot live at
-                * an alias) and would only self-join the in-flight fetch.
+                * Validating a chaining CNAME: a fetch at the alias's own
+                * name cannot advance the chain (no other type can live at
+                * a CNAME owner, so e.g. the DS/DNSKEY needed for an
+                * insecurity proof cannot be there) and would only
+                * self-join the in-flight fetch.  A chaining DNAME is
+                * different: it aliases only the names below its owner, so
+                * the owner itself may legitimately hold the DNSKEY or DS
+                * this validation needs (e.g. a DNAME at a zone apex).
                 */
-               if (cur->rdataset != NULL && cur->rdataset->attributes.chaining)
+               if (cur->rdataset != NULL &&
+                   cur->rdataset->attributes.chaining &&
+                   cur->rdataset->type == dns_rdatatype_cname)
                {
                        validator_log(
                                val, ISC_LOG_DEBUG(3),