]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
validator: refuse to validate answers with more than 8 NSEC3 records
authorVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 12 Feb 2024 10:16:47 +0000 (11:16 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Thu, 22 Feb 2024 12:58:51 +0000 (13:58 +0100)
(cherry picked from commit a05cf1d379d1af0958587bd111f791b72f404364)
This partially mitigates CVE-2023-50868 (release 5.7.1 is better)

lib/layer/validate.c

index 93f1d4fc6f19b0b88a539150714deee65ab7366d..b645a029f814dbd2146e04cdcc2c20c8dbf4ef63 100644 (file)
@@ -1119,6 +1119,24 @@ static int validate(kr_layer_t *ctx, knot_pkt_t *pkt)
                }
        }
 
+       /* Check for too many NSEC3 records.  That's an issue, as some parts of validation
+        * are quadratic in their count, doing nontrivial computations inside.
+        * Also there seems to be no use in sending many NSEC3 records. */
+       if (!qry->flags.CACHED) {
+               const knot_pktsection_t *sec = knot_pkt_section(pkt, KNOT_AUTHORITY);
+               int count = 0;
+               for (int i = 0; i < sec->count; ++i)
+                       count += (knot_pkt_rr(sec, i)->type == KNOT_RRTYPE_NSEC3);
+               if (count > 8) {
+                       VERBOSE_MSG(qry, "<= too many NSEC3 records in AUTHORITY (%d)\n", count);
+                       kr_request_set_extended_error(req, KNOT_EDNS_EDE_NSEC3_ITERS,
+                               /* It's not about iteration values per se, but close enough. */
+                               "DYRH: too many NSEC3 records");
+                       qry->flags.DNSSEC_BOGUS = true;
+                       return KR_STATE_FAIL;
+               }
+       }
+
        if (knot_wire_get_aa(pkt->wire) && qtype == KNOT_RRTYPE_DNSKEY) {
                const knot_rrset_t *ds = qry->zone_cut.trust_anchor;
                if (ds && !kr_ds_algo_support(ds)) {