From 684d7e008a9c001fda2e95427917345a72658d67 Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Tue, 25 Nov 2025 18:30:20 +0000 Subject: [PATCH 1/3] 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(). --- lib/dns/catz.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/dns/catz.c b/lib/dns/catz.c index 198e68ad6d..305296b020 100644 --- a/lib/dns/catz.c +++ b/lib/dns/catz.c @@ -1913,7 +1913,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)); @@ -1926,7 +1926,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, " { "); @@ -1939,13 +1940,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_LOGCATEGORY_GENERAL, DNS_LOGMODULE_CATZ, ISC_LOG_ERROR, "catz: zone '%s' uses an invalid primary " "(no IP address assigned)", - zname); + namebuf); CLEANUP(ISC_R_FAILURE); } isc_netaddr_fromsockaddr(&netaddr, @@ -1961,14 +1961,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 "); - CHECK(dns_name_totext(entry->opts.masters.keys[i], - DNS_NAME_OMITFINALDOT, buffer)); + 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 "); - CHECK(dns_name_totext(entry->opts.masters.tlss[i], - DNS_NAME_OMITFINALDOT, buffer)); + dns_name_format(entry->opts.masters.tlss[i], namebuf, + sizeof(namebuf)); + isc_buffer_putstr(buffer, namebuf); } isc_buffer_putstr(buffer, "; "); } From 2622140482f1df338d3d4cd2acc102ffc4fd4801 Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Wed, 26 Nov 2025 13:50:16 +0000 Subject: [PATCH 2/3] Add a check to the catz test to confirm that the issue is fixed Use a member zone with a long list of primaries with long key names to trigger the issue that was fixed by the previous commit. --- bin/tests/system/catz/ns1/named.conf.in | 15 ++++++ bin/tests/system/catz/ns4/named.conf.in | 14 +++++ bin/tests/system/catz/setup.sh | 1 + bin/tests/system/catz/tests.sh | 68 +++++++++++++++++++++++++ bin/tests/system/catz/tests_sh_catz.py | 1 + 5 files changed, 99 insertions(+) diff --git a/bin/tests/system/catz/ns1/named.conf.in b/bin/tests/system/catz/ns1/named.conf.in index 9d508440bd..dc1e2d93f4 100644 --- a/bin/tests/system/catz/ns1/named.conf.in +++ b/bin/tests/system/catz/ns1/named.conf.in @@ -137,6 +137,16 @@ view "default" { also-notify { 10.53.0.4; }; notify explicit; }; + + # A catalog zone to test specific issues + zone "catalog-misc.example" { + type primary; + file "catalog-misc.example.db"; + allow-transfer { any; }; + allow-update { any; }; + also-notify { 10.53.0.4; }; + notify explicit; + }; }; view "ch" ch { @@ -162,3 +172,8 @@ key next_key. { secret "LaAnCU+Z"; algorithm @DEFAULT_HMAC@; }; + +key longlonglongname0123456789abcdef. { + secret "LaAnCU+Z"; + algorithm @DEFAULT_HMAC@; +}; diff --git a/bin/tests/system/catz/ns4/named.conf.in b/bin/tests/system/catz/ns4/named.conf.in index 75cb19e3ea..87caf74913 100644 --- a/bin/tests/system/catz/ns4/named.conf.in +++ b/bin/tests/system/catz/ns4/named.conf.in @@ -35,6 +35,9 @@ options { dnssec-validation no; catalog-zones { + zone "catalog-misc.example" + min-update-interval 1s + default-primaries { 10.53.0.1; }; zone "catalog-tls.example" min-update-interval 1s default-primaries { 10.53.0.1 key tsig_key tls ephemeral; }; @@ -50,6 +53,12 @@ zone "catalog-tls.example" { primaries { 10.53.0.1 key tsig_key tls ephemeral; }; }; +zone "catalog-misc.example" { + type secondary; + file "catalog-misc.example.db"; + primaries { 10.53.0.1; }; +}; + zone "catalog-self.example" { type primary; file "catalog-self.example.db"; @@ -65,3 +74,8 @@ key next_key. { secret "LaAnCU+Z"; algorithm @DEFAULT_HMAC@; }; + +key longlonglongname0123456789abcdef. { + secret "LaAnCU+Z"; + algorithm @DEFAULT_HMAC@; +}; diff --git a/bin/tests/system/catz/setup.sh b/bin/tests/system/catz/setup.sh index 21474678f1..38339e2bd8 100644 --- a/bin/tests/system/catz/setup.sh +++ b/bin/tests/system/catz/setup.sh @@ -25,6 +25,7 @@ cp -f ns1/catalog.example.db.in ns1/catalog3.example.db cp -f ns1/catalog.example.db.in ns1/catalog4.example.db # catalog5 is missing on purpose cp -f ns1/catalog.example.db.in ns1/catalog6.example.db +cp -f ns1/catalog.example.db.in ns1/catalog-misc.example.db cp -f ns1/catalog.example.db.in ns1/catalog-tls.example.db cp -f ns4/catalog.example.db.in ns4/catalog-self.example.db diff --git a/bin/tests/system/catz/tests.sh b/bin/tests/system/catz/tests.sh index be3e3f4be9..b1d965b247 100644 --- a/bin/tests/system/catz/tests.sh +++ b/bin/tests/system/catz/tests.sh @@ -2641,6 +2641,74 @@ wait_for_soa @10.53.0.4 tls1.example. dig.out.test$n || ret=1 if [ $ret -ne 0 ]; then echo_i "failed"; fi status=$((status + ret)) +########################################################################## +# GL #5658 + +n=$((n + 1)) +echo_i "Adding a domain longlong.longlong.long.long.name.example. to primary via RNDC ($n)" +ret=0 +# enough initial content for IXFR response when TXT record is added below +echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" >ns1/longlong.longlong.long.long.name.example.db +echo "@ 3600 IN NS invalid." >>ns1/longlong.longlong.long.long.name.example.db +echo "foo 3600 IN TXT some content here" >>ns1/longlong.longlong.long.long.name.example.db +echo "bar 3600 IN TXT some content here" >>ns1/longlong.longlong.long.long.name.example.db +echo "xxx 3600 IN TXT some content here" >>ns1/longlong.longlong.long.long.name.example.db +echo "yyy 3600 IN TXT some content here" >>ns1/longlong.longlong.long.long.name.example.db +rndccmd 10.53.0.1 addzone longlong.longlong.long.long.name.example. in default '{ type primary; file "longlong.longlong.long.long.name.example.db"; allow-transfer { key longlonglongname0123456789abcdef; }; allow-update { any; }; notify explicit; also-notify { 10.53.0.4; }; };' || ret=1 +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +n=$((n + 1)) +echo_i "checking that longlong.longlong.long.long.name.example. is now served by primary ($n)" +ret=0 +wait_for_soa @10.53.0.1 longlong.longlong.long.long.name.example. dig.out.test$n || ret=1 +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +nextpart ns4/named.run >/dev/null + +n=$((n + 1)) +echo_i "Adding domain longlong.longlong.long.long.name.example. to catalog-misc zone ($n)" +ret=0 +$NSUPDATE -d <>nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.1 ${PORT} + update add longlong.zones.catalog-misc.example. 3600 IN PTR longlong.longlong.long.long.name.example. + update add label1.primaries.ext.longlong.zones.catalog-misc.example. 3600 IN A 10.53.0.1 + update add label1.primaries.ext.longlong.zones.catalog-misc.example. 3600 IN TXT "longlonglongname0123456789abcdef" + update add label2.primaries.ext.longlong.zones.catalog-misc.example. 3600 IN A 10.53.0.1 + update add label2.primaries.ext.longlong.zones.catalog-misc.example. 3600 IN TXT "longlonglongname0123456789abcdef" + update add label3.primaries.ext.longlong.zones.catalog-misc.example. 3600 IN A 10.53.0.1 + update add label3.primaries.ext.longlong.zones.catalog-misc.example. 3600 IN TXT "longlonglongname0123456789abcdef" + update add label4.primaries.ext.longlong.zones.catalog-misc.example. 3600 IN A 10.53.0.1 + update add label4.primaries.ext.longlong.zones.catalog-misc.example. 3600 IN TXT "longlonglongname0123456789abcdef" + update add label5.primaries.ext.longlong.zones.catalog-misc.example. 3600 IN A 10.53.0.1 + update add label5.primaries.ext.longlong.zones.catalog-misc.example. 3600 IN TXT "longlonglongname0123456789abcdef" + update add label6.primaries.ext.longlong.zones.catalog-misc.example. 3600 IN A 10.53.0.1 + update add label6.primaries.ext.longlong.zones.catalog-misc.example. 3600 IN TXT "longlonglongname0123456789abcdef" + update add label7.primaries.ext.longlong.zones.catalog-misc.example. 3600 IN A 10.53.0.1 + update add label7.primaries.ext.longlong.zones.catalog-misc.example. 3600 IN TXT "longlonglongname0123456789abcdef" + update add label8.primaries.ext.longlong.zones.catalog-misc.example. 3600 IN A 10.53.0.1 + update add label8.primaries.ext.longlong.zones.catalog-misc.example. 3600 IN TXT "longlonglongname0123456789abcdef" + send +END +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +n=$((n + 1)) +echo_i "waiting for secondary to sync up ($n)" +ret=0 +wait_for_message ns4/named.run "catz: adding zone 'longlong.longlong.long.long.name.example' from catalog 'catalog-misc.example'" \ + && wait_for_message ns4/named.run "transfer of 'longlong.longlong.long.long.name.example/IN' from 10.53.0.1#${PORT}: Transfer status: success" || ret=1 +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +n=$((n + 1)) +echo_i "checking that longlong.longlong.long.long.name.example. is served by secondary ($n)" +ret=0 +wait_for_soa @10.53.0.4 longlong.longlong.long.long.name.example. dig.out.test$n || ret=1 +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + ########################################################################## # GL #3777 nextpart ns4/named.run >/dev/null diff --git a/bin/tests/system/catz/tests_sh_catz.py b/bin/tests/system/catz/tests_sh_catz.py index 639a0f3f0e..060e45fc0f 100644 --- a/bin/tests/system/catz/tests_sh_catz.py +++ b/bin/tests/system/catz/tests_sh_catz.py @@ -21,6 +21,7 @@ pytestmark = pytest.mark.extra_artifacts( "ns*/*.nzd*", "ns*/catalog*.example.db", "ns*/*dom*.example.db", + "ns1/longlong.longlong.long.long.name.example.db", "ns1/tls1.example.db", "ns2/__catz__*.db", "ns2/named.conf.tmp", From 066847af25be21b200d90ff2b851ca5357cfb4b2 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Tue, 9 Dec 2025 18:07:42 +1100 Subject: [PATCH 3/3] log failing buffer --- bin/named/server.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/bin/named/server.c b/bin/named/server.c index 2d67b7adc3..a39eb30837 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -2352,20 +2352,26 @@ catz_addmodzone_cb(void *arg) { if (result == ISC_R_SUCCESS) { result = cfg_parse_buffer(confbuf, "catz", 0, &cfg_type_addzoneconf, 0, &zoneconf); - isc_buffer_free(&confbuf); } /* * Fail if either dns_catz_generate_zonecfg() or cfg_parse_buffer() * failed. */ if (result != ISC_R_SUCCESS) { - isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "catz: error \"%s\" while trying to generate " - "config for zone '%s'", - isc_result_totext(result), nameb); + isc_log_write( + NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER, + ISC_LOG_ERROR, + "catz: error \"%s\" while trying to generate " + "config for zone '%s'%s%.*s%s", + isc_result_totext(result), nameb, + confbuf != NULL ? " buffer '" : "", + confbuf != NULL ? (int)isc_buffer_usedlength(confbuf) + : 0, + confbuf != NULL ? (char *)isc_buffer_base(confbuf) : "", + confbuf != NULL ? "'" : ""); goto cleanup; } + isc_buffer_free(&confbuf); CHECK(cfg_map_get(zoneconf, "zone", &zlist)); if (!cfg_obj_islist(zlist)) { CLEANUP(ISC_R_FAILURE); @@ -2425,6 +2431,9 @@ catz_addmodzone_cb(void *arg) { dns_zone_set_parentcatz(zone, cz->origin); cleanup: + if (confbuf != NULL) { + isc_buffer_free(&confbuf); + } if (zone != NULL) { dns_zone_detach(&zone); }