]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix to limit the DSNS per-label walk in the iterator. Thanks
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 27 May 2026 10:12:39 +0000 (12:12 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 27 May 2026 10:12:39 +0000 (12:12 +0200)
  to Qifan Zhang, Palo Alto Networks, for the report.

doc/Changelog
iterator/iterator.c
iterator/iterator.h

index 7945a98cd72f46887a9c47adb26d6ed5c21d078e..5e398a34f199c53dc41b62d6511b4dbf57f561a6 100644 (file)
@@ -2,6 +2,8 @@
        - Fix for autotrust state-file line overflow, that can give
          hold-down bypass. Thanks to Qifan Zhang, Palo Alto Networks,
          for the report.
+       - Fix to limit the DSNS per-label walk in the iterator. Thanks
+         to Qifan Zhang, Palo Alto Networks, for the report.
 
 26 May 2026: Wouter
        - Fix for mesh new client and mesh new callback to rollback the
index 642536d9522b98b28df6fa2f5ee2622f03c7f42e..ae54da0d97eebe681f616388a4ac142b8cef4cea 100644 (file)
@@ -2366,6 +2366,12 @@ processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id)
 
        /* go up one (more) step, until we hit the dp, if so, end */
        dname_remove_label(&iq->dsns_point, &iq->dsns_point_len);
+       if(++iq->dsns_count > MAX_DSNS_FIND_COUNT) {
+               verbose(VERB_QUERY, "DS NS search exceeded %d labels",
+                       MAX_DSNS_FIND_COUNT);
+               errinf(qstate, "DS NS search exceeded label limit");
+               return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
+       }
        if(query_dname_compare(iq->dsns_point, iq->dp->name) == 0) {
                /* there was no inbetween nameserver, use the old delegation
                 * point again.  And this time, because dsns_point is nonNULL
index 5c3acda3bd4720fc4dbcec06afb2b5421e4525f5..87e54d41e7cd88fd142d4562bca4c6aab171ba42 100644 (file)
@@ -104,6 +104,11 @@ extern int BLACKLIST_PENALTY;
 #define RTT_BAND 400
 /** Number of retries for empty nodata packets before it is accepted. */
 #define EMPTY_NODATA_RETRY_COUNT 2
+/** max label-strip iterations in DSNS_FIND_STATE (RFC 4035 4.2 parent-NS
+ * search) before giving up; bounds upstream NS sends per client DS.
+ * Means the max number of labels in grandchild to the grandparent zone that
+ * are co-hosted. */
+#define MAX_DSNS_FIND_COUNT    20
 
 /**
  * Iterator global state for nat64.
@@ -399,6 +404,8 @@ struct iter_qstate {
        uint8_t* dsns_point;
        /** length of the dname in dsns_point */
        size_t dsns_point_len;
+       /** number of label-strip iterations performed in DSNS_FIND_STATE */
+       int dsns_count;
 
        /** 
         * expected dnssec information for this iteration step.