]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Tighten referral DS acceptance
authorMark Andrews <marka@isc.org>
Mon, 13 Apr 2026 06:49:37 +0000 (16:49 +1000)
committerMark Andrews <marka@isc.org>
Thu, 25 Jun 2026 05:21:00 +0000 (15:21 +1000)
Named was accepting DS records for sibling zones when it shouldn't
have.  Only DS rrsets that match the delegation name should have
been accepted.

Remove ds_name from struct respctx as it is no longer useful.

lib/dns/resolver.c

index 183712a3e64d24349a828a0666dce602be2834c8..5dc634a010c94127fdb23aa16cb92fdeecc80043 100644 (file)
@@ -980,7 +980,6 @@ typedef struct respctx {
        dns_rdataset_t *ns_rdataset; /* NS rdataset */
 
        dns_name_t *soa_name; /* SOA name in a negative answer */
-       dns_name_t *ds_name;  /* DS name in a negative answer */
 
        dns_name_t *found_name;     /* invalid name in negative
                                     * response */
@@ -8187,7 +8186,6 @@ rctx_answer_init(respctx_t *rctx) {
        rctx->ns_rdataset = NULL;
 
        rctx->soa_name = NULL;
-       rctx->ds_name = NULL;
        rctx->found_name = NULL;
 
        rctx->vrdataset = NULL;
@@ -9359,34 +9357,34 @@ rctx_authority_dnssec(respctx_t *rctx) {
                                 * marked.
                                 */
                                break;
-                       case dns_rdatatype_ds:
+                       case dns_rdatatype_ds:;
                                /*
-                                * DS or SIG DS.
+                                * DS or RRSIG(DS).
                                 *
                                 * These should only be here if this is
                                 * a referral, and there should only be
                                 * one DS RRset.
                                 */
+                               const char *typestr = (rdataset->type ==
+                                                      dns_rdatatype_ds)
+                                                             ? "DS"
+                                                             : "RRSIG(DS)";
+
                                if (rctx->ns_name == NULL) {
-                                       log_formerr(fctx,
-                                                   "DS with no referral");
+                                       log_formerr(fctx, "%s with no referral",
+                                                   typestr);
                                        rctx->result = DNS_R_FORMERR;
                                        return ISC_R_COMPLETE;
                                }
 
-                               if (rdataset->type == dns_rdatatype_ds) {
-                                       if (rctx->ds_name != NULL &&
-                                           name != rctx->ds_name)
-                                       {
-                                               log_formerr(fctx,
-                                                           "DS doesn't match "
-                                                           "referral (NS)");
-                                               rctx->result = DNS_R_FORMERR;
-                                               return ISC_R_COMPLETE;
-                                       }
-                                       rctx->ds_name = name;
+                               if (name != rctx->ns_name) {
+                                       log_formerr(fctx,
+                                                   "%s doesn't match the "
+                                                   "delegation owner name",
+                                                   typestr);
+                                       rctx->result = DNS_R_FORMERR;
+                                       return ISC_R_COMPLETE;
                                }
-
                                name->attributes.cache = true;
                                rdataset->attributes.cache = true;