fix: dev: Fix couple of reference counting bugs

Fix missing detach/free on error paths.

Merge branch 'ondrej/fix-reference-counting-errors' into 'main'

See merge request isc-projects/bind9!11666
This commit is contained in:
Ondřej Surý 2026-03-16 10:48:13 +01:00
commit 6a94864c62
5 changed files with 42 additions and 27 deletions

View file

@ -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;
}

View file

@ -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;
}

View file

@ -22,6 +22,7 @@
#include <isc/file.h>
#include <isc/hash.h>
#include <isc/hex.h>
#include <isc/list.h>
#include <isc/log.h>
#include <isc/loop.h>
#include <isc/md.h>
@ -12523,6 +12524,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 +12540,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;
}
@ -14252,7 +14262,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));
@ -14471,6 +14481,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);
@ -20277,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;
@ -20285,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
@ -20583,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);
@ -20670,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;
}
@ -20694,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;
@ -20871,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];

View file

@ -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;
}

View file

@ -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);
}