]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix #441: Minimal NSEC range not accepted for top level domains.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 17 Mar 2021 13:04:02 +0000 (14:04 +0100)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 17 Mar 2021 13:04:02 +0000 (14:04 +0100)
doc/Changelog
iterator/iter_scrub.c

index b6bbfa2100c16704bdc07c480e496e46a7daf29a..bce6fbee09843ecc687c346837e1b3961f3221a6 100644 (file)
@@ -1,3 +1,6 @@
+17 March 2021: Wouter
+       - Fix #441: Minimal NSEC range not accepted for top level domains.
+
 11 March 2021: Wouter
        - Fix parse of LOC RR type for decimetres.
 
index aae934dd44fedf6a88e1d8382592c2ea4a25f60a..f093c1bf999abdb7898d316bfe7658307be42493 100644 (file)
@@ -640,25 +640,37 @@ store_rrset(sldns_buffer* pkt, struct msg_parse* msg, struct module_env* env,
 
 /**
  * Check if right hand name in NSEC is within zone
+ * @param pkt: the packet buffer for decompression.
  * @param rrset: the NSEC rrset
  * @param zonename: the zone name.
  * @return true if BAD.
  */
-static int sanitize_nsec_is_overreach(struct rrset_parse* rrset, 
-       uint8_t* zonename)
+static int sanitize_nsec_is_overreach(sldns_buffer* pkt,
+       struct rrset_parse* rrset, uint8_t* zonename)
 {
        struct rr_parse* rr;
        uint8_t* rhs;
        size_t len;
        log_assert(rrset->type == LDNS_RR_TYPE_NSEC);
        for(rr = rrset->rr_first; rr; rr = rr->next) {
+               size_t pos = sldns_buffer_position(pkt);
+               size_t rhspos;
                rhs = rr->ttl_data+4+2;
                len = sldns_read_uint16(rr->ttl_data+4);
-               if(!dname_valid(rhs, len)) {
-                       /* malformed domain name in rdata */
+               rhspos = rhs-sldns_buffer_begin(pkt);
+               sldns_buffer_set_position(pkt, rhspos);
+               if(pkt_dname_len(pkt) == 0) {
+                       /* malformed */
+                       sldns_buffer_set_position(pkt, pos);
                        return 1;
                }
-               if(!dname_subdomain_c(rhs, zonename)) {
+               if(sldns_buffer_position(pkt)-rhspos > len) {
+                       /* outside of rdata boundaries */
+                       sldns_buffer_set_position(pkt, pos);
+                       return 1;
+               }
+               sldns_buffer_set_position(pkt, pos);
+               if(!pkt_sub(pkt, rhs, zonename)) {
                        /* overreaching */
                        return 1;
                }
@@ -791,7 +803,7 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
                }
                /* check if right hand side of NSEC is within zone */
                if(rrset->type == LDNS_RR_TYPE_NSEC &&
-                       sanitize_nsec_is_overreach(rrset, zonename)) {
+                       sanitize_nsec_is_overreach(pkt, rrset, zonename)) {
                        remove_rrset("sanitize: removing overreaching NSEC "
                                "RRset:", pkt, msg, prev, &rrset);
                        continue;