Commit 436c125085 for bind
commit 436c125085704d7e035b15d7174b5ed18551768f
Author: Evan Hunt <each@isc.org>
Date: Thu Oct 29 23:37:57 2026 -0700
validate DELEG namelist with dns_name_fromwire()
When reading a DELEG record off the wire, check each server-name in the
rdata for correctness by processing it with dns_name_fromwire(). This
avoids a possible assertion failure when running dns_rdata_checknames()
later.
diff --git a/lib/dns/rdata/in_1/deleg_61440.c b/lib/dns/rdata/in_1/deleg_61440.c
index e079c847fb..ed47c9a454 100644
--- a/lib/dns/rdata/in_1/deleg_61440.c
+++ b/lib/dns/rdata/in_1/deleg_61440.c
@@ -88,6 +88,10 @@ deleg_validate(uint16_t key, isc_region_t *region) {
for (i = 0; i < ARRAY_SIZE(direg); i++) {
if (direg[i].value == key) {
+ dns_fixedname_t fn;
+ dns_name_t *name = dns_fixedname_initname(&fn);
+ isc_buffer_t b;
+
switch (direg[i].encoding) {
case deleg_ipv4:
if ((region->length % 4) != 0 ||
@@ -107,6 +111,18 @@ deleg_validate(uint16_t key, isc_region_t *region) {
if (region->length == 0) {
return DNS_R_FORMERR;
}
+ while (region->length > 0U) {
+ isc_buffer_init(&b, region->base,
+ region->length);
+ isc_buffer_add(&b, region->length);
+ isc_buffer_setactive(&b,
+ region->length);
+ RETERR(dns_name_fromwire(name, &b, NULL,
+ NULL));
+ isc_region_consume(
+ region,
+ isc_buffer_consumedlength(&b));
+ }
break;
case deleg_keylist: {
if ((region->length % 2) != 0 ||
@@ -912,15 +928,13 @@ generic_checknames_in_deleg(ARGS_CHECKNAMES) {
dns_name_fromregion(&name, &r);
isc_region_consume(&r, name.length);
- if (bad != NULL) {
- dns_name_clone(&name, bad);
- }
- if (!dns_name_ishostname(&name, false)) {
- return false;
- }
- if (rdata->type == dns_rdatatype_deleg &&
- dns_name_issubdomain(&name, owner))
+ if (!dns_name_ishostname(&name, false) ||
+ (rdata->type == dns_rdatatype_deleg &&
+ dns_name_issubdomain(&name, owner)))
{
+ if (bad != NULL) {
+ dns_name_clone(&name, bad);
+ }
return false;
}
}