summaryrefslogtreecommitdiffstats
path: root/debian/patches/0005-validator-refuse-to-validate-answers-with-more-than-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/0005-validator-refuse-to-validate-answers-with-more-than-.patch')
-rw-r--r--debian/patches/0005-validator-refuse-to-validate-answers-with-more-than-.patch37
1 files changed, 37 insertions, 0 deletions
diff --git a/debian/patches/0005-validator-refuse-to-validate-answers-with-more-than-.patch b/debian/patches/0005-validator-refuse-to-validate-answers-with-more-than-.patch
new file mode 100644
index 0000000..dd547a1
--- /dev/null
+++ b/debian/patches/0005-validator-refuse-to-validate-answers-with-more-than-.patch
@@ -0,0 +1,37 @@
+From: =?utf-8?b?VmxhZGltw61yIMSMdW7DoXQ=?= <vladimir.cunat@nic.cz>
+Date: Mon, 12 Feb 2024 11:16:47 +0100
+Subject: validator: refuse to validate answers with more than 8 NSEC3 records
+
+---
+ lib/layer/validate.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/lib/layer/validate.c b/lib/layer/validate.c
+index 5fea99d..95a7624 100644
+--- a/lib/layer/validate.c
++++ b/lib/layer/validate.c
+@@ -1120,6 +1120,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)) {