]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
iterate: fix NSEC3 records missing from answer in an edge case docs-develop-nsec-3srvyj/deployments/4211
authorVladimír Čunát <vladimir.cunat@nic.cz>
Wed, 29 May 2024 13:07:46 +0000 (15:07 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Wed, 29 May 2024 13:13:49 +0000 (15:13 +0200)
When positive wildcard expansion happens, NSEC(3) records are needed
to prove that the expansion was allowed.  If the NSEC3 had too many
iterations, we downgrade the answer to insecure status, but
unintentionally we also dropped the NSEC3 record from the answer.

That was breaking DNSSEC validation of that answer, e.g. when
forwarding to Knot Resolver.  The validator needs the NSEC3 -
either to validate the expansion or to determine that it's too expensive.

NEWS
lib/layer/iterate.c

diff --git a/NEWS b/NEWS
index dca74386432170a166679bbddf2a2b888ab8cc3f..5e7990838dd8acdbe33dab7c5bba95f67915139a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,12 @@ Improvements
 ------------
 - stats: add separate metrics for IPv6 and IPv4 (!1544)
 
+Bugfixes
+--------
+- fix NSEC3 records missing in answer for positive wildcard expansion
+  with the NSEC3 having over-limit iteration count (#910, !1550)
+
+
 Knot Resolver 5.7.2 (2024-03-27)
 ================================
 
index 5d16015ecd59f9c88ddf3bc52807f5bae878fa5d..656bc2d29a29152185781d311a0f8314689a2df8 100644 (file)
@@ -825,7 +825,10 @@ static int process_answer(knot_pkt_t *pkt, struct kr_request *req)
                }
        } else if (!query->parent) {
                /* Answer for initial query */
-               const bool to_wire = ((pkt_class & (PKT_NXDOMAIN|PKT_NODATA)) != 0);
+               const bool to_wire = ((pkt_class & (PKT_NXDOMAIN|PKT_NODATA)) != 0)
+                       /* We need to cover the case of positive wildcard answer
+                        * with over-limit NSEC3 iterations. */
+                               || query->flags.DNSSEC_WEXPAND;
                state = pick_authority(pkt, req, to_wire);
                if (state != kr_ok()) {
                        return KR_STATE_FAIL;