]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix validation for repeated use of a DNAME record.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 6 Jun 2024 13:28:21 +0000 (15:28 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 6 Jun 2024 13:28:21 +0000 (15:28 +0200)
doc/Changelog
validator/val_utils.c
validator/validator.c

index 4d7a8fdee4429ba2c5efc9797607218e036859d3..3fb5447dc9c880b96beb1be3e53638110cb99c31 100644 (file)
@@ -1,6 +1,7 @@
 6 June 2024: Wouter
        - Fix memory leak in setup of dsa sig.
        - Fix typos for 'the the' in text.
+       - Fix validation for repeated use of a DNAME record.
 
 4 June 2024: Yorgos
        - Merge #1080: AddressSanitizer detection in tdir tests and memory leak
index a7db41dadc3d4b1b7f44393d64a77d589e7ad340..add6d9bba64aabd64115b7e93eb2a388381896d0 100644 (file)
@@ -240,6 +240,26 @@ val_find_best_signer(struct ub_packed_rrset_key* rrset,
        }
 }
 
+/** Detect if the, unsigned, CNAME is under a previous DNAME RR in the
+ * message, and thus it was generated from that previous DNAME.
+ */
+static int
+cname_under_previous_dname(struct reply_info* rep, size_t cname_idx,
+       size_t* ret)
+{
+       size_t i;
+       for(i=0; i<cname_idx; i++) {
+               if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_DNAME &&
+                       dname_strict_subdomain_c(rep->rrsets[cname_idx]->
+                       rk.dname, rep->rrsets[i]->rk.dname)) {
+                       *ret = i;
+                       return 1;
+               }
+       }
+       *ret = 0;
+       return 0;
+}
+
 void 
 val_find_signer(enum val_classification subtype, struct query_info* qinf, 
        struct reply_info* rep, size_t skip, uint8_t** signer_name, 
@@ -275,12 +295,19 @@ val_find_signer(enum val_classification subtype, struct query_info* qinf,
                *signer_name = NULL;
                *signer_len = 0;
        } else if(subtype == VAL_CLASS_CNAME) {
+               size_t j;
                /* check for the first signed cname/dname rrset */
                for(i=skip; i<rep->an_numrrsets; i++) {
                        val_find_rrset_signer(rep->rrsets[i], 
                                signer_name, signer_len);
                        if(*signer_name)
                                return;
+                       if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_CNAME
+                               && cname_under_previous_dname(rep, i, &j)) {
+                               val_find_rrset_signer(rep->rrsets[j],
+                                       signer_name, signer_len);
+                               return;
+                       }
                        if(ntohs(rep->rrsets[i]->rk.type) != LDNS_RR_TYPE_DNAME)
                                break; /* only check CNAME after a DNAME */
                }
@@ -979,7 +1006,7 @@ void
 val_fill_reply(struct reply_info* chase, struct reply_info* orig, 
        size_t skip, uint8_t* name, size_t len, uint8_t* signer)
 {
-       size_t i;
+       size_t i, j;
        int seen_dname = 0;
        chase->rrset_count = 0;
        chase->an_numrrsets = 0;
@@ -1002,8 +1029,15 @@ val_fill_reply(struct reply_info* chase, struct reply_info* orig,
                                LDNS_RR_TYPE_DNAME) {
                                        seen_dname = 1;
                        }
+               } else if(ntohs(orig->rrsets[i]->rk.type) == LDNS_RR_TYPE_CNAME
+                       && ((struct packed_rrset_data*)orig->rrsets[i]->
+                       entry.data)->rrsig_count == 0 &&
+                       cname_under_previous_dname(orig, i, &j) &&
+                       rrset_has_signer(orig->rrsets[j], name, len)) {
+                       chase->rrsets[chase->an_numrrsets++] = orig->rrsets[j];
+                       chase->rrsets[chase->an_numrrsets++] = orig->rrsets[i];
                }
-       }       
+       }
        /* AUTHORITY section */
        for(i = (skip > orig->an_numrrsets)?skip:orig->an_numrrsets;
                i<orig->an_numrrsets+orig->ns_numrrsets; 
index 3cf291658e715cc1c747caa76b687bd4ac14fa8d..ec656db127b816c6fa9b94cac80718df739ed687 100644 (file)
@@ -275,7 +275,7 @@ val_new_getmsg(struct module_qstate* qstate, struct val_qstate* vq)
                return NULL; /* protect against integer overflow */
        vq->chase_reply->rrsets = regional_alloc_init(qstate->region,
                vq->orig_msg->rep->rrsets, sizeof(struct ub_packed_rrset_key*)
-                       * vq->orig_msg->rep->rrset_count);
+                       * (vq->orig_msg->rep->rrset_count + vq->orig_msg->rep->an_numrrsets /* for extra DNAME records for unsigned CNAME repetitions*/) );
        if(!vq->chase_reply->rrsets)
                return NULL;
        vq->rrset_skip = 0;