]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Guard parent-NS walk against running off the root 11909/head
authorOndřej Surý <ondrej@isc.org>
Wed, 29 Apr 2026 18:20:04 +0000 (20:20 +0200)
committerOndřej Surý <ondrej@isc.org>
Fri, 1 May 2026 06:18:36 +0000 (08:18 +0200)
Once the walk reaches the root, splitting one more label off would
trip an internal assertion and abort named.  Stop cleanly with
ISC_R_NOTFOUND so the dispatcher cancels the fetch.  Only reachable
through misconfiguration (root configured as a primary with parental
agents, or a parent zone that NODATAs its own NS).

Assisted-by: Claude:claude-opus-4-7
lib/dns/zone.c
lib/dns/zonefetch.c

index e5254dd710305aa6eca9bfe83b6aa899968d6a9a..d6a86dacc4098a026b0a9e7f6d094828e7d22ff8 100644 (file)
@@ -17653,15 +17653,18 @@ checkds_send(dns_zone_t *zone) {
 static isc_result_t
 nsfetch_start(dns_zonefetch_t *fetch) {
        dns_nsfetch_t *nsfetch;
-       unsigned int nlabels = 1;
 
        REQUIRE(fetch->fetchtype == ZONEFETCHTYPE_NS);
 
        nsfetch = &fetch->fetchdata.nsfetch;
 
-       /* Derive parent domain. XXXWMM: Check for root domain */
+       /* Derive parent domain. Check for root domain. */
+       if (dns_name_countlabels(&nsfetch->pname) <= 1U) {
+               return ISC_R_NOTFOUND;
+       }
+
        dns_name_split(&nsfetch->pname,
-                      dns_name_countlabels(&nsfetch->pname) - nlabels, NULL,
+                      dns_name_countlabels(&nsfetch->pname) - 1U, NULL,
                       &nsfetch->pname);
 
        fetch->qtype = dns_rdatatype_ns;
index ff28bff566ec3f8c8e68fe4e5bb3bc584ba95ab9..475ee19ffcc89747b080b4829710eb71552fe705 100644 (file)
@@ -75,12 +75,20 @@ cancel:
                return;
        } else if (result != ISC_R_SHUTTINGDOWN) {
                char namebuf[DNS_NAME_FORMATSIZE];
-               char typebuf[DNS_RDATATYPE_FORMATSIZE];
-               dns_name_format(fetch->qname, namebuf, sizeof(namebuf));
-               dns_rdatatype_format(fetch->qtype, typebuf, sizeof(typebuf));
-               dns_zone_log(zone, ISC_LOG_WARNING,
-                            "Failed fetch for %s/%s request", namebuf,
-                            typebuf);
+
+               if (DNS_NAME_VALID(fetch->qname)) {
+                       char typebuf[DNS_RDATATYPE_FORMATSIZE];
+                       dns_name_format(fetch->qname, namebuf, sizeof(namebuf));
+                       dns_rdatatype_format(fetch->qtype, typebuf,
+                                            sizeof(typebuf));
+                       dns_zone_log(zone, ISC_LOG_WARNING,
+                                    "Failed fetch for %s/%s request", namebuf,
+                                    typebuf);
+               } else {
+                       dns_zone_nameonly(zone, namebuf, sizeof(namebuf));
+                       dns_zone_log(zone, ISC_LOG_WARNING,
+                                    "Failed fetch for zone %s", namebuf);
+               }
        }
 
        /*