From d0165070c7f11e09498ad7c8e19ada7eea1fa044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Sat, 14 Mar 2026 12:46:05 +0100 Subject: [PATCH 1/7] Fix memory context leak in dns_client_resolve() error path Use isc_mem_putanddetach() instead of isc_mem_put() to properly detach the attached memory context stored in resarg->mctx. --- lib/dns/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/dns/client.c b/lib/dns/client.c index 91e74e17b2..565c4d8ce9 100644 --- a/lib/dns/client.c +++ b/lib/dns/client.c @@ -953,7 +953,7 @@ dns_client_resolve(dns_client_t *client, const dns_name_t *name, result = startresolve(client, name, rdclass, type, options, resolve_done, resarg, &resarg->trans); if (result != ISC_R_SUCCESS) { - isc_mem_put(client->mctx, resarg, sizeof(*resarg)); + isc_mem_putanddetach(&resarg->mctx, resarg, sizeof(*resarg)); return result; } From 80fae7a4b7d8f9aa5aedb5f5ad34f90ce1ad3e77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Sat, 14 Mar 2026 12:52:07 +0100 Subject: [PATCH 2/7] Fix memory leak in ixfr_commit() error path The 'data' allocation was not freed when reaching the cleanup label with an error result. --- lib/dns/xfrin.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index 783b7d0dd1..feff048e9a 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -686,6 +686,9 @@ ixfr_commit(dns_xfrin_t *xfr) { } cleanup: + if (result != ISC_R_SUCCESS) { + isc_mem_put(xfr->mctx, data, sizeof(*data)); + } return result; } From 1505cb1c24fcbfcf43b1a1de6957c73afacccdd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Sat, 14 Mar 2026 12:53:03 +0100 Subject: [PATCH 3/7] Fix TSIG key and transport leaks in zone_notify() error paths Two 'goto next' paths in zone_notify() skipped detaching the TSIG key and transport, leaking them on TLS configuration failure and when the destination address is disabled. --- lib/dns/zone.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index b524a90189..693e048f89 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -12523,6 +12523,9 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) { "could not get TLS configuration " "for zone transfer: %s", isc_result_totext(result)); + if (key != NULL) { + dns_tsigkey_detach(&key); + } goto next; } @@ -12536,6 +12539,12 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) { INSIST(isc_sockaddr_pf(&src) == isc_sockaddr_pf(&dst)); if (isc_sockaddr_disabled(&dst)) { + if (key != NULL) { + dns_tsigkey_detach(&key); + } + if (transport != NULL) { + dns_transport_detach(&transport); + } goto next; } From d7e1013741e3921f0f18246d15ef6f800ada77a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Sat, 14 Mar 2026 12:53:29 +0100 Subject: [PATCH 4/7] Fix cb_args memory leak in ns_query() error path Initialize cb_args to NULL and free it in the cleanup path so it is not leaked when the function fails after allocation. --- lib/dns/zone.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 693e048f89..8f6ded6717 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -14261,7 +14261,7 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { bool reqnsid; uint16_t udpsize = SEND_BUFFER_SIZE; isc_sockaddr_t curraddr, sourceaddr; - struct stub_cb_args *cb_args; + struct stub_cb_args *cb_args = NULL; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(LOCKED_ZONE(zone)); @@ -14480,6 +14480,9 @@ cleanup: if (stub->zone != NULL) { zone_idetach(&stub->zone); } + if (cb_args != NULL) { + isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args)); + } isc_mem_put(stub->mctx, stub, sizeof(*stub)); if (message != NULL) { dns_message_detach(&message); From 63d3c1f58a347d7d15c1e5477c6f9793cf139787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Sat, 14 Mar 2026 12:53:51 +0100 Subject: [PATCH 5/7] Simplify checkds_create() to return void Since memory allocation never fails in BIND 9, checkds_create() cannot fail. Change it to return void and use designated initializers, removing error handling at all call sites. --- lib/dns/zone.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 8f6ded6717..741e88a588 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -20289,7 +20290,7 @@ checkds_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr, return false; } -static isc_result_t +static void checkds_create(isc_mem_t *mctx, unsigned int flags, dns_checkds_t **checkdsp) { dns_checkds_t *checkds; @@ -20297,16 +20298,16 @@ checkds_create(isc_mem_t *mctx, unsigned int flags, dns_checkds_t **checkdsp) { checkds = isc_mem_get(mctx, sizeof(*checkds)); *checkds = (dns_checkds_t){ + .magic = CHECKDS_MAGIC, .flags = flags, + .link = ISC_LINK_INITIALIZER, + .mctx = isc_mem_ref(mctx), + .ns = DNS_NAME_INITEMPTY, }; - isc_mem_attach(mctx, &checkds->mctx); isc_sockaddr_any(&checkds->dst); - dns_name_init(&checkds->ns); - ISC_LINK_INIT(checkds, link); - checkds->magic = CHECKDS_MAGIC; + *checkdsp = checkds; - return ISC_R_SUCCESS; } static void @@ -20595,7 +20596,7 @@ checkds_send_tons(dns_checkds_t *checkds) { } newcheckds = NULL; - CHECK(checkds_create(checkds->mctx, 0, &newcheckds)); + checkds_create(checkds->mctx, 0, &newcheckds); zone_iattach(zone, &newcheckds->zone); ISC_LIST_APPEND(newcheckds->zone->checkds_requests, newcheckds, link); @@ -20682,6 +20683,12 @@ checkds_send(dns_zone_t *zone) { INSIST(isc_sockaddr_pf(&src) == isc_sockaddr_pf(&dst)); if (isc_sockaddr_disabled(&dst)) { + if (key != NULL) { + dns_tsigkey_detach(&key); + } + if (transport != NULL) { + dns_transport_detach(&transport); + } goto next; } @@ -20706,14 +20713,7 @@ checkds_send(dns_zone_t *zone) { "parent %d", i); - result = checkds_create(zone->mctx, flags, &checkds); - if (result != ISC_R_SUCCESS) { - dns_zone_log(zone, ISC_LOG_DEBUG(3), - "checkds: create DS query for " - "parent %d failed", - i); - goto next; - } + checkds_create(zone->mctx, flags, &checkds); zone_iattach(zone, &checkds->zone); dns_name_dup(dns_rootname, checkds->mctx, &checkds->ns); checkds->src = src; @@ -20883,13 +20883,7 @@ nsfetch_checkds(dns_zonefetch_t *fetch, isc_result_t eresult) { if (isqueued) { continue; } - result = checkds_create(zone->mctx, 0, &checkds); - if (result != ISC_R_SUCCESS) { - dns_zone_log(zone, ISC_LOG_DEBUG(3), - "checkds: checkds_create() failed: %s", - isc_result_totext(result)); - break; - } + checkds_create(zone->mctx, 0, &checkds); if (isc_log_wouldlog(ISC_LOG_DEBUG(3))) { char nsnamebuf[DNS_NAME_FORMATSIZE]; From 2ab3d7c0757ef8dc3d7a979bad1443a9454e8f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Sat, 14 Mar 2026 12:54:27 +0100 Subject: [PATCH 6/7] Fix missing server socket detach in TLS accept error path When TLS creation fails in tlslisten_acceptcb(), tlssock->server was not detached before detaching tlssock itself. --- lib/isc/netmgr/tlsstream.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/isc/netmgr/tlsstream.c b/lib/isc/netmgr/tlsstream.c index 39c29c9ebf..3a9ab1dfbf 100644 --- a/lib/isc/netmgr/tlsstream.c +++ b/lib/isc/netmgr/tlsstream.c @@ -932,6 +932,7 @@ tlslisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) { if (tlssock->tlsstream.tls == NULL) { tlssock->closed = true; isc_tlsctx_free(&tlssock->tlsstream.ctx); + isc__nmsocket_detach(&tlssock->server); isc__nmsocket_detach(&tlssock); return ISC_R_TLSERROR; } From df1993611bae62ad0267d8652d599b4158f3e9a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Sat, 14 Mar 2026 12:54:50 +0100 Subject: [PATCH 7/7] Fix KASP key leaks on keystore lookup failure In both cfg_kasp_fromconfig() and cfg_kasp_builtinconfig(), the newly allocated KASP key was not destroyed when the keystore lookup failed. --- lib/isccfg/kaspconf.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/isccfg/kaspconf.c b/lib/isccfg/kaspconf.c index 6593f78145..ab4df8a51d 100644 --- a/lib/isccfg/kaspconf.c +++ b/lib/isccfg/kaspconf.c @@ -817,6 +817,7 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp, "find keystore (%s)", isc_result_totext(result)); } + dns_kasp_key_destroy(new_key); goto cleanup; } dns_kasp_addkey(kasp, new_key); @@ -930,9 +931,13 @@ cfg_kasp_builtinconfig(isc_mem_t *mctx, const char *name, new_key->lifetime = 0; new_key->algorithm = DST_ALG_ECDSA256; new_key->length = 256; - CHECK(dns_keystorelist_find(keystorelist, - DNS_KEYSTORE_KEYDIRECTORY, - &new_key->keystore)); + result = dns_keystorelist_find(keystorelist, + DNS_KEYSTORE_KEYDIRECTORY, + &new_key->keystore); + if (result != ISC_R_SUCCESS) { + dns_kasp_key_destroy(new_key); + goto cleanup; + } dns_kasp_addkey(kasp, new_key); }