Fix a bug in dns_catz_generate_zonecfg()

The dns_catz_generate_zonecfg() function generates a zone configuration
string to use with a new catalog zone member zone. The buffer for the
string is 512 bytes initially (ISC_BUFFER_INCR), but can be reallocated
when required, when using corresponding isc_buffer functions like
isc_buffer_reserve(), isc_buffer_putstr(), isc_buffer_copyregion(), etc.

However, the dns_name_totext() function, which expects the buffer as an
argument, doesn't automatically resize it if the name doesn't fit there,
but instead just returns ISC_R_NOSPACE.

The chance of this occurring increases when the configuration string is
large due to, for example, long zone name, long list of primary servers
which have keys configured and/or TLS configured.

Use dns_name_format() accompanied with isc_buffer_putstr() instead of
dns_name_totext().

(cherry picked from commit 684d7e008a)
This commit is contained in:
Aram Sargsyan 2025-11-25 18:30:20 +00:00 committed by Arаm Sаrgsyаn
parent e471eb02ff
commit 59e9dfc5b4

View file

@ -1975,7 +1975,7 @@ dns_catz_generate_zonecfg(dns_catz_zone_t *catz, dns_catz_entry_t *entry,
uint32_t i;
isc_netaddr_t netaddr;
char pbuf[sizeof("65535")]; /* used for port number */
char zname[DNS_NAME_FORMATSIZE];
char namebuf[DNS_NAME_FORMATSIZE];
REQUIRE(DNS_CATZ_ZONE_VALID(catz));
REQUIRE(DNS_CATZ_ENTRY_VALID(entry));
@ -1988,7 +1988,8 @@ dns_catz_generate_zonecfg(dns_catz_zone_t *catz, dns_catz_entry_t *entry,
isc_buffer_allocate(catz->catzs->mctx, &buffer, ISC_BUFFER_INCR);
isc_buffer_putstr(buffer, "zone \"");
dns_name_totext(&entry->name, DNS_NAME_OMITFINALDOT, buffer);
dns_name_format(&entry->name, namebuf, sizeof(namebuf));
isc_buffer_putstr(buffer, namebuf);
isc_buffer_putstr(buffer, "\" { type secondary; primaries");
isc_buffer_putstr(buffer, " { ");
@ -2001,13 +2002,12 @@ dns_catz_generate_zonecfg(dns_catz_zone_t *catz, dns_catz_entry_t *entry,
case AF_INET6:
break;
default:
dns_name_format(&entry->name, zname,
DNS_NAME_FORMATSIZE);
dns_name_format(&entry->name, namebuf, sizeof(namebuf));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
"catz: zone '%s' uses an invalid primary "
"(no IP address assigned)",
zname);
namebuf);
result = ISC_R_FAILURE;
goto cleanup;
}
@ -2024,20 +2024,16 @@ dns_catz_generate_zonecfg(dns_catz_zone_t *catz, dns_catz_entry_t *entry,
if (entry->opts.masters.keys[i] != NULL) {
isc_buffer_putstr(buffer, " key ");
result = dns_name_totext(entry->opts.masters.keys[i],
DNS_NAME_OMITFINALDOT, buffer);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
dns_name_format(entry->opts.masters.keys[i], namebuf,
sizeof(namebuf));
isc_buffer_putstr(buffer, namebuf);
}
if (entry->opts.masters.tlss[i] != NULL) {
isc_buffer_putstr(buffer, " tls ");
result = dns_name_totext(entry->opts.masters.tlss[i],
DNS_NAME_OMITFINALDOT, buffer);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
dns_name_format(entry->opts.masters.tlss[i], namebuf,
sizeof(namebuf));
isc_buffer_putstr(buffer, namebuf);
}
isc_buffer_putstr(buffer, "; ");
}