Guard parent-NS walk against running off the root

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
This commit is contained in:
Ondřej Surý 2026-04-29 20:20:04 +02:00
parent 1ce7cf2dd2
commit 141e8110f7
2 changed files with 20 additions and 9 deletions

View 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;

View 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);
}
}
/*