]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/cache pkt_renew(): don't keep parts of packet header docs-develop-pkt-9zso9k/deployments/7222
authorVladimír Čunát <vladimir.cunat@nic.cz>
Fri, 13 Jun 2025 13:27:10 +0000 (15:27 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Thu, 17 Jul 2025 07:04:12 +0000 (09:04 +0200)
No idea why it's been done in this weird way since forever.

NEWS
lib/cache/knot_pkt.c
lib/layer/iterate.c

diff --git a/NEWS b/NEWS
index de9c8d725b3ecc4139f0904844fa59bf5871ff12..a15a9844c51e2da8a416ee0627abbc18216fb38d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,13 @@
+Knot Resolver 5.7.6 (2025-07-17)
+================================
+
+Security
+--------
+- DoS: fix a rare segfault in `resolve` function (!1720)
+  Someone controlling the DNS traffic might be able
+  to trigger this crash intentionally and too often.
+
+
 Knot Resolver 5.7.5 (2025-04-24)
 ================================
 
index 864cb57ca9e32150e082cc3cdbd88be378fe30fb..140af77549430d68f85e49d10c2de8f59d045371 100644 (file)
 
 int pkt_renew(knot_pkt_t *pkt, const knot_dname_t *name, uint16_t type)
 {
-       /* Clear the packet if needed. */
-       if (pkt->rrset_count != 0 || !knot_dname_is_equal(knot_pkt_qname(pkt), name)
-           || knot_pkt_qtype(pkt) != type || knot_pkt_qclass(pkt) != KNOT_CLASS_IN) {
-               int ret = kr_pkt_recycle(pkt);
-               if (ret) return kr_error(ret);
-               ret = knot_pkt_put_question(pkt, name, KNOT_CLASS_IN, type);
-               if (ret) return kr_error(ret);
-       }
+       knot_pkt_clear(pkt);
+       int ret = knot_pkt_put_question(pkt, name, KNOT_CLASS_IN, type);
+       if (ret) return kr_error(ret);
 
        pkt->parsed = pkt->size = KR_PKT_SIZE_NOWIRE;
        knot_wire_set_qr(pkt->wire);
index 656bc2d29a29152185781d311a0f8314689a2df8..688f13cfe2c28b54b85dda2ce52ee6211741f9a2 100644 (file)
@@ -1057,6 +1057,8 @@ static int resolve(kr_layer_t *ctx, knot_pkt_t *pkt)
        if (!query) {
                return ctx->state;
        }
+       if (pkt->size == KR_PKT_SIZE_NOWIRE)
+               goto skip_checks; // answers from cache are sane, surely
        query->flags.PKT_IS_SANE = false;
 
        WITH_VERBOSE(query) {
@@ -1108,7 +1110,7 @@ static int resolve(kr_layer_t *ctx, knot_pkt_t *pkt)
                }
                return KR_STATE_CONSUME;
        }
-
+skip_checks:
        /* If exiting above here, there's no sense to put it into packet cache.
         * Having "extra bytes" at the end of DNS message is considered SANE here.
         * The most important part is to check for spoofing: is_paired_to_query() */